Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Tweaking indentation of code; really unimportant... |
|---|---|
| Timelines: | family | ancestors | dkf-indent-tweak |
| Files: | files | file ages | folders |
| SHA3-256: |
bb728069601b0c645b362f5222cade02 |
| User & Date: | dkf 2024-01-30 17:07:44.120 |
Context
|
2024-01-30
| ||
| 17:07 | Tweaking indentation of code; really unimportant... Leaf check-in: bb72806960 user: dkf tags: dkf-indent-tweak | |
|
2024-01-29
| ||
| 21:12 | Merge 8.7 check-in: 9ae7acab75 user: jan.nijtmans tags: trunk, main | |
Changes
Changes to generic/tcl.h.
| ︙ | ︙ | |||
449 450 451 452 453 454 455 | #define TCL_REG_CANMATCH 001000 /* Report details on partial/limited * matches. */ /* * Flags values passed to Tcl_RegExpExecObj. */ | | | | | | | 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 |
#define TCL_REG_CANMATCH 001000 /* 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 $. */
/*
* Structures filled in by Tcl_RegExpInfo. Note that all offset values are
* relative to the start of the match string, not the beginning of the entire
* string.
*/
typedef struct Tcl_RegExpIndices {
#if TCL_MAJOR_VERSION > 8
Tcl_Size start; /* Character offset of first character in
* match. */
Tcl_Size end; /* Character offset of first character after
* the match. */
#else
long start;
long end;
#endif
} Tcl_RegExpIndices;
typedef struct Tcl_RegExpInfo {
Tcl_Size nsubs; /* Number of subexpressions in the compiled
* expression. */
Tcl_RegExpIndices *matches; /* Array of nsubs match offset pairs. */
#if TCL_MAJOR_VERSION > 8
Tcl_Size extendStart; /* The offset at which a subsequent match
* might begin. */
#else
long extendStart;
long reserved; /* Reserved for later use. */
#endif
} Tcl_RegExpInfo;
|
| ︙ | ︙ | |||
613 614 615 616 617 618 619 | typedef void (Tcl_AlertNotifierProc) (void *clientData); typedef void (Tcl_ServiceModeHookProc) (int mode); typedef void *(Tcl_InitNotifierProc) (void); typedef void (Tcl_FinalizeNotifierProc) (void *clientData); typedef void (Tcl_MainLoopProc) (void); /* Abstract List functions */ | | | | | | < | | | | | | | < | | < | | | | 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 | typedef void (Tcl_AlertNotifierProc) (void *clientData); typedef void (Tcl_ServiceModeHookProc) (int mode); typedef void *(Tcl_InitNotifierProc) (void); typedef void (Tcl_FinalizeNotifierProc) (void *clientData); typedef void (Tcl_MainLoopProc) (void); /* Abstract List functions */ typedef Tcl_Size (Tcl_ObjTypeLengthProc) (struct Tcl_Obj *listPtr); typedef int (Tcl_ObjTypeIndexProc) (Tcl_Interp *interp, struct Tcl_Obj *listPtr, Tcl_Size index, struct Tcl_Obj** elemObj); typedef int (Tcl_ObjTypeSliceProc) (Tcl_Interp *interp, struct Tcl_Obj *listPtr, Tcl_Size fromIdx, Tcl_Size toIdx, struct Tcl_Obj **newObjPtr); typedef int (Tcl_ObjTypeReverseProc) (Tcl_Interp *interp, struct Tcl_Obj *listPtr, struct Tcl_Obj **newObjPtr); typedef int (Tcl_ObjTypeGetElements) (Tcl_Interp *interp, struct Tcl_Obj *listPtr, Tcl_Size *objcptr, struct Tcl_Obj ***objvptr); typedef struct Tcl_Obj * (Tcl_ObjTypeSetElement) (Tcl_Interp *interp, struct Tcl_Obj *listPtr, Tcl_Size indexCount, struct Tcl_Obj *const indexArray[], struct Tcl_Obj *valueObj); typedef int (Tcl_ObjTypeReplaceProc) (Tcl_Interp *interp, struct Tcl_Obj *listObj, Tcl_Size first, Tcl_Size numToDelete, Tcl_Size numToInsert, struct Tcl_Obj *const insertObjs[]); typedef int (Tcl_ObjTypeInOperatorProc) (Tcl_Interp *interp, struct Tcl_Obj *valueObj, struct Tcl_Obj *listObj, int *boolResult); #ifndef TCL_NO_DEPRECATED # define Tcl_PackageInitProc Tcl_LibraryInitProc # define Tcl_PackageUnloadProc Tcl_LibraryUnloadProc #endif /* |
| ︙ | ︙ | |||
666 667 668 669 670 671 672 |
/* Called to convert the object's internal rep
* to this type. Frees the internal rep of the
* old type. Returns TCL_ERROR on failure. */
#if TCL_MAJOR_VERSION > 8
size_t version;
/* List emulation functions - ObjType Version 1 */
| | | | | | | | | | | | > | | > | | | | | 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 |
/* Called to convert the object's internal rep
* to this type. Frees the internal rep of the
* old type. Returns TCL_ERROR on failure. */
#if TCL_MAJOR_VERSION > 8
size_t version;
/* List emulation functions - ObjType Version 1 */
Tcl_ObjTypeLengthProc *lengthProc;
/* Return the [llength] of the AbstractList */
Tcl_ObjTypeIndexProc *indexProc;
/* Return a value (Tcl_Obj) for [lindex $al $index] */
Tcl_ObjTypeSliceProc *sliceProc;
/* Return an AbstractList for [lrange $al $start $end] */
Tcl_ObjTypeReverseProc *reverseProc;
/* Return an AbstractList for [lreverse $al] */
Tcl_ObjTypeGetElements *getElementsProc;
/* Return an objv[] of all elements in the list */
Tcl_ObjTypeSetElement *setElementProc;
/* Replace the element at the indicies with the
* given valueObj. */
Tcl_ObjTypeReplaceProc *replaceProc;
/* Replace subset with subset */
Tcl_ObjTypeInOperatorProc *inOperProc;
/* "in" and "ni" expr list operation. Determines
* if the given string value matches an element
* in the list */
#endif
} Tcl_ObjType;
#if TCL_MAJOR_VERSION > 8
# define TCL_OBJTYPE_V0 0, \
0,0,0,0,0,0,0,0 /* Pre-Tcl 9 */
# define TCL_OBJTYPE_V1(a) offsetof(Tcl_ObjType, indexProc), \
|
| ︙ | ︙ | |||
745 746 747 748 749 750 751 |
* array as a readonly value. */
Tcl_Size length; /* The number of bytes at *bytes, not
* including the terminating null. */
const Tcl_ObjType *typePtr; /* Denotes the object's type. Always
* corresponds to the type of the object's
* internal rep. NULL indicates the object has
* no internal rep (has no type). */
| | > | | 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 |
* array as a readonly value. */
Tcl_Size length; /* The number of bytes at *bytes, not
* including the terminating null. */
const Tcl_ObjType *typePtr; /* Denotes the object's type. Always
* corresponds to the type of the object's
* internal rep. NULL indicates the object has
* no internal rep (has no type). */
Tcl_ObjInternalRep internalRep;
/* The internal representation: */
} Tcl_Obj;
/*
*----------------------------------------------------------------------------
* The following definitions support Tcl's namespace facility. Note: the first
* five fields must match exactly the fields in a Namespace structure (see
* tclInt.h).
*/
typedef struct Tcl_Namespace {
char *name; /* The namespace's name within its parent
* namespace. This contains no ::'s. The name
* of the global namespace is "" although "::"
* is an synonym. */
char *fullName; /* The namespace's fully qualified name. This
* starts with ::. */
void *clientData; /* Arbitrary value associated with this
* namespace. */
Tcl_NamespaceDeleteProc *deleteProc;
/* Function invoked when deleting the
* namespace to, e.g., free clientData. */
struct Tcl_Namespace *parentPtr;
/* Points to the namespace that contains this
* one. NULL if this is the global
|
| ︙ | ︙ | |||
831 832 833 834 835 836 837 |
* Tcl_CreateCommand. The other function is typically set to a compatibility
* wrapper that does string-to-object or object-to-string argument conversions
* then calls the other function.
*/
typedef struct {
int isNativeObjectProc; /* 1 if objProc was registered by a call to
| | | | > | | | 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 |
* Tcl_CreateCommand. The other function is typically set to a compatibility
* wrapper that does string-to-object or object-to-string argument conversions
* then calls the other function.
*/
typedef struct {
int isNativeObjectProc; /* 1 if objProc was registered by a call to
* Tcl_CreateObjCommand; 2 if objProc was
* registered by a call to Tcl_CreateObjCommand2;
* 0 otherwise. Tcl_SetCmdInfo does not modify
* this field. */
Tcl_ObjCmdProc *objProc; /* Command's object-based function. */
void *objClientData; /* ClientData for object proc. */
Tcl_CmdProc *proc; /* Command's string-based function. */
void *clientData; /* ClientData for string proc. */
Tcl_CmdDeleteProc *deleteProc;
/* Function to call when command is
* deleted. */
void *deleteData; /* Value to pass to deleteProc (usually the
* same as clientData). */
Tcl_Namespace *namespacePtr;/* Points to the namespace that contains this
* command. Note that Tcl_SetCmdInfo will not
* change a command's namespace; use
* TclRenameCommand or Tcl_Eval (of 'rename')
* to do that. */
Tcl_ObjCmdProc2 *objProc2; /* Command's object2-based function. */
|
| ︙ | ︙ | |||
1073 1074 1075 1076 1077 1078 1079 |
*/
struct Tcl_HashEntry {
Tcl_HashEntry *nextPtr; /* Pointer to next entry in this hash bucket,
* or NULL for end of chain. */
Tcl_HashTable *tablePtr; /* Pointer to table containing entry. */
size_t hash; /* Hash value. */
| | | 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 |
*/
struct Tcl_HashEntry {
Tcl_HashEntry *nextPtr; /* Pointer to next entry in this hash bucket,
* or NULL for end of chain. */
Tcl_HashTable *tablePtr; /* Pointer to table containing entry. */
size_t hash; /* Hash value. */
void *clientData; /* Application stores something here with
* Tcl_SetHashValue. */
union { /* Key has one of these forms: */
char *oneWordValue; /* One-word value for key. */
Tcl_Obj *objPtr; /* Tcl_Obj * key value. */
int words[1]; /* Multiple integer words for key. The actual
* size will be as large as necessary for this
* table's keys. */
|
| ︙ | ︙ | |||
1161 1162 1163 1164 1165 1166 1167 |
struct Tcl_HashTable {
Tcl_HashEntry **buckets; /* Pointer to bucket array. Each element
* points to first entry in bucket's hash
* chain, or NULL. */
Tcl_HashEntry *staticBuckets[TCL_SMALL_HASH_TABLE];
/* Bucket array used for small tables (to
* avoid mallocs and frees). */
| | | | | | 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 |
struct Tcl_HashTable {
Tcl_HashEntry **buckets; /* Pointer to bucket array. Each element
* points to first entry in bucket's hash
* chain, or NULL. */
Tcl_HashEntry *staticBuckets[TCL_SMALL_HASH_TABLE];
/* Bucket array used for small tables (to
* avoid mallocs and frees). */
Tcl_Size numBuckets; /* Total number of buckets allocated at
* **bucketPtr. */
Tcl_Size numEntries; /* Total number of entries present in
* table. */
Tcl_Size rebuildSize; /* Enlarge table when numEntries gets to be
* this large. */
#if TCL_MAJOR_VERSION > 8
size_t mask; /* Mask value used in hashing function. */
#endif
int downShift; /* Shift count used in hashing function.
* Designed to use high-order bits of
* randomized keys. */
#if TCL_MAJOR_VERSION < 9
int mask; /* Mask value used in hashing function. */
#endif
int keyType; /* Type of keys used in this table. It's
* either TCL_CUSTOM_KEYS, TCL_STRING_KEYS,
* TCL_ONE_WORD_KEYS, or an integer giving the
* number of ints that is the size of the
* key. */
Tcl_HashEntry *(*findProc) (Tcl_HashTable *tablePtr, const char *key);
|
| ︙ | ︙ | |||
1237 1238 1239 1240 1241 1242 1243 |
* dictionaries. These fields should not be accessed by code outside
* tclDictObj.c
*/
typedef struct {
void *next; /* Search position for underlying hash
* table. */
| | | 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 |
* dictionaries. These fields should not be accessed by code outside
* tclDictObj.c
*/
typedef struct {
void *next; /* Search position for underlying hash
* table. */
TCL_HASH_TYPE epoch; /* Epoch marker for dictionary being searched,
* or 0 if search has terminated. */
Tcl_Dict dictionaryPtr; /* Reference to dictionary being searched. */
} Tcl_DictSearch;
/*
*----------------------------------------------------------------------------
* Flag values to pass to Tcl_DoOneEvent to disable searches for some kinds of
|
| ︙ | ︙ | |||
1651 1652 1653 1654 1655 1656 1657 |
/* Called by 'Tcl_FSOpenFileChannel()'.
* Provided by any reasonable filesystem. */
Tcl_FSMatchInDirectoryProc *matchInDirectoryProc;
/* Called by 'Tcl_FSMatchInDirectory()'. NULL
* if the filesystem does not support glob or
* recursive copy. */
Tcl_FSUtimeProc *utimeProc; /* Called by 'Tcl_FSUtime()', by 'file
| | | | | | | 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 |
/* Called by 'Tcl_FSOpenFileChannel()'.
* Provided by any reasonable filesystem. */
Tcl_FSMatchInDirectoryProc *matchInDirectoryProc;
/* Called by 'Tcl_FSMatchInDirectory()'. NULL
* if the filesystem does not support glob or
* recursive copy. */
Tcl_FSUtimeProc *utimeProc; /* Called by 'Tcl_FSUtime()', by 'file
* mtime' to set (not read) times, 'file
* atime', and the open-r/open-w/fcopy variant
* of 'file copy'. */
Tcl_FSLinkProc *linkProc; /* Called by 'Tcl_FSLink()'. NULL if reading or
* creating links is not supported. */
Tcl_FSListVolumesProc *listVolumesProc;
/* Lists filesystem volumes added by this
* filesystem. NULL if the filesystem does not
* use volumes. */
Tcl_FSFileAttrStringsProc *fileAttrStringsProc;
/* List all valid attributes strings. NULL if
* the filesystem does not support the 'file
* attributes' command. Can be used to attach
* arbitrary additional data to files in a
* filesystem. */
Tcl_FSFileAttrsGetProc *fileAttrsGetProc;
/* Called by 'Tcl_FSFileAttrsGet()' and by
* 'file attributes'. */
Tcl_FSFileAttrsSetProc *fileAttrsSetProc;
/* Called by 'Tcl_FSFileAttrsSet()' and by
* 'file attributes'. */
Tcl_FSCreateDirectoryProc *createDirectoryProc;
/* Called by 'Tcl_FSCreateDirectory()'. May be
* NULL if the filesystem is read-only. */
Tcl_FSRemoveDirectoryProc *removeDirectoryProc;
/* Called by 'Tcl_FSRemoveDirectory()'. May be
* NULL if the filesystem is read-only. */
Tcl_FSDeleteFileProc *deleteFileProc;
|
| ︙ | ︙ | |||
1764 1765 1766 1767 1768 1769 1770 |
* token.
*/
typedef struct Tcl_Token {
int type; /* Type of token, such as TCL_TOKEN_WORD; see
* below for valid types. */
const char *start; /* First character in token. */
| | | | 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 |
* token.
*/
typedef struct Tcl_Token {
int type; /* Type of token, such as TCL_TOKEN_WORD; see
* below for valid types. */
const char *start; /* First character in token. */
Tcl_Size size; /* Number of bytes in token. */
Tcl_Size numComponents; /* If this token is composed of other tokens,
* this field tells how many of them there are
* (including components of components, etc.).
* The component tokens immediately follow
* this one. */
} Tcl_Token;
/*
|
| ︙ | ︙ | |||
1879 1880 1881 1882 1883 1884 1885 |
*/
#define NUM_STATIC_TOKENS 20
typedef struct Tcl_Parse {
const char *commentStart; /* Pointer to # that begins the first of one
* or more comments preceding the command. */
| | | | 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 |
*/
#define NUM_STATIC_TOKENS 20
typedef struct Tcl_Parse {
const char *commentStart; /* Pointer to # that begins the first of one
* or more comments preceding the command. */
Tcl_Size commentSize; /* Number of bytes in comments (up through
* newline character that terminates the last
* comment). If there were no comments, this
* field is 0. */
const char *commandStart; /* First character in first word of
* command. */
Tcl_Size commandSize; /* Number of bytes in command, including first
* character of first word, up through the
* terminating newline, close bracket, or
* semicolon. */
Tcl_Size numWords; /* Total number of words in command. May be
* 0. */
Tcl_Token *tokenPtr; /* Pointer to first token representing the
* words of the command. Initially points to
|
| ︙ | ︙ | |||
1952 1953 1954 1955 1956 1957 1958 |
* encoding type. */
Tcl_EncodingConvertProc *toUtfProc;
/* Function to convert from external encoding
* into UTF-8. */
Tcl_EncodingConvertProc *fromUtfProc;
/* Function to convert from UTF-8 into
* external encoding. */
| | < | 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 |
* encoding type. */
Tcl_EncodingConvertProc *toUtfProc;
/* Function to convert from external encoding
* into UTF-8. */
Tcl_EncodingConvertProc *fromUtfProc;
/* Function to convert from UTF-8 into
* external encoding. */
Tcl_FreeProc *freeProc; /* If non-NULL, function to call when this
* encoding is deleted. */
void *clientData; /* Arbitrary value associated with encoding
* type. Passed to conversion functions. */
Tcl_Size nullSize; /* Number of zero bytes that signify
* end-of-string in this encoding. This number
* is used to determine the source string
* length when the srcLen argument is
|
| ︙ | ︙ | |||
1985 1986 1987 1988 1989 1990 1991 | * 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 - Not used any more. | | | 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 | * 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 - Not used any more. * 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 |
| ︙ | ︙ | |||
2161 2162 2163 2164 2165 2166 2167 |
* argv array. */
void *srcPtr; /* Value to be used in setting dst; usage
* depends on type.*/
void *dstPtr; /* Address of value to be modified; usage
* depends on type.*/
const char *helpStr; /* Documentation message describing this
* option. */
| | | 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 |
* argv array. */
void *srcPtr; /* Value to be used in setting dst; usage
* depends on type.*/
void *dstPtr; /* Address of value to be modified; usage
* depends on type.*/
const char *helpStr; /* Documentation message describing this
* option. */
void *clientData; /* Word to pass to function callbacks. */
} Tcl_ArgvInfo;
/*
* Legal values for the type field of a Tcl_ArgInfo: see the user
* documentation for details.
*/
|
| ︙ | ︙ | |||
2518 2519 2520 2521 2522 2523 2524 | } \ } while(0) # undef Tcl_IsShared # define Tcl_IsShared(objPtr) \ ((objPtr)->refCount > 1) /* | | | < | 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 |
} \
} while(0)
# undef Tcl_IsShared
# define Tcl_IsShared(objPtr) \
((objPtr)->refCount > 1)
/*
* Declare that obj will no longer be used or referenced. This will release
* the obj if there is no referece count, otherwise let it be.
*/
# define Tcl_BounceRefCount(objPtr) \
TclBounceRefCount(objPtr);
static inline void TclBounceRefCount(Tcl_Obj* objPtr)
{
if (objPtr) {
|
| ︙ | ︙ |
Changes to generic/tclAlloc.c.
| ︙ | ︙ | |||
507 508 509 510 511 512 513 |
*
*----------------------------------------------------------------------
*/
void *
TclpRealloc(
void *oldPtr, /* Pointer to alloc'ed block. */
| | | 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 |
*
*----------------------------------------------------------------------
*/
void *
TclpRealloc(
void *oldPtr, /* Pointer to alloc'ed block. */
size_t numBytes) /* New size of memory. */
{
int i;
union overhead *overPtr;
struct block *bigBlockPtr;
int expensive;
size_t maxSize;
|
| ︙ | ︙ | |||
690 691 692 693 694 695 696 | * *---------------------------------------------------------------------- */ #undef TclpAlloc void * TclpAlloc( | | | 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 |
*
*----------------------------------------------------------------------
*/
#undef TclpAlloc
void *
TclpAlloc(
size_t numBytes) /* Number of bytes to allocate. */
{
return malloc(numBytes);
}
/*
*----------------------------------------------------------------------
*
|
| ︙ | ︙ | |||
739 740 741 742 743 744 745 |
*
*----------------------------------------------------------------------
*/
void *
TclpRealloc(
void *oldPtr, /* Pointer to alloced block. */
| | | 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 |
*
*----------------------------------------------------------------------
*/
void *
TclpRealloc(
void *oldPtr, /* Pointer to alloced block. */
size_t numBytes) /* New size of memory. */
{
return realloc(oldPtr, numBytes);
}
#endif /* !USE_TCLALLOC */
#else
TCL_MAC_EMPTY_FILE(generic_tclAlloc_c)
|
| ︙ | ︙ |
Changes to generic/tclArithSeries.c.
| ︙ | ︙ | |||
63 64 65 66 67 68 69 |
double end;
double step;
int precision;
} ArithSeriesDbl;
/* -------------------------- ArithSeries object ---------------------------- */
| > | | < | > | > | | | | | | | | | 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
double end;
double step;
int precision;
} ArithSeriesDbl;
/* -------------------------- ArithSeries object ---------------------------- */
static int TclArithSeriesObjIndex(
TCL_UNUSED(Tcl_Interp *), Tcl_Obj *arithSeriesObj,
Tcl_Size index, Tcl_Obj **elemObj);
static Tcl_Size ArithSeriesObjLength(Tcl_Obj *arithSeriesObj);
static int TclArithSeriesObjRange(
Tcl_Interp *interp, Tcl_Obj *arithSeriesObj,
Tcl_Size fromIdx, Tcl_Size toIdx, Tcl_Obj **newObjPtr);
static int TclArithSeriesObjReverse(Tcl_Interp *interp,
Tcl_Obj *arithSeriesObj, Tcl_Obj **newObjPtr);
static int TclArithSeriesGetElements(Tcl_Interp *interp,
Tcl_Obj *objPtr, Tcl_Size *objcPtr, Tcl_Obj ***objvPtr);
static void DupArithSeriesInternalRep(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr);
static void FreeArithSeriesInternalRep(Tcl_Obj *arithSeriesObjPtr);
static void UpdateStringOfArithSeries(Tcl_Obj *arithSeriesObjPtr);
static int SetArithSeriesFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
static int ArithSeriesInOperation(Tcl_Interp *interp, Tcl_Obj *valueObj,
Tcl_Obj *arithSeriesObj, int *boolResult);
static const Tcl_ObjType arithSeriesType = {
"arithseries", /* name */
FreeArithSeriesInternalRep, /* freeIntRepProc */
DupArithSeriesInternalRep, /* dupIntRepProc */
UpdateStringOfArithSeries, /* updateStringProc */
SetArithSeriesFromAny, /* setFromAnyProc */
TCL_OBJTYPE_V2(
|
| ︙ | ︙ | |||
109 110 111 112 113 114 115 | * - ArithSeriesGetInternalRep -- Return the internal rep from a Tcl_Obj * - Precision -- determine the number of factional digits for the given * double value * - maxPrecision -- Using the values provide, determine the longest percision * in the arithSeries */ static inline double | | > > > | | | | > | > | > > > | | | | < | < | | | > > > | > > > > | 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 |
* - ArithSeriesGetInternalRep -- Return the internal rep from a Tcl_Obj
* - Precision -- determine the number of factional digits for the given
* double value
* - maxPrecision -- Using the values provide, determine the longest percision
* in the arithSeries
*/
static inline double
ArithRound(
double d,
unsigned int n)
{
double scalefactor = pow(10, n);
return round(d * scalefactor) / scalefactor;
}
static inline double
ArithSeriesIndexDbl(
ArithSeries *arithSeriesRepPtr,
Tcl_WideInt index)
{
ArithSeriesDbl *dblRepPtr = (ArithSeriesDbl*) arithSeriesRepPtr;
if (arithSeriesRepPtr->isDouble) {
double d = dblRepPtr->start + (index * dblRepPtr->step);
unsigned n = (dblRepPtr->precision > 0 ? dblRepPtr->precision : 0);
return ArithRound(d, n);
} else {
return (double)(arithSeriesRepPtr->start + (index * arithSeriesRepPtr->step));
}
}
static inline Tcl_WideInt
ArithSeriesIndexInt(
ArithSeries *arithSeriesRepPtr,
Tcl_WideInt index)
{
ArithSeriesDbl *dblRepPtr = (ArithSeriesDbl*) arithSeriesRepPtr;
if (arithSeriesRepPtr->isDouble) {
return (Tcl_WideInt)(dblRepPtr->start + ((index) * dblRepPtr->step));
} else {
return (arithSeriesRepPtr->start + (index * arithSeriesRepPtr->step));
}
}
static inline ArithSeries*
ArithSeriesGetInternalRep(
Tcl_Obj *objPtr)
{
const Tcl_ObjInternalRep *irPtr;
irPtr = TclFetchInternalRep((objPtr), &arithSeriesType);
return irPtr ? (ArithSeries *)irPtr->twoPtrValue.ptr1 : NULL;
}
/*
* Compute number of significant factional digits
*/
static inline int
Precision(
double d)
{
char tmp[TCL_DOUBLE_SPACE+2], *off;
tmp[0] = 0;
Tcl_PrintDouble(NULL,d,tmp);
off = strchr(tmp, '.');
return (off ? strlen(off+1) : 0);
}
/*
* Find longest number of digits after the decimal point.
*/
static inline int
maxPrecision(
double start,
double end,
double step)
{
int dp = Precision(step);
int i = Precision(start);
dp = i>dp ? i : dp;
i = Precision(end);
dp = i>dp ? i : dp;
return dp;
}
static int TclArithSeriesObjStep(Tcl_Obj *arithSeriesObj, Tcl_Obj **stepObj);
/*
*----------------------------------------------------------------------
*
* ArithSeriesLen --
*
* Compute the length of the equivalent list where every element is
* generated starting from *start*, and adding *step* to generate
* every successive element that's < *end* for positive steps,
* or > *end* for negative steps.
*
* Results:
*
* The length of the list generated by the given range, that may be zero.
* The function returns -1 if the list is of length infinite.
*
* Side effects:
*
* None.
*
*----------------------------------------------------------------------
*/
static Tcl_WideInt
ArithSeriesLenInt(
Tcl_WideInt start,
Tcl_WideInt end,
Tcl_WideInt step)
{
Tcl_WideInt len;
if (step == 0) {
return 0;
}
len = 1 + ((end-start)/step);
return (len < 0) ? -1 : len;
}
static Tcl_WideInt
ArithSeriesLenDbl(
double start,
double end,
double step,
int precision)
{
double istart, iend, istep, ilen;
if (step == 0) {
return 0;
}
istart = start * pow(10,precision);
iend = end * pow(10,precision);
|
| ︙ | ︙ | |||
257 258 259 260 261 262 263 |
{
ArithSeries *srcArithSeriesRepPtr =
(ArithSeries *) srcPtr->internalRep.twoPtrValue.ptr1;
/*
* Allocate a new ArithSeries structure. */
if (srcArithSeriesRepPtr->isDouble) {
| | | | | | | | 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 |
{
ArithSeries *srcArithSeriesRepPtr =
(ArithSeries *) srcPtr->internalRep.twoPtrValue.ptr1;
/*
* Allocate a new ArithSeries structure. */
if (srcArithSeriesRepPtr->isDouble) {
ArithSeriesDbl *srcArithSeriesDblRepPtr = (ArithSeriesDbl *)
srcArithSeriesRepPtr;
ArithSeriesDbl *copyArithSeriesDblRepPtr = (ArithSeriesDbl *)
Tcl_Alloc(sizeof(ArithSeriesDbl));
*copyArithSeriesDblRepPtr = *srcArithSeriesDblRepPtr;
copyArithSeriesDblRepPtr->elements = NULL;
copyPtr->internalRep.twoPtrValue.ptr1 = copyArithSeriesDblRepPtr;
} else {
ArithSeries *copyArithSeriesRepPtr = (ArithSeries *)
Tcl_Alloc(sizeof(ArithSeries));
*copyArithSeriesRepPtr = *srcArithSeriesRepPtr;
copyArithSeriesRepPtr->elements = NULL;
copyPtr->internalRep.twoPtrValue.ptr1 = copyArithSeriesRepPtr;
}
copyPtr->internalRep.twoPtrValue.ptr2 = NULL;
copyPtr->typePtr = &arithSeriesType;
}
|
| ︙ | ︙ | |||
290 291 292 293 294 295 296 | * None. * * Side effects: * *---------------------------------------------------------------------- */ static void | > | | > < | | | | > > > > | 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 |
* None.
*
* Side effects:
*
*----------------------------------------------------------------------
*/
static void
FreeArithSeriesInternalRep(
Tcl_Obj *arithSeriesObjPtr) /* Free any allocated memory */
{
ArithSeries *arithSeriesRepPtr = (ArithSeries*)
arithSeriesObjPtr->internalRep.twoPtrValue.ptr1;
if (arithSeriesRepPtr) {
if (arithSeriesRepPtr->elements) {
Tcl_WideInt i, len = arithSeriesRepPtr->len;
for (i=0; i<len; i++) {
Tcl_DecrRefCount(arithSeriesRepPtr->elements[i]);
}
Tcl_Free((char*)arithSeriesRepPtr->elements);
arithSeriesRepPtr->elements = NULL;
}
Tcl_Free((char*)arithSeriesRepPtr);
}
}
/*
*----------------------------------------------------------------------
*
* NewArithSeriesInt --
*
* Creates a new ArithSeries object. The returned object has
* refcount = 0.
*
* Results:
*
* A Tcl_Obj pointer to the created ArithSeries object.
* A NULL pointer of the range is invalid.
*
* Side Effects:
*
* None.
*----------------------------------------------------------------------
*/
static
Tcl_Obj *
NewArithSeriesInt(
Tcl_WideInt start,
Tcl_WideInt end,
Tcl_WideInt step,
Tcl_WideInt len)
{
Tcl_WideInt length;
Tcl_Obj *arithSeriesObj;
ArithSeries *arithSeriesRepPtr;
length = len>=0 ? len : -1;
if (length < 0) length = -1;
|
| ︙ | ︙ | |||
353 354 355 356 357 358 359 |
arithSeriesRepPtr->end = end;
arithSeriesRepPtr->step = step;
arithSeriesRepPtr->len = length;
arithSeriesRepPtr->elements = NULL;
arithSeriesObj->internalRep.twoPtrValue.ptr1 = arithSeriesRepPtr;
arithSeriesObj->internalRep.twoPtrValue.ptr2 = NULL;
arithSeriesObj->typePtr = &arithSeriesType;
| > | | > | | | | > > > > | 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 |
arithSeriesRepPtr->end = end;
arithSeriesRepPtr->step = step;
arithSeriesRepPtr->len = length;
arithSeriesRepPtr->elements = NULL;
arithSeriesObj->internalRep.twoPtrValue.ptr1 = arithSeriesRepPtr;
arithSeriesObj->internalRep.twoPtrValue.ptr2 = NULL;
arithSeriesObj->typePtr = &arithSeriesType;
if (length > 0) {
Tcl_InvalidateStringRep(arithSeriesObj);
}
return arithSeriesObj;
}
/*
*----------------------------------------------------------------------
*
* NewArithSeriesDbl --
*
* Creates a new ArithSeries object with doubles. The returned object has
* refcount = 0.
*
* Results:
*
* A Tcl_Obj pointer to the created ArithSeries object.
* A NULL pointer of the range is invalid.
*
* Side Effects:
*
* None.
*----------------------------------------------------------------------
*/
static
Tcl_Obj *
NewArithSeriesDbl(
double start,
double end,
double step,
Tcl_WideInt len)
{
Tcl_WideInt length;
Tcl_Obj *arithSeriesObj;
ArithSeriesDbl *arithSeriesRepPtr;
length = len>=0 ? len : -1;
if (length < 0) {
|
| ︙ | ︙ | |||
410 411 412 413 414 415 416 |
arithSeriesRepPtr->elements = NULL;
arithSeriesRepPtr->precision = maxPrecision(start,end,step);
arithSeriesObj->internalRep.twoPtrValue.ptr1 = arithSeriesRepPtr;
arithSeriesObj->internalRep.twoPtrValue.ptr2 = NULL;
arithSeriesObj->typePtr = &arithSeriesType;
if (length > 0) {
| | | | | 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 |
arithSeriesRepPtr->elements = NULL;
arithSeriesRepPtr->precision = maxPrecision(start,end,step);
arithSeriesObj->internalRep.twoPtrValue.ptr1 = arithSeriesRepPtr;
arithSeriesObj->internalRep.twoPtrValue.ptr2 = NULL;
arithSeriesObj->typePtr = &arithSeriesType;
if (length > 0) {
Tcl_InvalidateStringRep(arithSeriesObj);
}
return arithSeriesObj;
}
/*
*----------------------------------------------------------------------
*
* assignNumber --
*
* Create the appropriate Tcl_Obj value for the given numeric values.
* Used locally only for decoding [lseq] numeric arguments.
* refcount = 0.
*
* Results:
*
* A Tcl_Obj pointer.
* No assignment on error.
*
* Side Effects:
*
* None.
*----------------------------------------------------------------------
*/
static void
assignNumber(
int useDoubles,
Tcl_WideInt *intNumberPtr,
double *dblNumberPtr,
|
| ︙ | ︙ | |||
475 476 477 478 479 480 481 | * * Creates a new ArithSeries object. Some arguments may be NULL and will * be computed based on the other given arguments. * refcount = 0. * * Results: * | | | | | 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 |
*
* Creates a new ArithSeries object. Some arguments may be NULL and will
* be computed based on the other given arguments.
* refcount = 0.
*
* Results:
*
* A Tcl_Obj pointer to the created ArithSeries object.
* An empty Tcl_Obj if the range is invalid.
*
* Side Effects:
*
* None.
*----------------------------------------------------------------------
*/
int
TclNewArithSeriesObj(
Tcl_Interp *interp, /* For error reporting */
Tcl_Obj **arithSeriesObj, /* return value */
|
| ︙ | ︙ | |||
558 559 560 561 562 563 564 |
} else {
end = start + (step * (len-1));
dend = end;
}
}
if (len > TCL_SIZE_MAX) {
| | < | | < | | | | | | | | | | > | > | | > > | | | | | > | | | | | | | | | 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 |
} else {
end = start + (step * (len-1));
dend = end;
}
}
if (len > TCL_SIZE_MAX) {
Tcl_SetObjResult(interp,
Tcl_NewStringObj("max length of a Tcl list exceeded", -1));
Tcl_SetErrorCode(interp, "TCL", "MEMORY", (void *)NULL);
return TCL_ERROR;
}
if (arithSeriesObj) {
*arithSeriesObj = (useDoubles)
? NewArithSeriesDbl(dstart, dend, dstep, len)
: NewArithSeriesInt(start, end, step, len);
}
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
* TclArithSeriesObjIndex --
*
* Returns the element with the specified index in the list represented
* by the specified Arithmetic Sequence object. If the index is out of
* range, TCL_ERROR is returned, otherwise TCL_OK is returned and the
* integer value of the element is stored in *element.
*
* Results:
*
* TCL_OK on success.
*
* Side Effects:
*
* On success, the integer pointed by *element is modified.
* An empty string ("") is assigned if index is out-of-bounds.
*
*----------------------------------------------------------------------
*/
int
TclArithSeriesObjIndex(
TCL_UNUSED(Tcl_Interp *), /* Used for error reporting if not NULL. */
Tcl_Obj *arithSeriesObj, /* List obj */
Tcl_Size index, /* index to element of interest */
Tcl_Obj **elemObj) /* Return value */
{
ArithSeries *arithSeriesRepPtr = ArithSeriesGetInternalRep(arithSeriesObj);
if (index < 0 || arithSeriesRepPtr->len <= index) {
*elemObj = NULL;
} else {
/* List[i] = Start + (Step * index) */
if (arithSeriesRepPtr->isDouble) {
*elemObj = Tcl_NewDoubleObj(
ArithSeriesIndexDbl(arithSeriesRepPtr, index));
} else {
*elemObj = Tcl_NewWideIntObj(
ArithSeriesIndexInt(arithSeriesRepPtr, index));
}
}
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
* ArithSeriesObjLength
*
* Returns the length of the arithmetic series.
*
* Results:
*
* The length of the series as Tcl_WideInt.
*
* Side Effects:
*
* None.
*
*----------------------------------------------------------------------
*/
Tcl_Size
ArithSeriesObjLength(
Tcl_Obj *arithSeriesObj)
{
ArithSeries *arithSeriesRepPtr = (ArithSeries*)
arithSeriesObj->internalRep.twoPtrValue.ptr1;
return arithSeriesRepPtr->len;
}
/*
*----------------------------------------------------------------------
*
* TclArithSeriesObjStep --
*
* Return a Tcl_Obj with the step value from the give ArithSeries Obj.
* refcount = 0.
*
* Results:
*
* A Tcl_Obj pointer to the created ArithSeries object.
* A NULL pointer of the range is invalid.
*
* Side Effects:
*
* None.
*----------------------------------------------------------------------
*/
int
TclArithSeriesObjStep(
Tcl_Obj *arithSeriesObj,
Tcl_Obj **stepObj)
{
ArithSeries *arithSeriesRepPtr = ArithSeriesGetInternalRep(arithSeriesObj);
if (arithSeriesRepPtr->isDouble) {
*stepObj = Tcl_NewDoubleObj(
((ArithSeriesDbl*)(arithSeriesRepPtr))->step);
} else {
*stepObj = Tcl_NewWideIntObj(arithSeriesRepPtr->step);
}
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
* SetArithSeriesFromAny --
*
* The Arithmetic Series object is just an way to optimize
* Lists' space complexity, so no one should try to convert
* a string to an Arithmetic Series object.
*
* This function is here just to populate the Type structure.
*
* Results:
*
* The result is always TCL_ERROR. But see Side Effects.
*
* Side effects:
*
* Tcl Panic if called.
*
*----------------------------------------------------------------------
*/
static int
SetArithSeriesFromAny(
TCL_UNUSED(Tcl_Interp *), /* Used for error reporting if not NULL. */
TCL_UNUSED(Tcl_Obj *)) /* The object to convert. */
{
Tcl_Panic("SetArithSeriesFromAny: should never be called");
return TCL_ERROR;
}
/*
*----------------------------------------------------------------------
|
| ︙ | ︙ | |||
795 796 797 798 799 800 801 |
* Even if nothing below causes any changes, we still want the
* string-canonizing effect of [lrange 0 end].
*/
TclInvalidateStringRep(arithSeriesObj);
if (arithSeriesRepPtr->isDouble) {
| | > | | | 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 |
* Even if nothing below causes any changes, we still want the
* string-canonizing effect of [lrange 0 end].
*/
TclInvalidateStringRep(arithSeriesObj);
if (arithSeriesRepPtr->isDouble) {
ArithSeriesDbl *arithSeriesDblRepPtr = (ArithSeriesDbl*)
arithSeriesRepPtr;
double start, end, step;
Tcl_GetDoubleFromObj(NULL, startObj, &start);
Tcl_GetDoubleFromObj(NULL, endObj, &end);
Tcl_GetDoubleFromObj(NULL, stepObj, &step);
arithSeriesDblRepPtr->start = start;
arithSeriesDblRepPtr->end = end;
arithSeriesDblRepPtr->step = step;
arithSeriesDblRepPtr->precision = maxPrecision(start, end, step);
arithSeriesDblRepPtr->len = ArithSeriesLenDbl(
start, end, step, arithSeriesDblRepPtr->precision);
arithSeriesDblRepPtr->elements = NULL;
} else {
Tcl_WideInt start, end, step;
Tcl_GetWideIntFromObj(NULL, startObj, &start);
Tcl_GetWideIntFromObj(NULL, endObj, &end);
Tcl_GetWideIntFromObj(NULL, stepObj, &step);
|
| ︙ | ︙ | |||
885 886 887 888 889 890 891 |
/* If this exists, it has already been populated */
objv = arithSeriesRepPtr->elements;
} else {
/* Construct the elements array */
objv = (Tcl_Obj **)Tcl_Alloc(sizeof(Tcl_Obj*) * objc);
if (objv == NULL) {
if (interp) {
| | < | 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 |
/* If this exists, it has already been populated */
objv = arithSeriesRepPtr->elements;
} else {
/* Construct the elements array */
objv = (Tcl_Obj **)Tcl_Alloc(sizeof(Tcl_Obj*) * objc);
if (objv == NULL) {
if (interp) {
Tcl_SetObjResult(interp,
Tcl_NewStringObj("max length of a Tcl list exceeded", -1));
Tcl_SetErrorCode(interp, "TCL", "MEMORY", (void *)NULL);
}
return TCL_ERROR;
}
arithSeriesRepPtr->elements = objv;
for (i = 0; i < objc; i++) {
|
| ︙ | ︙ | |||
908 909 910 911 912 913 914 |
} else {
objv = NULL;
}
*objvPtr = objv;
*objcPtr = objc;
} else {
if (interp != NULL) {
| | < | 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 |
} else {
objv = NULL;
}
*objvPtr = objv;
*objcPtr = objc;
} else {
if (interp != NULL) {
Tcl_SetObjResult(interp,
Tcl_ObjPrintf("value is not an arithseries"));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "UNKNOWN", (void *)NULL);
}
return TCL_ERROR;
}
return TCL_OK;
}
|
| ︙ | ︙ | |||
1042 1043 1044 1045 1046 1047 1048 | * Note: This procedure does not invalidate an existing old string rep * so storage will be lost if this has not already been done. * * Results: * None. * * Side effects: | | | | | | | | | | | > | > | 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 |
* Note: This procedure does not invalidate an existing old string rep
* so storage will be lost if this has not already been done.
*
* Results:
* None.
*
* Side effects:
* The object's string is set to a valid string that results from the
* list-to-string conversion. This string will be empty if the list has
* no elements. The list internal representation should not be NULL and
* we assume it is not NULL.
*
* Notes:
* At the cost of overallocation it's possible to estimate the length of
* the string representation and make this procedure much faster.
* Because the programmer shouldn't expect the string conversion of a
* big arithmetic sequence to be fast, this version takes more care of
* space than time.
*
*----------------------------------------------------------------------
*/
static void
UpdateStringOfArithSeries(
Tcl_Obj *arithSeriesObjPtr)
{
ArithSeries *arithSeriesRepPtr = (ArithSeries*)
arithSeriesObjPtr->internalRep.twoPtrValue.ptr1;
char *p;
Tcl_Obj *eleObj;
Tcl_Size i, bytlen = 0;
/*
* Pass 1: estimate space.
*/
|
| ︙ | ︙ | |||
1133 1134 1135 1136 1137 1138 1139 |
static int
ArithSeriesInOperation(
Tcl_Interp *interp,
Tcl_Obj *valueObj,
Tcl_Obj *arithSeriesObjPtr,
int *boolResult)
{
| | > | | 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 |
static int
ArithSeriesInOperation(
Tcl_Interp *interp,
Tcl_Obj *valueObj,
Tcl_Obj *arithSeriesObjPtr,
int *boolResult)
{
ArithSeries *arithSeriesRepPtr = (ArithSeries*)
arithSeriesObjPtr->internalRep.twoPtrValue.ptr1;
ArithSeriesDbl *dblRepPtr = (ArithSeriesDbl*) arithSeriesRepPtr;
int status;
Tcl_Size index, incr, elen, vlen;
if (arithSeriesRepPtr->isDouble) {
double y;
int test = 0;
|
| ︙ | ︙ |
Changes to generic/tclAssembly.c.
| ︙ | ︙ | |||
47 48 49 50 51 52 53 |
* State identified for a basic block's catch context.
*/
typedef enum BasicBlockCatchState {
BBCS_UNKNOWN = 0, /* Catch context has not yet been identified */
BBCS_NONE, /* Block is outside of any catch */
BBCS_INCATCH, /* Block is within a catch context */
| | | 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
* State identified for a basic block's catch context.
*/
typedef enum BasicBlockCatchState {
BBCS_UNKNOWN = 0, /* Catch context has not yet been identified */
BBCS_NONE, /* Block is outside of any catch */
BBCS_INCATCH, /* Block is within a catch context */
BBCS_CAUGHT /* Block is within a catch context and
* may be executed after an exception fires */
} BasicBlockCatchState;
/*
* Structure that defines a basic block - a linear sequence of bytecode
* instructions with no jumps in or out (including not changing the
* state of any exception range).
|
| ︙ | ︙ | |||
218 219 220 221 222 223 224 |
typedef struct AssemblyEnv {
CompileEnv* envPtr; /* Compilation environment being used for code
* generation */
Tcl_Parse* parsePtr; /* Parse of the current line of source */
Tcl_HashTable labelHash; /* Hash table whose keys are labels and whose
* values are 'label' objects storing the code
* offsets of the labels. */
| | | | 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 |
typedef struct AssemblyEnv {
CompileEnv* envPtr; /* Compilation environment being used for code
* generation */
Tcl_Parse* parsePtr; /* Parse of the current line of source */
Tcl_HashTable labelHash; /* Hash table whose keys are labels and whose
* values are 'label' objects storing the code
* offsets of the labels. */
Tcl_Size cmdLine; /* Current line number within the assembly
* code */
Tcl_Size* clNext; /* Invisible continuation line for
* [info frame] */
BasicBlock* head_bb; /* First basic block in the code */
BasicBlock* curr_bb; /* Current basic block */
int maxDepth; /* Maximum stack depth encountered */
int curCatchDepth; /* Current depth of catches */
int maxCatchDepth; /* Maximum depth of catches encountered */
int flags; /* Compilation flags (TCL_EVAL_DIRECT) */
|
| ︙ | ︙ | |||
1268 1269 1270 1271 1272 1273 1274 |
TalInstType instType; /* Type of the instruction */
Tcl_Obj* operand1Obj = NULL;
/* First operand to the instruction */
const char* operand1; /* String rep of the operand */
Tcl_Size operand1Len; /* String length of the operand */
int opnd; /* Integer representation of an operand */
int litIndex; /* Literal pool index of a constant */
| | | 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 |
TalInstType instType; /* Type of the instruction */
Tcl_Obj* operand1Obj = NULL;
/* First operand to the instruction */
const char* operand1; /* String rep of the operand */
Tcl_Size operand1Len; /* String length of the operand */
int opnd; /* Integer representation of an operand */
int litIndex; /* Literal pool index of a constant */
Tcl_Size localVar; /* LVT index of a local variable */
int flags; /* Flags for a basic block */
JumptableInfo* jtPtr; /* Pointer to a jumptable */
int infoIndex; /* Index of the jumptable in auxdata */
int status = TCL_ERROR; /* Return value from this function */
/*
* Make sure that the instruction name is known at compile time.
|
| ︙ | ︙ | |||
1932 1933 1934 1935 1936 1937 1938 |
*/
DEBUG_PRINT("basic block %p has %d exceptions starting at %d\n",
curr_bb, exceptionCount, savedExceptArrayNext);
curr_bb->foreignExceptionBase = savedExceptArrayNext;
curr_bb->foreignExceptionCount = exceptionCount;
curr_bb->foreignExceptions =
| | | 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 |
*/
DEBUG_PRINT("basic block %p has %d exceptions starting at %d\n",
curr_bb, exceptionCount, savedExceptArrayNext);
curr_bb->foreignExceptionBase = savedExceptArrayNext;
curr_bb->foreignExceptionCount = exceptionCount;
curr_bb->foreignExceptions =
(ExceptionRange*)Tcl_Alloc(exceptionCount * sizeof(ExceptionRange));
memcpy(curr_bb->foreignExceptions,
envPtr->exceptArrayPtr + savedExceptArrayNext,
exceptionCount * sizeof(ExceptionRange));
for (i = 0; i < exceptionCount; ++i) {
curr_bb->foreignExceptions[i].nestingLevel -= envPtr->exceptDepth;
}
envPtr->exceptArrayNext = savedExceptArrayNext;
|
| ︙ | ︙ | |||
1965 1966 1967 1968 1969 1970 1971 |
*/
static int
CreateMirrorJumpTable(
AssemblyEnv* assemEnvPtr, /* Assembly environment */
Tcl_Obj* jumps) /* List of alternating keywords and labels */
{
| | | 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 |
*/
static int
CreateMirrorJumpTable(
AssemblyEnv* assemEnvPtr, /* Assembly environment */
Tcl_Obj* jumps) /* List of alternating keywords and labels */
{
Tcl_Size objc; /* Number of elements in the 'jumps' list */
Tcl_Obj** objv; /* Pointers to the elements in the list */
CompileEnv* envPtr = assemEnvPtr->envPtr;
/* Compilation environment */
Tcl_Interp* interp = (Tcl_Interp*) envPtr->iPtr;
/* Tcl interpreter */
BasicBlock* bbPtr = assemEnvPtr->curr_bb;
/* Current basic block */
|
| ︙ | ︙ | |||
2000 2001 2002 2003 2004 2005 2006 |
return TCL_ERROR;
}
/*
* Allocate the jumptable.
*/
| | > | | 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 |
return TCL_ERROR;
}
/*
* Allocate the jumptable.
*/
jtPtr = (JumptableInfo*) Tcl_Alloc(sizeof(JumptableInfo));
jtHashPtr = &jtPtr->hashTable;
Tcl_InitHashTable(jtHashPtr, TCL_STRING_KEYS);
/*
* Fill the keys and labels into the table.
*/
DEBUG_PRINT("jump table {\n");
for (i = 0; i < objc; i+=2) {
DEBUG_PRINT(" %s -> %s\n", TclGetString(objv[i]),
TclGetString(objv[i+1]));
hashEntry = Tcl_CreateHashEntry(jtHashPtr, TclGetString(objv[i]),
&isNew);
if (!isNew) {
if (assemEnvPtr->flags & TCL_EVAL_DIRECT) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"duplicate entry in jump table for \"%s\"",
TclGetString(objv[i])));
Tcl_SetErrorCode(interp,
"TCL", "ASSEM", "DUPJUMPTABLEENTRY", (void *)NULL);
DeleteMirrorJumpTable(jtPtr);
return TCL_ERROR;
}
}
Tcl_SetHashValue(hashEntry, objv[i+1]);
Tcl_IncrRefCount(objv[i+1]);
}
|
| ︙ | ︙ |
Changes to generic/tclAsync.c.
| ︙ | ︙ | |||
26 27 28 29 30 31 32 |
* invoked in the next call to
* Tcl_AsyncInvoke. */
struct AsyncHandler *nextPtr, *prevPtr;
/* Next, previous in list of all handlers
* for the process. */
Tcl_AsyncProc *proc; /* Procedure to call when handler is
* invoked. */
| | | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
* invoked in the next call to
* Tcl_AsyncInvoke. */
struct AsyncHandler *nextPtr, *prevPtr;
/* Next, previous in list of all handlers
* for the process. */
Tcl_AsyncProc *proc; /* Procedure to call when handler is
* invoked. */
void *clientData; /* Value to pass to handler when it is
* invoked. */
struct ThreadSpecificData *originTsd;
/* Used in Tcl_AsyncMark to modify thread-
* specific data from outside the thread it is
* associated to. */
Tcl_ThreadId originThrdId; /* Origin thread where this token was created
* and where it will be yielded. */
void *notifierData; /* Platform notifier data or NULL. */
} AsyncHandler;
typedef struct ThreadSpecificData {
int asyncReady; /* This is set to 1 whenever a handler becomes
* ready and it is cleared to zero whenever
* Tcl_AsyncInvoke is called. It can be
* checked elsewhere in the application by
|
| ︙ | ︙ | |||
138 139 140 141 142 143 144 |
*----------------------------------------------------------------------
*/
Tcl_AsyncHandler
Tcl_AsyncCreate(
Tcl_AsyncProc *proc, /* Procedure to call when handler is
* invoked. */
| | | 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
*----------------------------------------------------------------------
*/
Tcl_AsyncHandler
Tcl_AsyncCreate(
Tcl_AsyncProc *proc, /* Procedure to call when handler is
* invoked. */
void *clientData) /* Argument to pass to handler. */
{
AsyncHandler *asyncPtr;
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
asyncPtr = (AsyncHandler*)Tcl_Alloc(sizeof(AsyncHandler));
asyncPtr->ready = 0;
asyncPtr->nextPtr = NULL;
|
| ︙ | ︙ |
Changes to generic/tclBasic.c.
| ︙ | ︙ | |||
1516 1517 1518 1519 1520 1521 1522 |
*/
void
Tcl_CallWhenDeleted(
Tcl_Interp *interp, /* Interpreter to watch. */
Tcl_InterpDeleteProc *proc, /* Function to call when interpreter is about
* to be deleted. */
| | | 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 |
*/
void
Tcl_CallWhenDeleted(
Tcl_Interp *interp, /* Interpreter to watch. */
Tcl_InterpDeleteProc *proc, /* Function to call when interpreter is about
* to be deleted. */
void *clientData) /* One-word value to pass to proc. */
{
Interp *iPtr = (Interp *) interp;
static Tcl_ThreadDataKey assocDataCounterKey;
int *assocDataCounterPtr =
(int *)Tcl_GetThreadData(&assocDataCounterKey, sizeof(int));
int isNew;
char buffer[32 + TCL_INTEGER_SPACE];
|
| ︙ | ︙ | |||
1564 1565 1566 1567 1568 1569 1570 |
*/
void
Tcl_DontCallWhenDeleted(
Tcl_Interp *interp, /* Interpreter to watch. */
Tcl_InterpDeleteProc *proc, /* Function to call when interpreter is about
* to be deleted. */
| | | 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 |
*/
void
Tcl_DontCallWhenDeleted(
Tcl_Interp *interp, /* Interpreter to watch. */
Tcl_InterpDeleteProc *proc, /* Function to call when interpreter is about
* to be deleted. */
void *clientData) /* One-word value to pass to proc. */
{
Interp *iPtr = (Interp *) interp;
Tcl_HashTable *hTablePtr;
Tcl_HashSearch hSearch;
Tcl_HashEntry *hPtr;
AssocData *dPtr;
|
| ︙ | ︙ | |||
1612 1613 1614 1615 1616 1617 1618 |
void
Tcl_SetAssocData(
Tcl_Interp *interp, /* Interpreter to associate with. */
const char *name, /* Name for association. */
Tcl_InterpDeleteProc *proc, /* Proc to call when interpreter is about to
* be deleted. */
| | | 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 |
void
Tcl_SetAssocData(
Tcl_Interp *interp, /* Interpreter to associate with. */
const char *name, /* Name for association. */
Tcl_InterpDeleteProc *proc, /* Proc to call when interpreter is about to
* be deleted. */
void *clientData) /* One-word value to pass to proc. */
{
Interp *iPtr = (Interp *) interp;
AssocData *dPtr;
Tcl_HashEntry *hPtr;
int isNew;
if (iPtr->assocData == NULL) {
|
| ︙ | ︙ | |||
2489 2490 2491 2492 2493 2494 2495 |
Tcl_Interp *interp, /* Token for command interpreter returned by a
* previous call to Tcl_CreateInterp. */
const char *cmdName, /* Name of command. If it contains namespace
* qualifiers, the new command is put in the
* specified namespace; otherwise it is put in
* the global namespace. */
Tcl_CmdProc *proc, /* Function to associate with cmdName. */
| | | 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 |
Tcl_Interp *interp, /* Token for command interpreter returned by a
* previous call to Tcl_CreateInterp. */
const char *cmdName, /* Name of command. If it contains namespace
* qualifiers, the new command is put in the
* specified namespace; otherwise it is put in
* the global namespace. */
Tcl_CmdProc *proc, /* Function to associate with cmdName. */
void *clientData, /* Arbitrary value passed to string proc. */
Tcl_CmdDeleteProc *deleteProc)
/* If not NULL, gives a function to call when
* this command is deleted. */
{
Interp *iPtr = (Interp *) interp;
ImportRef *oldRefPtr = NULL;
Namespace *nsPtr;
|
| ︙ | ︙ | |||
2678 2679 2680 2681 2682 2683 2684 |
* on the calling sequence.
*
*----------------------------------------------------------------------
*/
typedef struct {
Tcl_ObjCmdProc2 *proc;
| | | < | > | 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 |
* on the calling sequence.
*
*----------------------------------------------------------------------
*/
typedef struct {
Tcl_ObjCmdProc2 *proc;
void *clientData; /* Arbitrary value to pass to proc function. */
Tcl_CmdDeleteProc *deleteProc;
void *deleteData; /* Arbitrary value to pass to deleteProc function. */
Tcl_ObjCmdProc2 *nreProc;
} CmdWrapperInfo;
static int cmdWrapperProc(
void *clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj * const *objv)
{
CmdWrapperInfo *info = (CmdWrapperInfo *)clientData;
if (objc < 0) {
objc = -1;
|
| ︙ | ︙ | |||
2718 2719 2720 2721 2722 2723 2724 |
* previous call to Tcl_CreateInterp). */
const char *cmdName, /* Name of command. If it contains namespace
* qualifiers, the new command is put in the
* specified namespace; otherwise it is put in
* the global namespace. */
Tcl_ObjCmdProc2 *proc, /* Object-based function to associate with
* name. */
| | | 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 |
* previous call to Tcl_CreateInterp). */
const char *cmdName, /* Name of command. If it contains namespace
* qualifiers, the new command is put in the
* specified namespace; otherwise it is put in
* the global namespace. */
Tcl_ObjCmdProc2 *proc, /* Object-based function to associate with
* name. */
void *clientData, /* Arbitrary value to pass to object
* function. */
Tcl_CmdDeleteProc *deleteProc
/* If not NULL, gives a function to call when
* this command is deleted. */
)
{
CmdWrapperInfo *info = (CmdWrapperInfo *)Tcl_Alloc(sizeof(CmdWrapperInfo));
|
| ︙ | ︙ | |||
2746 2747 2748 2749 2750 2751 2752 |
* previous call to Tcl_CreateInterp). */
const char *cmdName, /* Name of command. If it contains namespace
* qualifiers, the new command is put in the
* specified namespace; otherwise it is put in
* the global namespace. */
Tcl_ObjCmdProc *proc, /* Object-based function to associate with
* name. */
| | | 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 |
* previous call to Tcl_CreateInterp). */
const char *cmdName, /* Name of command. If it contains namespace
* qualifiers, the new command is put in the
* specified namespace; otherwise it is put in
* the global namespace. */
Tcl_ObjCmdProc *proc, /* Object-based function to associate with
* name. */
void *clientData, /* Arbitrary value to pass to object
* function. */
Tcl_CmdDeleteProc *deleteProc
/* If not NULL, gives a function to call when
* this command is deleted. */
)
{
Interp *iPtr = (Interp *) interp;
|
| ︙ | ︙ | |||
2796 2797 2798 2799 2800 2801 2802 |
TclCreateObjCommandInNs(
Tcl_Interp *interp,
const char *cmdName, /* Name of command, without any namespace
* components. */
Tcl_Namespace *namesp, /* The namespace to create the command in */
Tcl_ObjCmdProc *proc, /* Object-based function to associate with
* name. */
| | | 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 |
TclCreateObjCommandInNs(
Tcl_Interp *interp,
const char *cmdName, /* Name of command, without any namespace
* components. */
Tcl_Namespace *namesp, /* The namespace to create the command in */
Tcl_ObjCmdProc *proc, /* Object-based function to associate with
* name. */
void *clientData, /* Arbitrary value to pass to object
* function. */
Tcl_CmdDeleteProc *deleteProc)
/* If not NULL, gives a function to call when
* this command is deleted. */
{
int deleted = 0, isNew = 0;
Command *cmdPtr;
|
| ︙ | ︙ | |||
2965 2966 2967 2968 2969 2970 2971 | * InvokeStringCommand allocates and frees storage. * *---------------------------------------------------------------------- */ int InvokeStringCommand( | | | | 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 |
* InvokeStringCommand allocates and frees storage.
*
*----------------------------------------------------------------------
*/
int
InvokeStringCommand(
void *clientData, /* Points to command's Command structure. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
Command *cmdPtr = (Command *)clientData;
int i, result;
const char **argv = (const char **)
TclStackAlloc(interp, (objc + 1) * sizeof(char *));
|
| ︙ | ︙ | |||
3253 3254 3255 3256 3257 3258 3259 | * None. * *---------------------------------------------------------------------- */ static int invokeObj2Command( | | | 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 |
* None.
*
*----------------------------------------------------------------------
*/
static int
invokeObj2Command(
void *clientData, /* Points to command's Command structure. */
Tcl_Interp *interp, /* Current interpreter. */
Tcl_Size objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
int result;
Command *cmdPtr = (Command *) clientData;
|
| ︙ | ︙ | |||
3905 3906 3907 3908 3909 3910 3911 | * Transfers a message from the cancellation message to the interpreter. * *---------------------------------------------------------------------- */ static int CancelEvalProc( | | | 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 |
* Transfers a message from the cancellation message to the interpreter.
*
*----------------------------------------------------------------------
*/
static int
CancelEvalProc(
void *clientData, /* Interp to cancel the script in progress. */
TCL_UNUSED(Tcl_Interp *),
int code) /* Current return code from command. */
{
CancelInfo *cancelInfo = (CancelInfo *)clientData;
Interp *iPtr;
if (cancelInfo != NULL) {
|
| ︙ | ︙ | |||
3983 3984 3985 3986 3987 3988 3989 | * deleted or when the last ByteCode referring to it is freed. * *---------------------------------------------------------------------- */ void TclCleanupCommand( | | | 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 |
* deleted or when the last ByteCode referring to it is freed.
*
*----------------------------------------------------------------------
*/
void
TclCleanupCommand(
Command *cmdPtr) /* Points to the Command structure to
* be freed. */
{
if (cmdPtr->refCount-- <= 1) {
Tcl_Free(cmdPtr);
}
}
|
| ︙ | ︙ | |||
4231 4232 4233 4234 4235 4236 4237 |
int
Tcl_CancelEval(
Tcl_Interp *interp, /* Interpreter in which to cancel the
* script. */
Tcl_Obj *resultObjPtr, /* The script cancellation error message or
* NULL for a default error message. */
| | | 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 |
int
Tcl_CancelEval(
Tcl_Interp *interp, /* Interpreter in which to cancel the
* script. */
Tcl_Obj *resultObjPtr, /* The script cancellation error message or
* NULL for a default error message. */
void *clientData, /* Passed to CancelEvalProc. */
int flags) /* Collection of OR-ed bits that control
* the cancellation of the script. Only
* TCL_CANCEL_UNWIND is currently
* supported. */
{
Tcl_HashEntry *hPtr;
CancelInfo *cancelInfo;
|
| ︙ | ︙ | |||
5056 5057 5058 5059 5060 5061 5062 |
int
Tcl_EvalTokensStandard(
Tcl_Interp *interp, /* Interpreter in which to lookup variables,
* execute nested commands, and report
* errors. */
Tcl_Token *tokenPtr, /* Pointer to first in an array of tokens to
* evaluate and concatenate. */
| | | 5056 5057 5058 5059 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 |
int
Tcl_EvalTokensStandard(
Tcl_Interp *interp, /* Interpreter in which to lookup variables,
* execute nested commands, and report
* errors. */
Tcl_Token *tokenPtr, /* Pointer to first in an array of tokens to
* evaluate and concatenate. */
Tcl_Size count) /* Number of tokens to consider at tokenPtr.
* Must be at least 1. */
{
return TclSubstTokens(interp, tokenPtr, count, /* numLeftPtr */ NULL, 1,
NULL, NULL);
}
/*
|
| ︙ | ︙ | |||
5111 5112 5113 5114 5115 5116 5117 |
Tcl_Size numBytes, /* Number of bytes in script. If -1, the
* script consists of all bytes up to the
* first NUL character. */
int flags, /* Collection of OR-ed bits that control the
* evaluation of the script. Only
* TCL_EVAL_GLOBAL is currently supported. */
Tcl_Size line, /* The line the script starts on. */
| | | 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 |
Tcl_Size numBytes, /* Number of bytes in script. If -1, the
* script consists of all bytes up to the
* first NUL character. */
int flags, /* Collection of OR-ed bits that control the
* evaluation of the script. Only
* TCL_EVAL_GLOBAL is currently supported. */
Tcl_Size line, /* The line the script starts on. */
Tcl_Size *clNextOuter, /* Information about an outer context for */
const char *outerScript) /* continuation line data. This is set only in
* TclSubstTokens(), to properly handle
* [...]-nested commands. The 'outerScript'
* refers to the most-outer script containing
* the embedded command, which is referred to
* by 'script'. The 'clNextOuter' refers to
* the current entry in the table of
|
| ︙ | ︙ | |||
5155 5156 5157 5158 5159 5160 5161 |
CmdFrame *eeFramePtr = (CmdFrame *)TclStackAlloc(interp, sizeof(CmdFrame));
Tcl_Obj **stackObjArray = (Tcl_Obj **)
TclStackAlloc(interp, minObjs * sizeof(Tcl_Obj *));
int *expandStack = (int *)TclStackAlloc(interp, minObjs * sizeof(int));
Tcl_Size *linesStack = (Tcl_Size *)TclStackAlloc(interp, minObjs * sizeof(Tcl_Size));
/* TIP #280 Structures for tracking of command
* locations. */
| | | 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 5169 |
CmdFrame *eeFramePtr = (CmdFrame *)TclStackAlloc(interp, sizeof(CmdFrame));
Tcl_Obj **stackObjArray = (Tcl_Obj **)
TclStackAlloc(interp, minObjs * sizeof(Tcl_Obj *));
int *expandStack = (int *)TclStackAlloc(interp, minObjs * sizeof(int));
Tcl_Size *linesStack = (Tcl_Size *)TclStackAlloc(interp, minObjs * sizeof(Tcl_Size));
/* TIP #280 Structures for tracking of command
* locations. */
Tcl_Size *clNext = NULL; /* Pointer for the tracking of invisible
* continuation lines. Initialized only if the
* caller gave us a table of locations to
* track, via scriptCLLocPtr. It always refers
* to the table entry holding the location of
* the next invisible continuation line to
* look for, while parsing the script. */
|
| ︙ | ︙ | |||
6641 6642 6643 6644 6645 6646 6647 |
*----------------------------------------------------------------------
*/
int
TclObjInvoke(
Tcl_Interp *interp, /* Interpreter in which command is to be
* invoked. */
| | | 6641 6642 6643 6644 6645 6646 6647 6648 6649 6650 6651 6652 6653 6654 6655 |
*----------------------------------------------------------------------
*/
int
TclObjInvoke(
Tcl_Interp *interp, /* Interpreter in which command is to be
* invoked. */
Tcl_Size objc, /* Count of arguments. */
Tcl_Obj *const objv[], /* Argument objects; objv[0] points to the
* name of the command to invoke. */
int flags) /* Combination of flags controlling the call:
* TCL_INVOKE_HIDDEN, TCL_INVOKE_NO_UNKNOWN,
* or TCL_INVOKE_NO_TRACEBACK. */
{
if (interp == NULL) {
|
| ︙ | ︙ | |||
7232 7233 7234 7235 7236 7237 7238 |
Tcl_SetObjResult(interp, Tcl_NewDoubleObj(sqrt(d)));
}
return TCL_OK;
}
static int
ExprUnaryFunc(
| | | 7232 7233 7234 7235 7236 7237 7238 7239 7240 7241 7242 7243 7244 7245 7246 |
Tcl_SetObjResult(interp, Tcl_NewDoubleObj(sqrt(d)));
}
return TCL_OK;
}
static int
ExprUnaryFunc(
void *clientData, /* Contains the address of a function that
* takes one double argument and returns a
* double result. */
Tcl_Interp *interp, /* The interpreter in which to execute the
* function. */
int objc, /* Actual parameter count */
Tcl_Obj *const *objv) /* Actual parameter list */
{
|
| ︙ | ︙ | |||
7296 7297 7298 7299 7300 7301 7302 |
}
Tcl_SetObjResult(interp, Tcl_NewDoubleObj(dResult));
return TCL_OK;
}
static int
ExprBinaryFunc(
| | | 7296 7297 7298 7299 7300 7301 7302 7303 7304 7305 7306 7307 7308 7309 7310 |
}
Tcl_SetObjResult(interp, Tcl_NewDoubleObj(dResult));
return TCL_OK;
}
static int
ExprBinaryFunc(
void *clientData, /* Contains the address of a function that
* takes two double arguments and returns a
* double result. */
Tcl_Interp *interp, /* The interpreter in which to execute the
* function. */
int objc, /* Actual parameter count. */
Tcl_Obj *const *objv) /* Parameter vector. */
{
|
| ︙ | ︙ | |||
8588 8589 8590 8591 8592 8593 8594 |
* specified namespace; otherwise it is put in
* the global namespace. */
Tcl_ObjCmdProc *proc, /* Object-based function to associate with
* name, provides direct access for direct
* calls. */
Tcl_ObjCmdProc *nreProc, /* Object-based function to associate with
* name, provides NR implementation */
| | | 8588 8589 8590 8591 8592 8593 8594 8595 8596 8597 8598 8599 8600 8601 8602 |
* specified namespace; otherwise it is put in
* the global namespace. */
Tcl_ObjCmdProc *proc, /* Object-based function to associate with
* name, provides direct access for direct
* calls. */
Tcl_ObjCmdProc *nreProc, /* Object-based function to associate with
* name, provides NR implementation */
void *clientData, /* Arbitrary value to pass to object
* function. */
Tcl_CmdDeleteProc *deleteProc)
/* If not NULL, gives a function to call when
* this command is deleted. */
{
Command *cmdPtr = (Command *)
Tcl_CreateObjCommand(interp, cmdName, proc, clientData,
|
| ︙ | ︙ | |||
8637 8638 8639 8640 8641 8642 8643 |
return TclNREvalObjEx(interp, objPtr, flags, NULL, INT_MIN);
}
int
Tcl_NREvalObjv(
Tcl_Interp *interp, /* Interpreter in which to evaluate the
* command. Also used for error reporting. */
| | | 8637 8638 8639 8640 8641 8642 8643 8644 8645 8646 8647 8648 8649 8650 8651 |
return TclNREvalObjEx(interp, objPtr, flags, NULL, INT_MIN);
}
int
Tcl_NREvalObjv(
Tcl_Interp *interp, /* Interpreter in which to evaluate the
* command. Also used for error reporting. */
Tcl_Size objc, /* Number of words in command. */
Tcl_Obj *const objv[], /* An array of pointers to objects that are
* the words that make up the command. */
int flags) /* Collection of OR-ed bits that control the
* evaluation of the script. Only
* TCL_EVAL_GLOBAL, TCL_EVAL_INVOKE and
* TCL_EVAL_NOERR are currently supported. */
{
|
| ︙ | ︙ | |||
8818 8819 8820 8821 8822 8823 8824 |
/*
* The tailcall data is in a Tcl list: the first element is the
* namespace, the rest the command to be tailcalled.
*/
nsObjPtr = Tcl_NewStringObj(nsPtr->fullName, -1);
listPtr = Tcl_NewListObj(objc, objv);
| | | 8818 8819 8820 8821 8822 8823 8824 8825 8826 8827 8828 8829 8830 8831 8832 |
/*
* The tailcall data is in a Tcl list: the first element is the
* namespace, the rest the command to be tailcalled.
*/
nsObjPtr = Tcl_NewStringObj(nsPtr->fullName, -1);
listPtr = Tcl_NewListObj(objc, objv);
TclListObjSetElement(interp, listPtr, 0, nsObjPtr);
iPtr->varFramePtr->tailcallPtr = listPtr;
}
return TCL_RETURN;
}
/*
|
| ︙ | ︙ |
Changes to generic/tclBinary.c.
| ︙ | ︙ | |||
764 765 766 767 768 769 770 |
if ((BYTEARRAY_MAX_LEN - byteArrayPtr->used) < len) {
/* Will wrap around !! */
Tcl_Panic("max size of a byte array exceeded");
}
needed = byteArrayPtr->used + len;
if (needed > byteArrayPtr->allocated) {
Tcl_Size newCapacity;
| | < | < | < | 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 |
if ((BYTEARRAY_MAX_LEN - byteArrayPtr->used) < len) {
/* Will wrap around !! */
Tcl_Panic("max size of a byte array exceeded");
}
needed = byteArrayPtr->used + len;
if (needed > byteArrayPtr->allocated) {
Tcl_Size newCapacity;
byteArrayPtr = (ByteArray *) TclReallocElemsEx(
byteArrayPtr, needed, 1,
offsetof(ByteArray, bytes), &newCapacity);
byteArrayPtr->allocated = newCapacity;
SET_BYTEARRAY(irPtr, byteArrayPtr);
}
if (bytes) {
memcpy(byteArrayPtr->bytes + byteArrayPtr->used, bytes, len);
}
|
| ︙ | ︙ |
Changes to generic/tclCkalloc.c.
| ︙ | ︙ | |||
1249 1250 1251 1252 1253 1254 1255 | * Panics if memory of at least the requested size could not be * allocated. * *------------------------------------------------------------------------ */ void * TclAllocElemsEx( | | | | | | | < | 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 |
* Panics if memory of at least the requested size could not be
* allocated.
*
*------------------------------------------------------------------------
*/
void *
TclAllocElemsEx(
Tcl_Size elemCount, /* Allocation will store at least these many... */
Tcl_Size elemSize, /* ...elements of this size */
Tcl_Size leadSize, /* Additional leading space in bytes */
Tcl_Size *capacityPtr) /* OUTPUT: Actual capacity is stored
* here if non-NULL. Only modified on success */
{
void *ptr = TclAttemptReallocElemsEx(
NULL, elemCount, elemSize, leadSize, capacityPtr);
if (ptr == NULL) {
Tcl_Panic("Failed to allocate %" TCL_SIZE_MODIFIER
"d elements of size %" TCL_SIZE_MODIFIER "d bytes.",
elemCount, elemSize);
}
return ptr;
}
/*
*------------------------------------------------------------------------
*
|
| ︙ | ︙ | |||
1284 1285 1286 1287 1288 1289 1290 | * Pointer to allocated memory block which is at least as large * as the requested size or NULL if allocation failed. * *------------------------------------------------------------------------ */ void * TclAttemptReallocElemsEx( | | | | | | | | | 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 |
* Pointer to allocated memory block which is at least as large
* as the requested size or NULL if allocation failed.
*
*------------------------------------------------------------------------
*/
void *
TclAttemptReallocElemsEx(
void *oldPtr, /* Pointer to memory block to reallocate or
* NULL to indicate this is a new allocation */
Tcl_Size elemCount, /* Allocation will store at least these many... */
Tcl_Size elemSize, /* ...elements of this size */
Tcl_Size leadSize, /* Additional leading space in bytes */
Tcl_Size *capacityPtr) /* OUTPUT: Actual capacity is stored
* here if non-NULL. Only modified on success */
{
void *ptr;
Tcl_Size limit;
Tcl_Size attempt;
assert(elemCount > 0);
assert(elemSize > 0);
|
| ︙ | ︙ | |||
1354 1355 1356 1357 1358 1359 1360 | * Panics if memory of at least the requested size could not be * allocated. * *------------------------------------------------------------------------ */ void * TclReallocElemsEx( | | | | | | | | < | 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 |
* Panics if memory of at least the requested size could not be
* allocated.
*
*------------------------------------------------------------------------
*/
void *
TclReallocElemsEx(
void *oldPtr, /* Pointer to memory block to reallocate */
Tcl_Size elemCount, /* Allocation will store at least these many... */
Tcl_Size elemSize, /* ...elements of this size */
Tcl_Size leadSize, /* Additional leading space in bytes */
Tcl_Size *capacityPtr) /* OUTPUT: Actual capacity is stored
* here if non-NULL. Only modified on success */
{
void *ptr = TclAttemptReallocElemsEx(
oldPtr, elemCount, elemSize, leadSize, capacityPtr);
if (ptr == NULL) {
Tcl_Panic("Failed to reallocate %" TCL_SIZE_MODIFIER
"d elements of size %" TCL_SIZE_MODIFIER "d bytes.",
elemCount, elemSize);
}
return ptr;
}
/*
*---------------------------------------------------------------------------
*
|
| ︙ | ︙ |
Changes to generic/tclClock.c.
| ︙ | ︙ | |||
308 309 310 311 312 313 314 | * leaves an error message in the interpreter result. * *---------------------------------------------------------------------- */ static int ClockConvertlocaltoutcObjCmd( | | | 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 |
* leaves an error message in the interpreter result.
*
*----------------------------------------------------------------------
*/
static int
ClockConvertlocaltoutcObjCmd(
void *clientData, /* Client data */
Tcl_Interp *interp, /* Tcl interpreter */
int objc, /* Parameter count */
Tcl_Obj *const *objv) /* Parameter vector */
{
ClockClientData *data = (ClockClientData *)clientData;
Tcl_Obj *const *lit = data->literals;
Tcl_Obj *secondsObj;
|
| ︙ | ︙ | |||
400 401 402 403 404 405 406 | * julianDay - Julian Day Number in the local time zone * *---------------------------------------------------------------------- */ int ClockGetdatefieldsObjCmd( | | | 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 |
* julianDay - Julian Day Number in the local time zone
*
*----------------------------------------------------------------------
*/
int
ClockGetdatefieldsObjCmd(
void *clientData, /* Opaque pointer to literal pool, etc. */
Tcl_Interp *interp, /* Tcl interpreter */
int objc, /* Parameter count */
Tcl_Obj *const *objv) /* Parameter vector */
{
TclDateFields fields;
Tcl_Obj *dict;
ClockClientData *data = (ClockClientData *)clientData;
|
| ︙ | ︙ | |||
556 557 558 559 560 561 562 |
return TCL_ERROR;
}
return TclGetIntFromObj(interp, value, storePtr);
}
static int
ClockGetjuliandayfromerayearmonthdayObjCmd(
| | | 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 |
return TCL_ERROR;
}
return TclGetIntFromObj(interp, value, storePtr);
}
static int
ClockGetjuliandayfromerayearmonthdayObjCmd(
void *clientData, /* Opaque pointer to literal pool, etc. */
Tcl_Interp *interp, /* Tcl interpreter */
int objc, /* Parameter count */
Tcl_Obj *const *objv) /* Parameter vector */
{
TclDateFields fields;
Tcl_Obj *dict;
ClockClientData *data = (ClockClientData *)clientData;
|
| ︙ | ︙ | |||
640 641 642 643 644 645 646 | * result being an error message. * *---------------------------------------------------------------------- */ static int ClockGetjuliandayfromerayearweekdayObjCmd( | | | 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 |
* result being an error message.
*
*----------------------------------------------------------------------
*/
static int
ClockGetjuliandayfromerayearweekdayObjCmd(
void *clientData, /* Opaque pointer to literal pool, etc. */
Tcl_Interp *interp, /* Tcl interpreter */
int objc, /* Parameter count */
Tcl_Obj *const *objv) /* Parameter vector */
{
TclDateFields fields;
Tcl_Obj *dict;
ClockClientData *data = (ClockClientData *)clientData;
|
| ︙ | ︙ | |||
726 727 728 729 730 731 732 |
static int
ConvertLocalToUTC(
Tcl_Interp *interp, /* Tcl interpreter */
TclDateFields *fields, /* Fields of the time */
Tcl_Obj *tzdata, /* Time zone data */
int changeover) /* Julian Day of the Gregorian transition */
{
| | | 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 |
static int
ConvertLocalToUTC(
Tcl_Interp *interp, /* Tcl interpreter */
TclDateFields *fields, /* Fields of the time */
Tcl_Obj *tzdata, /* Time zone data */
int changeover) /* Julian Day of the Gregorian transition */
{
Tcl_Size rowc; /* Number of rows in tzdata */
Tcl_Obj **rowv; /* Pointers to the rows */
/*
* Unpack the tz data.
*/
if (TclListObjGetElementsM(interp, tzdata, &rowc, &rowv) != TCL_OK) {
|
| ︙ | ︙ | |||
771 772 773 774 775 776 777 |
*----------------------------------------------------------------------
*/
static int
ConvertLocalToUTCUsingTable(
Tcl_Interp *interp, /* Tcl interpreter */
TclDateFields *fields, /* Time to convert, with 'seconds' filled in */
| | | 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 |
*----------------------------------------------------------------------
*/
static int
ConvertLocalToUTCUsingTable(
Tcl_Interp *interp, /* Tcl interpreter */
TclDateFields *fields, /* Time to convert, with 'seconds' filled in */
Tcl_Size rowc, /* Number of points at which time changes */
Tcl_Obj *const rowv[]) /* Points at which time changes */
{
Tcl_Obj *row;
Tcl_Size cellc;
Tcl_Obj **cellv;
int have[8];
int nHave = 0;
|
| ︙ | ︙ | |||
929 930 931 932 933 934 935 |
static int
ConvertUTCToLocal(
Tcl_Interp *interp, /* Tcl interpreter */
TclDateFields *fields, /* Fields of the time */
Tcl_Obj *tzdata, /* Time zone data */
int changeover) /* Julian Day of the Gregorian transition */
{
| | | 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 |
static int
ConvertUTCToLocal(
Tcl_Interp *interp, /* Tcl interpreter */
TclDateFields *fields, /* Fields of the time */
Tcl_Obj *tzdata, /* Time zone data */
int changeover) /* Julian Day of the Gregorian transition */
{
Tcl_Size rowc; /* Number of rows in tzdata */
Tcl_Obj **rowv; /* Pointers to the rows */
/*
* Unpack the tz data.
*/
if (TclListObjGetElementsM(interp, tzdata, &rowc, &rowv) != TCL_OK) {
|
| ︙ | ︙ | |||
974 975 976 977 978 979 980 |
*----------------------------------------------------------------------
*/
static int
ConvertUTCToLocalUsingTable(
Tcl_Interp *interp, /* Tcl interpreter */
TclDateFields *fields, /* Fields of the date */
| | | | 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 |
*----------------------------------------------------------------------
*/
static int
ConvertUTCToLocalUsingTable(
Tcl_Interp *interp, /* Tcl interpreter */
TclDateFields *fields, /* Fields of the date */
Tcl_Size rowc, /* Number of rows in the conversion table
* (>= 1) */
Tcl_Obj *const rowv[]) /* Rows of the conversion table */
{
Tcl_Obj *row; /* Row containing the current information */
Tcl_Size cellc; /* Count of cells in the row (must be 4) */
Tcl_Obj **cellv; /* Pointers to the cells */
/*
* Look up the nearest transition time.
*/
row = LookupLastTransition(interp, fields->seconds, rowc, rowv);
|
| ︙ | ︙ | |||
1114 1115 1116 1117 1118 1119 1120 |
*----------------------------------------------------------------------
*/
static Tcl_Obj *
LookupLastTransition(
Tcl_Interp *interp, /* Interpreter for error messages */
Tcl_WideInt tick, /* Time from the epoch */
| | | 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 |
*----------------------------------------------------------------------
*/
static Tcl_Obj *
LookupLastTransition(
Tcl_Interp *interp, /* Interpreter for error messages */
Tcl_WideInt tick, /* Time from the epoch */
Tcl_Size rowc, /* Number of rows of tzdata */
Tcl_Obj *const *rowv) /* Rows in tzdata */
{
Tcl_Size l;
Tcl_Size u;
Tcl_Obj *compObj;
Tcl_WideInt compVal;
|
| ︙ | ︙ | |||
1869 1870 1871 1872 1873 1874 1875 | * to speed that particular code up. * *----------------------------------------------------------------------------- */ static int ClockParseformatargsObjCmd( | | | 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 |
* to speed that particular code up.
*
*-----------------------------------------------------------------------------
*/
static int
ClockParseformatargsObjCmd(
void *clientData, /* Client data containing literal pool */
Tcl_Interp *interp, /* Tcl interpreter */
int objc, /* Parameter count */
Tcl_Obj *const objv[]) /* Parameter vector */
{
ClockClientData *dataPtr = (ClockClientData *)clientData;
Tcl_Obj **litPtr = dataPtr->literals;
Tcl_Obj *results[3]; /* Format, locale and timezone */
|
| ︙ | ︙ | |||
2090 2091 2092 2093 2094 2095 2096 | * None. * *---------------------------------------------------------------------- */ static void ClockDeleteCmdProc( | | | 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 |
* None.
*
*----------------------------------------------------------------------
*/
static void
ClockDeleteCmdProc(
void *clientData) /* Opaque pointer to the client data */
{
ClockClientData *data = (ClockClientData *)clientData;
int i;
if (data->refCount-- <= 1) {
for (i = 0; i < LIT__END; ++i) {
Tcl_DecrRefCount(data->literals[i]);
|
| ︙ | ︙ |
Changes to generic/tclCmdAH.c.
| ︙ | ︙ | |||
26 27 28 29 30 31 32 |
struct ForeachState {
Tcl_Obj *bodyPtr; /* The script body of the command. */
Tcl_Size bodyIdx; /* The argument index of the body. */
Tcl_Size j, maxj; /* Number of loop iterations. */
Tcl_Size numLists; /* Count of value lists. */
Tcl_Size *index; /* Array of value list indices. */
| | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
struct ForeachState {
Tcl_Obj *bodyPtr; /* The script body of the command. */
Tcl_Size bodyIdx; /* The argument index of the body. */
Tcl_Size j, maxj; /* Number of loop iterations. */
Tcl_Size numLists; /* Count of value lists. */
Tcl_Size *index; /* Array of value list indices. */
Tcl_Size *varcList; /* # loop variables per list. */
Tcl_Obj ***varvList; /* Array of var name lists. */
Tcl_Obj **vCopyList; /* Copies of var name list arguments. */
Tcl_Size *argcList; /* Array of value list sizes. */
Tcl_Obj ***argvList; /* Array of value lists. */
Tcl_Obj **aCopyList; /* Copies of value list arguments. */
Tcl_Obj *resultList; /* List of result values from the loop body,
* or NULL if we're not collecting them
|
| ︙ | ︙ | |||
526 527 528 529 530 531 532 |
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
Tcl_Obj *data; /* Byte array to convert */
Tcl_DString ds; /* Buffer to hold the string */
Tcl_Encoding encoding; /* Encoding to use */
| | | 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 |
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
Tcl_Obj *data; /* Byte array to convert */
Tcl_DString ds; /* Buffer to hold the string */
Tcl_Encoding encoding; /* Encoding to use */
Tcl_Size length = 0; /* Length of the byte array being converted */
const char *bytesPtr; /* Pointer to the first byte of the array */
int flags;
int result;
Tcl_Obj *failVarObj;
Tcl_Size errorLocation;
if (EncodingConvertParseOptions(
|
| ︙ | ︙ | |||
626 627 628 629 630 631 632 |
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
Tcl_Obj *data; /* String to convert */
Tcl_DString ds; /* Buffer to hold the byte array */
Tcl_Encoding encoding; /* Encoding to use */
| | | 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 |
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
Tcl_Obj *data; /* String to convert */
Tcl_DString ds; /* Buffer to hold the byte array */
Tcl_Encoding encoding; /* Encoding to use */
Tcl_Size length; /* Length of the string being converted */
const char *stringPtr; /* Pointer to the first byte of the string */
int result;
int flags;
Tcl_Obj *failVarObj;
Tcl_Size errorLocation;
if (EncodingConvertParseOptions(
|
| ︙ | ︙ |
Changes to generic/tclCmdIL.c.
| ︙ | ︙ | |||
2469 2470 2471 2472 2473 2474 2475 |
*----------------------------------------------------------------------
*/
int
Tcl_LinsertObjCmd(
TCL_UNUSED(void *),
Tcl_Interp *interp, /* Current interpreter. */
| | | 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 |
*----------------------------------------------------------------------
*/
int
Tcl_LinsertObjCmd(
TCL_UNUSED(void *),
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
Tcl_Obj *listPtr;
Tcl_Size len, index;
int copied = 0, result;
if (objc < 3) {
|
| ︙ | ︙ | |||
2599 2600 2601 2602 2603 2604 2605 |
*/
int
Tcl_LlengthObjCmd(
TCL_UNUSED(void *),
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
| | < | 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 |
*/
int
Tcl_LlengthObjCmd(
TCL_UNUSED(void *),
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
Tcl_Size listLen;
int result;
Tcl_Obj *objPtr;
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, "list");
|
| ︙ | ︙ | |||
2648 2649 2650 2651 2652 2653 2654 |
*/
int
Tcl_LpopObjCmd(
TCL_UNUSED(void *),
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
| | < | 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 |
*/
int
Tcl_LpopObjCmd(
TCL_UNUSED(void *),
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
Tcl_Size listLen;
int copied = 0, result;
Tcl_Obj *elemPtr, *stored;
Tcl_Obj *listPtr;
if (objc < 2) {
|
| ︙ | ︙ | |||
2768 2769 2770 2771 2772 2773 2774 |
*/
int
Tcl_LrangeObjCmd(
TCL_UNUSED(void *),
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
| | < | 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 |
*/
int
Tcl_LrangeObjCmd(
TCL_UNUSED(void *),
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
int result;
Tcl_Size listLen, first, last;
if (objc != 4) {
Tcl_WrongNumArgs(interp, 1, objv, "list first last");
return TCL_ERROR;
}
|
| ︙ | ︙ | |||
2980 2981 2982 2983 2984 2985 2986 |
*----------------------------------------------------------------------
*/
int
Tcl_LrepeatObjCmd(
TCL_UNUSED(void *),
Tcl_Interp *interp, /* Current interpreter. */
| | | < | 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 |
*----------------------------------------------------------------------
*/
int
Tcl_LrepeatObjCmd(
TCL_UNUSED(void *),
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* The argument objects. */
{
Tcl_WideInt elementCount, i;
Tcl_Size totalElems;
Tcl_Obj *listPtr, **dataArray = NULL;
/*
* Check arguments for legality:
|
| ︙ | ︙ |
Changes to generic/tclCmdMZ.c.
| ︙ | ︙ | |||
26 27 28 29 30 31 32 | Tcl_Obj *oldOptions, Tcl_Obj *errorInfo); static Tcl_NRPostProc SwitchPostProc; static Tcl_NRPostProc TryPostBody; static Tcl_NRPostProc TryPostFinal; static Tcl_NRPostProc TryPostHandler; static int UniCharIsAscii(int character); static int UniCharIsHexDigit(int character); | | | | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | Tcl_Obj *oldOptions, Tcl_Obj *errorInfo); static Tcl_NRPostProc SwitchPostProc; static Tcl_NRPostProc TryPostBody; static Tcl_NRPostProc TryPostFinal; static Tcl_NRPostProc TryPostHandler; static int UniCharIsAscii(int character); static int UniCharIsHexDigit(int character); static int StringCmpOpts(Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], int *nocase, Tcl_Size *reqlength); /* * Default set of characters to trim in [string trim] and friends. This is a * UTF-8 literal string containing all Unicode space characters [TIP #413] */ const char tclDefaultTrimSet[] = |
| ︙ | ︙ | |||
2765 2766 2767 2768 2769 2770 2771 |
goto str_cmp_args;
}
i++;
if (TclGetWideIntFromObj(interp, objv[i], &wreqlength) != TCL_OK) {
return TCL_ERROR;
}
if ((Tcl_WideUInt)wreqlength > TCL_SIZE_MAX) {
| | | | 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 |
goto str_cmp_args;
}
i++;
if (TclGetWideIntFromObj(interp, objv[i], &wreqlength) != TCL_OK) {
return TCL_ERROR;
}
if ((Tcl_WideUInt)wreqlength > TCL_SIZE_MAX) {
*reqlength = -1;
} else {
*reqlength = wreqlength;
}
} else {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"bad option \"%s\": must be -nocase or -length",
string));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "option",
string, (void *)NULL);
|
| ︙ | ︙ |
Changes to generic/tclCompCmds.c.
| ︙ | ︙ | |||
375 376 377 378 379 380 381 | * a non-local variable: upvar from a local one! This consumes the * variable name that was left at stacktop. */ localIndex = TclFindCompiledLocal(varTokenPtr->start, varTokenPtr->size, 1, envPtr); PushStringLiteral(envPtr, "0"); | | | | | 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 |
* a non-local variable: upvar from a local one! This consumes the
* variable name that was left at stacktop.
*/
localIndex = TclFindCompiledLocal(varTokenPtr->start,
varTokenPtr->size, 1, envPtr);
PushStringLiteral(envPtr, "0");
TclEmitInstInt4(INST_REVERSE, 2, envPtr);
TclEmitInstInt4(INST_UPVAR, localIndex, envPtr);
TclEmitOpcode(INST_POP, envPtr);
}
/*
* Prepare for the internal foreach.
*/
keyVar = AnonymousLocal(envPtr);
|
| ︙ | ︙ | |||
2965 2966 2967 2968 2969 2970 2971 | * the new ForeachInfo record. * *---------------------------------------------------------------------- */ static void * DupForeachInfo( | | | 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 |
* the new ForeachInfo record.
*
*----------------------------------------------------------------------
*/
static void *
DupForeachInfo(
void *clientData) /* The foreach command's compilation auxiliary
* data to duplicate. */
{
ForeachInfo *srcPtr = (ForeachInfo *)clientData;
ForeachInfo *dupPtr;
ForeachVarList *srcListPtr, *dupListPtr;
int numVars, i, j, numLists = srcPtr->numLists;
|
| ︙ | ︙ | |||
3014 3015 3016 3017 3018 3019 3020 | * ForeachInfo structure. * *---------------------------------------------------------------------- */ static void FreeForeachInfo( | | | 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 |
* ForeachInfo structure.
*
*----------------------------------------------------------------------
*/
static void
FreeForeachInfo(
void *clientData) /* The foreach command's compilation auxiliary
* data to free. */
{
ForeachInfo *infoPtr = (ForeachInfo *)clientData;
ForeachVarList *listPtr;
size_t i, numLists = infoPtr->numLists;
for (i = 0; i < numLists; i++) {
|
| ︙ | ︙ | |||
3417 3418 3419 3420 3421 3422 3423 | * * TclLocalScalarFromToken -- * * Get the index into the table of compiled locals that corresponds * to a local scalar variable name. * * Results: | | | | | | 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 | * * TclLocalScalarFromToken -- * * Get the index into the table of compiled locals that corresponds * to a local scalar variable name. * * Results: * Returns the non-negative integer index value into the table of * compiled locals corresponding to a local scalar variable name. * If the arguments passed in do not identify a local scalar variable * then return TCL_INDEX_NONE. * * Side effects: * May add an entry into the table of compiled locals. * *---------------------------------------------------------------------- */ |
| ︙ | ︙ |
Changes to generic/tclCompCmdsSZ.c.
| ︙ | ︙ | |||
38 39 40 41 42 43 44 | CompileEnv *envPtr); static int CompileUnaryOpCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, int instruction, CompileEnv *envPtr); static void IssueSwitchChainedTests(Tcl_Interp *interp, CompileEnv *envPtr, int mode, int noCase, Tcl_Size numWords, Tcl_Token **bodyToken, | | | | | 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | CompileEnv *envPtr); static int CompileUnaryOpCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, int instruction, CompileEnv *envPtr); static void IssueSwitchChainedTests(Tcl_Interp *interp, CompileEnv *envPtr, int mode, int noCase, Tcl_Size numWords, Tcl_Token **bodyToken, Tcl_Size *bodyLines, Tcl_Size **bodyNext); static void IssueSwitchJumpTable(Tcl_Interp *interp, CompileEnv *envPtr, int numWords, Tcl_Token **bodyToken, Tcl_Size *bodyLines, Tcl_Size **bodyContLines); static int IssueTryClausesInstructions(Tcl_Interp *interp, CompileEnv *envPtr, Tcl_Token *bodyToken, int numHandlers, int *matchCodes, Tcl_Obj **matchClauses, int *resultVarIndices, int *optionVarIndices, Tcl_Token **handlerTokens); static int IssueTryClausesFinallyInstructions(Tcl_Interp *interp, CompileEnv *envPtr, Tcl_Token *bodyToken, |
| ︙ | ︙ | |||
2116 2117 2118 2119 2120 2121 2122 |
CompileEnv *envPtr, /* Holds resulting instructions. */
int mode, /* Exact, Glob or Regexp */
int noCase, /* Case-insensitivity flag. */
Tcl_Size numBodyTokens, /* Number of tokens describing things the
* switch can match against and bodies to
* execute when the match succeeds. */
Tcl_Token **bodyToken, /* Array of pointers to pattern list items. */
| | | 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 |
CompileEnv *envPtr, /* Holds resulting instructions. */
int mode, /* Exact, Glob or Regexp */
int noCase, /* Case-insensitivity flag. */
Tcl_Size numBodyTokens, /* Number of tokens describing things the
* switch can match against and bodies to
* execute when the match succeeds. */
Tcl_Token **bodyToken, /* Array of pointers to pattern list items. */
Tcl_Size *bodyLines, /* Array of line numbers for body list
* items. */
Tcl_Size **bodyContLines) /* Array of continuation line info. */
{
enum {Switch_Exact, Switch_Glob, Switch_Regexp};
int foundDefault; /* Flag to indicate whether a "default" clause
* is present. */
JumpFixup *fixupArray; /* Array of forward-jump fixup records. */
|
| ︙ | ︙ | |||
2364 2365 2366 2367 2368 2369 2370 |
IssueSwitchJumpTable(
Tcl_Interp *interp, /* Context for compiling script bodies. */
CompileEnv *envPtr, /* Holds resulting instructions. */
int numBodyTokens, /* Number of tokens describing things the
* switch can match against and bodies to
* execute when the match succeeds. */
Tcl_Token **bodyToken, /* Array of pointers to pattern list items. */
| | | 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 |
IssueSwitchJumpTable(
Tcl_Interp *interp, /* Context for compiling script bodies. */
CompileEnv *envPtr, /* Holds resulting instructions. */
int numBodyTokens, /* Number of tokens describing things the
* switch can match against and bodies to
* execute when the match succeeds. */
Tcl_Token **bodyToken, /* Array of pointers to pattern list items. */
Tcl_Size *bodyLines, /* Array of line numbers for body list
* items. */
Tcl_Size **bodyContLines) /* Array of continuation line info. */
{
JumptableInfo *jtPtr;
int infoIndex, isNew, *finalFixups, numRealBodies = 0, jumpLocation;
int mustGenerate, foundDefault, jumpToDefault, i;
Tcl_DString buffer;
|
| ︙ | ︙ |
Changes to generic/tclCompile.c.
| ︙ | ︙ | |||
683 684 685 686 687 688 689 | static ByteCode * CompileSubstObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int flags); static void DupByteCodeInternalRep(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr); static unsigned char * EncodeCmdLocMap(CompileEnv *envPtr, ByteCode *codePtr, unsigned char *startPtr); static void EnterCmdExtentData(CompileEnv *envPtr, | | > | > | 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 | static ByteCode * CompileSubstObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int flags); static void DupByteCodeInternalRep(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr); static unsigned char * EncodeCmdLocMap(CompileEnv *envPtr, ByteCode *codePtr, unsigned char *startPtr); static void EnterCmdExtentData(CompileEnv *envPtr, Tcl_Size cmdNumber, Tcl_Size numSrcBytes, Tcl_Size numCodeBytes); static void EnterCmdStartData(CompileEnv *envPtr, Tcl_Size cmdNumber, Tcl_Size srcOffset, Tcl_Size codeOffset); static void FreeByteCodeInternalRep(Tcl_Obj *objPtr); static void FreeSubstCodeInternalRep(Tcl_Obj *objPtr); static int GetCmdLocEncodingSize(CompileEnv *envPtr); static int IsCompactibleCompileEnv(CompileEnv *envPtr); static void PreventCycle(Tcl_Obj *objPtr, CompileEnv *envPtr); #ifdef TCL_COMPILE_STATS static void RecordByteCodeStats(ByteCode *codePtr); |
| ︙ | ︙ | |||
775 776 777 778 779 780 781 |
int
TclSetByteCodeFromAny(
Tcl_Interp *interp, /* The interpreter for which the code is being
* compiled. Must not be NULL. */
Tcl_Obj *objPtr, /* The object to make a ByteCode object. */
CompileHookProc *hookProc, /* Procedure to invoke after compilation. */
| | | 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 |
int
TclSetByteCodeFromAny(
Tcl_Interp *interp, /* The interpreter for which the code is being
* compiled. Must not be NULL. */
Tcl_Obj *objPtr, /* The object to make a ByteCode object. */
CompileHookProc *hookProc, /* Procedure to invoke after compilation. */
void *clientData) /* Hook procedure private data. */
{
Interp *iPtr = (Interp *) interp;
CompileEnv compEnv; /* Compilation environment structure allocated
* in frame. */
Tcl_Size length;
int result = TCL_OK;
const char *stringPtr;
|
| ︙ | ︙ | |||
3030 3031 3032 3033 3034 3035 3036 | * variable is unknown, or if the name is NULL. * *---------------------------------------------------------------------- */ Tcl_Size TclFindCompiledLocal( | | | 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 |
* variable is unknown, or if the name is NULL.
*
*----------------------------------------------------------------------
*/
Tcl_Size
TclFindCompiledLocal(
const char *name, /* Points to first character of the name of a
* scalar or array variable. If NULL, a
* temporary var should be created. */
Tcl_Size nameBytes, /* Number of bytes in the name. */
int create, /* If 1, allocate a local frame entry for the
* variable if it is new. */
CompileEnv *envPtr) /* Points to the current compile environment*/
{
|
| ︙ | ︙ | |||
3209 3210 3211 3212 3213 3214 3215 |
EnterCmdStartData(
CompileEnv *envPtr, /* Points to the compilation environment
* structure in which to enter command
* location information. */
Tcl_Size cmdIndex, /* Index of the command whose start data is
* being set. */
Tcl_Size srcOffset, /* Offset of first char of the command. */
| | | 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 |
EnterCmdStartData(
CompileEnv *envPtr, /* Points to the compilation environment
* structure in which to enter command
* location information. */
Tcl_Size cmdIndex, /* Index of the command whose start data is
* being set. */
Tcl_Size srcOffset, /* Offset of first char of the command. */
Tcl_Size codeOffset) /* Offset of first byte of command code. */
{
CmdLocation *cmdLocPtr;
if (cmdIndex < 0 || cmdIndex >= envPtr->numCommands) {
Tcl_Panic("EnterCmdStartData: bad command index %" TCL_Z_MODIFIER "u", cmdIndex);
}
|
| ︙ | ︙ | |||
3287 3288 3289 3290 3291 3292 3293 |
static void
EnterCmdExtentData(
CompileEnv *envPtr, /* Points to the compilation environment
* structure in which to enter command
* location information. */
Tcl_Size cmdIndex, /* Index of the command whose source and code
* length data is being set. */
| | | | 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 |
static void
EnterCmdExtentData(
CompileEnv *envPtr, /* Points to the compilation environment
* structure in which to enter command
* location information. */
Tcl_Size cmdIndex, /* Index of the command whose source and code
* length data is being set. */
Tcl_Size numSrcBytes, /* Number of command source chars. */
Tcl_Size numCodeBytes) /* Offset of last byte of command code. */
{
CmdLocation *cmdLocPtr;
if (cmdIndex < 0 || cmdIndex >= envPtr->numCommands) {
Tcl_Panic("EnterCmdExtentData: bad command index %" TCL_Z_MODIFIER "u", cmdIndex);
}
|
| ︙ | ︙ | |||
3411 3412 3413 3414 3415 3416 3417 |
*
*----------------------------------------------------------------------
*/
Tcl_Size
TclCreateExceptRange(
ExceptionRangeType type, /* The kind of ExceptionRange desired. */
| | | 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 |
*
*----------------------------------------------------------------------
*/
Tcl_Size
TclCreateExceptRange(
ExceptionRangeType type, /* The kind of ExceptionRange desired. */
CompileEnv *envPtr) /* Points to CompileEnv for which to create a
* new ExceptionRange structure. */
{
ExceptionRange *rangePtr;
ExceptionAux *auxPtr;
Tcl_Size index = envPtr->exceptArrayNext;
if (index >= envPtr->exceptArrayEnd) {
|
| ︙ | ︙ | |||
3771 3772 3773 3774 3775 3776 3777 | * If there is not enough room in the CompileEnv's AuxData array, its size * is doubled. *---------------------------------------------------------------------- */ Tcl_Size TclCreateAuxData( | | | | 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 |
* If there is not enough room in the CompileEnv's AuxData array, its size
* is doubled.
*----------------------------------------------------------------------
*/
Tcl_Size
TclCreateAuxData(
void *clientData, /* The compilation auxiliary data to store in
* the new aux data record. */
const AuxDataType *typePtr, /* Pointer to the type to attach to this
* AuxData */
CompileEnv *envPtr) /* Points to the CompileEnv for which a new
* aux data structure is to be allocated. */
{
Tcl_Size index; /* Index for the new AuxData structure. */
AuxData *auxDataPtr;
/* Points to the new AuxData structure */
index = envPtr->auxDataArrayNext;
|
| ︙ | ︙ |
Changes to generic/tclCompile.h.
| ︙ | ︙ | |||
30 31 32 33 34 35 36 | * what level of tracing is desired: * 0: no compilation tracing * 1: summarize compilation of top level cmds and proc bodies * 2: display all instructions of each ByteCode compiled * This variable is linked to the Tcl variable "tcl_traceCompile". */ | | | | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | * what level of tracing is desired: * 0: no compilation tracing * 1: summarize compilation of top level cmds and proc bodies * 2: display all instructions of each ByteCode compiled * This variable is linked to the Tcl variable "tcl_traceCompile". */ MODULE_SCOPE int tclTraceCompile; /* * Variable that controls whether execution tracing is enabled and, if so, * what level of tracing is desired: * 0: no execution tracing * 1: trace invocations of Tcl procs only * 2: trace invocations of all (not compiled away) commands * 3: display each instruction executed * This variable is linked to the Tcl variable "tcl_traceExec". */ MODULE_SCOPE int tclTraceExec; #endif /* * The type of lambda expressions. Note that every lambda will *always* have a * string representation. */ |
| ︙ | ︙ | |||
85 86 87 88 89 90 91 |
CATCH_EXCEPTION_RANGE /* Exception's range is controlled by a catch
* command. Errors in the range cause a jump
* to a catch PC offset. */
} ExceptionRangeType;
typedef struct {
ExceptionRangeType type; /* The kind of ExceptionRange. */
| | | | | | | | | | | | > | | | | | | | | | 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 |
CATCH_EXCEPTION_RANGE /* Exception's range is controlled by a catch
* command. Errors in the range cause a jump
* to a catch PC offset. */
} ExceptionRangeType;
typedef struct {
ExceptionRangeType type; /* The kind of ExceptionRange. */
Tcl_Size nestingLevel; /* Static depth of the exception range. Used
* to find the most deeply-nested range
* surrounding a PC at runtime. */
Tcl_Size codeOffset; /* Offset of the first instruction byte of the
* code range. */
Tcl_Size numCodeBytes; /* Number of bytes in the code range. */
Tcl_Size breakOffset; /* If LOOP_EXCEPTION_RANGE, the target PC
* offset for a break command in the range. */
Tcl_Size continueOffset; /* If LOOP_EXCEPTION_RANGE and not TCL_INDEX_NONE, the
* target PC offset for a continue command in
* the code range. Otherwise, ignore this
* range when processing a continue
* command. */
Tcl_Size catchOffset; /* If a CATCH_EXCEPTION_RANGE, the target PC
* offset for any "exception" in range. */
} ExceptionRange;
/*
* Auxiliary data used when issuing (currently just loop) exception ranges,
* but which is not required during execution.
*/
typedef struct ExceptionAux {
int supportsContinue; /* Whether this exception range will have a
* continueOffset created for it; if it is a
* loop exception range that *doesn't* have
* one (see [for] next-clause) then we must
* not pick up the range when scanning for a
* target to continue to. */
Tcl_Size stackDepth; /* The stack depth at the point where the
* exception range was created. This is used
* to calculate the number of POPs required to
* restore the stack to its prior state. */
Tcl_Size expandTarget; /* The number of expansions expected on the
* auxData stack at the time the loop starts;
* we can't currently discard them except by
* doing INST_INVOKE_EXPANDED; this is a known
* problem. */
Tcl_Size expandTargetDepth; /* The stack depth expected at the outermost
* expansion within the loop. Not meaningful
* if there are no open expansions between the
* looping level and the point of jump
* issue. */
Tcl_Size numBreakTargets; /* The number of [break]s that want to be
* targeted to the place where this loop
* exception will be bound to. */
TCL_HASH_TYPE *breakTargets;/* The offsets of the INST_JUMP4 instructions
* issued by the [break]s that we must
* update. Note that resizing a jump (via
* TclFixupForwardJump) can cause the contents
* of this array to be updated. When
* numBreakTargets==0, this is NULL. */
Tcl_Size allocBreakTargets; /* The size of the breakTargets array. */
Tcl_Size numContinueTargets;/* The number of [continue]s that want to be
* targeted to the place where this loop
* exception will be bound to. */
TCL_HASH_TYPE *continueTargets; /* The offsets of the INST_JUMP4 instructions
* issued by the [continue]s that we must
* update. Note that resizing a jump (via
* TclFixupForwardJump) can cause the contents
* of this array to be updated. When
* numContinueTargets==0, this is NULL. */
Tcl_Size allocContinueTargets;
/* The size of the continueTargets array. */
} ExceptionAux;
/*
* Structure used to map between instruction pc and source locations. It
* defines for each compiled Tcl command its code's starting offset and its
* source's starting offset and length. Note that the code offset increases
* monotonically: that is, the table is sorted in code offset order. The
* source offset is not monotonic.
*/
typedef struct {
Tcl_Size codeOffset; /* Offset of first byte of command code. */
Tcl_Size numCodeBytes; /* Number of bytes for command's code. */
Tcl_Size srcOffset; /* Offset of first char of the command. */
Tcl_Size numSrcBytes; /* Number of command source chars. */
} CmdLocation;
/*
* TIP #280
* Structure to record additional location information for byte code. This
* information is internal and not saved. i.e. tbcload'ed code will not have
* this information. It records the lines for all words of all commands found
* in the byte code. The association with a ByteCode structure BC is done
* through the 'lineBCPtr' HashTable in Interp, keyed by the address of BC.
* Also recorded is information coming from the context, i.e. type of the
* frame and associated information, like the path of a sourced file.
*/
typedef struct {
Tcl_Size srcOffset; /* Command location to find the entry. */
Tcl_Size nline; /* Number of words in the command */
Tcl_Size *line; /* Line information for all words in the
* command. */
Tcl_Size **next; /* Transient information used by the compiler
* for tracking of hidden continuation
* lines. */
} ECL;
typedef struct {
int type; /* Context type. */
Tcl_Size start; /* Starting line for compiled script. Needed
* for the extended recompile check in
* tclCompileObj. */
Tcl_Obj *path; /* Path of the sourced file the command is
* in. */
ECL *loc; /* Command word locations (lines). */
Tcl_Size nloc; /* Number of allocated entries in 'loc'. */
Tcl_Size nuloc; /* Number of used entries in 'loc'. */
} ExtCmdLoc;
/*
* CompileProcs need the ability to record information during compilation that
* can be used by bytecode instructions during execution. The AuxData
* structure provides this "auxiliary data" mechanism. An arbitrary number of
* these structures can be stored in the ByteCode record (during compilation
|
| ︙ | ︙ | |||
262 263 264 265 266 267 268 |
* during compilation by CompileProcs and used by instructions during
* execution.
*/
typedef struct AuxData {
const AuxDataType *type; /* Pointer to the AuxData type associated with
* this ClientData. */
| | | 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 |
* during compilation by CompileProcs and used by instructions during
* execution.
*/
typedef struct AuxData {
const AuxDataType *type; /* Pointer to the AuxData type associated with
* this ClientData. */
void *clientData; /* The compilation data itself. */
} AuxData;
/*
* Structure defining the compilation environment. After compilation, fields
* describing bytecode instructions are copied out into the more compact
* ByteCode structure defined below.
*/
|
| ︙ | ︙ | |||
286 287 288 289 290 291 292 |
* compiled. Commands and their compile procs
* are specific to an interpreter so the code
* emitted will depend on the interpreter. */
const char *source; /* The source string being compiled by
* SetByteCodeFromAny. This pointer is not
* owned by the CompileEnv and must not be
* freed or changed by it. */
| | | | | | | | | | | 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 |
* compiled. Commands and their compile procs
* are specific to an interpreter so the code
* emitted will depend on the interpreter. */
const char *source; /* The source string being compiled by
* SetByteCodeFromAny. This pointer is not
* owned by the CompileEnv and must not be
* freed or changed by it. */
Tcl_Size numSrcBytes; /* Number of bytes in source. */
Proc *procPtr; /* If a procedure is being compiled, a pointer
* to its Proc structure; otherwise NULL. Used
* to compile local variables. Set from
* information provided by ObjInterpProc in
* tclProc.c. */
Tcl_Size numCommands; /* Number of commands compiled. */
Tcl_Size exceptDepth; /* Current exception range nesting level; TCL_INDEX_NONE
* if not in any range currently. */
Tcl_Size maxExceptDepth; /* Max nesting level of exception ranges; TCL_INDEX_NONE
* if no ranges have been compiled. */
Tcl_Size maxStackDepth; /* Maximum number of stack elements needed to
* execute the code. Set by compilation
* procedures before returning. */
Tcl_Size currStackDepth; /* Current stack depth. */
LiteralTable localLitTable; /* Contains LiteralEntry's describing all Tcl
* objects referenced by this compiled code.
* Indexed by the string representations of
* the literals. Used to avoid creating
* duplicate objects. */
unsigned char *codeStart; /* Points to the first byte of the code. */
unsigned char *codeNext; /* Points to next code array byte to use. */
unsigned char *codeEnd; /* Points just after the last allocated code
* array byte. */
int mallocedCodeArray; /* Set 1 if code array was expanded and
* codeStart points into the heap.*/
#if TCL_MAJOR_VERSION > 8
int mallocedExceptArray; /* 1 if ExceptionRange array was expanded and
* exceptArrayPtr points in heap, else 0. */
#endif
LiteralEntry *literalArrayPtr;
/* Points to start of LiteralEntry array. */
Tcl_Size literalArrayNext; /* Index of next free object array entry. */
Tcl_Size literalArrayEnd; /* Index just after last obj array entry. */
int mallocedLiteralArray; /* 1 if object array was expanded and objArray
* points into the heap, else 0. */
ExceptionRange *exceptArrayPtr;
/* Points to start of the ExceptionRange
* array. */
Tcl_Size exceptArrayNext; /* Next free ExceptionRange array index.
* exceptArrayNext is the number of ranges and
* (exceptArrayNext-1) is the index of the
* current range's array entry. */
Tcl_Size exceptArrayEnd; /* Index after the last ExceptionRange array
* entry. */
#if TCL_MAJOR_VERSION < 9
int mallocedExceptArray;
#endif
ExceptionAux *exceptAuxArrayPtr;
/* Array of information used to restore the
* state when processing BREAK/CONTINUE
|
| ︙ | ︙ | |||
375 376 377 378 379 380 381 |
CmdLocation staticCmdMapSpace[COMPILEENV_INIT_CMD_MAP_SIZE];
/* Initial storage for cmd location map. */
AuxData staticAuxDataArraySpace[COMPILEENV_INIT_AUX_DATA_SIZE];
/* Initial storage for aux data array. */
/* TIP #280 */
ExtCmdLoc *extCmdMapPtr; /* Extended command location information for
* 'info frame'. */
| | | | | 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 |
CmdLocation staticCmdMapSpace[COMPILEENV_INIT_CMD_MAP_SIZE];
/* Initial storage for cmd location map. */
AuxData staticAuxDataArraySpace[COMPILEENV_INIT_AUX_DATA_SIZE];
/* Initial storage for aux data array. */
/* TIP #280 */
ExtCmdLoc *extCmdMapPtr; /* Extended command location information for
* 'info frame'. */
Tcl_Size line; /* First line of the script, based on the
* invoking context, then the line of the
* command currently compiled. */
int atCmdStart; /* Flag to say whether an INST_START_CMD
* should be issued; they should never be
* issued repeatedly, as that is significantly
* inefficient. If set to 2, that instruction
* should not be issued at all (by the generic
* part of the command compiler). */
Tcl_Size expandCount; /* Number of INST_EXPAND_START instructions
* encountered that have not yet been paired
* with a corresponding
* INST_INVOKE_EXPANDED. */
Tcl_Size *clNext; /* If not NULL, it refers to the next slot in
* clLoc to check for an invisible
* continuation line. */
} CompileEnv;
/*
* The structure defining the bytecode instructions resulting from compiling a
* Tcl script. Note that this structure is variable length: a single heap
|
| ︙ | ︙ | |||
423 424 425 426 427 428 429 |
typedef struct ByteCode {
TclHandle interpHandle; /* Handle for interpreter containing the
* compiled code. Commands and their compile
* procs are specific to an interpreter so the
* code emitted will depend on the
* interpreter. */
| | | 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 |
typedef struct ByteCode {
TclHandle interpHandle; /* Handle for interpreter containing the
* compiled code. Commands and their compile
* procs are specific to an interpreter so the
* code emitted will depend on the
* interpreter. */
Tcl_Size compileEpoch; /* Value of iPtr->compileEpoch when this
* ByteCode was compiled. Used to invalidate
* code when, e.g., commands with compile
* procs are redefined. */
Namespace *nsPtr; /* Namespace context in which this code was
* compiled. If the code is executed if a
* different namespace, it must be
* recompiled. */
|
| ︙ | ︙ | |||
455 456 457 458 459 460 461 |
* Proc structure; otherwise NULL. This
* pointer is also not owned by the ByteCode
* and must not be freed by it. */
size_t structureSize; /* Number of bytes in the ByteCode structure
* itself. Does not include heap space for
* literal Tcl objects or storage referenced
* by AuxData entries. */
| | | | | | | | | | 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 |
* Proc structure; otherwise NULL. This
* pointer is also not owned by the ByteCode
* and must not be freed by it. */
size_t structureSize; /* Number of bytes in the ByteCode structure
* itself. Does not include heap space for
* literal Tcl objects or storage referenced
* by AuxData entries. */
Tcl_Size numCommands; /* Number of commands compiled. */
Tcl_Size numSrcBytes; /* Number of source bytes compiled. */
Tcl_Size numCodeBytes; /* Number of code bytes. */
Tcl_Size numLitObjects; /* Number of objects in literal array. */
Tcl_Size numExceptRanges; /* Number of ExceptionRange array elems. */
Tcl_Size numAuxDataItems; /* Number of AuxData items. */
Tcl_Size numCmdLocBytes; /* Number of bytes needed for encoded command
* location information. */
Tcl_Size maxExceptDepth; /* Maximum nesting level of ExceptionRanges;
* TCL_INDEX_NONE if no ranges were compiled. */
Tcl_Size maxStackDepth; /* Maximum number of stack elements needed to
* execute the code. */
unsigned char *codeStart; /* Points to the first byte of the code. This
* is just after the final ByteCode member
* cmdMapPtr. */
Tcl_Obj **objArrayPtr; /* Points to the start of the literal object
* array. This is just after the last code
* byte. */
ExceptionRange *exceptArrayPtr;
/* Points to the start of the ExceptionRange
* array. This is just after the last object
* in the object array. */
AuxData *auxDataArrayPtr; /* Points to the start of the auxiliary data
* array. This is just after the last entry in
* the ExceptionRange array. */
unsigned char *codeDeltaStart;
/* Points to the first of a sequence of bytes
|
| ︙ | ︙ | |||
825 826 827 828 829 830 831 |
INST_LAPPEND_LIST_ARRAY_STK,
INST_LAPPEND_LIST_STK,
INST_CLOCK_READ,
INST_DICT_GET_DEF,
| | | | | | | 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 |
INST_LAPPEND_LIST_ARRAY_STK,
INST_LAPPEND_LIST_STK,
INST_CLOCK_READ,
INST_DICT_GET_DEF,
/* TIP 461 */
INST_STR_LT,
INST_STR_GT,
INST_STR_LE,
INST_STR_GE,
INST_LREPLACE4,
/* TIP 667: const */
INST_CONST_IMM,
INST_CONST_STK,
|
| ︙ | ︙ | |||
965 966 967 968 969 970 971 |
* to 5 bytes. */
} JumpFixup;
#define JUMPFIXUP_INIT_ENTRIES 10
typedef struct JumpFixupArray {
JumpFixup *fixup; /* Points to start of jump fixup array. */
| | | | > | | | > | 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 |
* to 5 bytes. */
} JumpFixup;
#define JUMPFIXUP_INIT_ENTRIES 10
typedef struct JumpFixupArray {
JumpFixup *fixup; /* Points to start of jump fixup array. */
Tcl_Size next; /* Index of next free array entry. */
Tcl_Size end; /* Index of last usable entry in array. */
int mallocedArray; /* 1 if array was expanded and fixups points
* into the heap, else 0. */
JumpFixup staticFixupSpace[JUMPFIXUP_INIT_ENTRIES];
/* Initial storage for jump fixup array. */
} JumpFixupArray;
/*
* The structure describing one variable list of a foreach command. Note that
* only foreach commands inside procedure bodies are compiled inline so a
* ForeachVarList structure always describes local variables. Furthermore,
* only scalar variables are supported for inline-compiled foreach loops.
*/
typedef struct ForeachVarList {
Tcl_Size numVars; /* The number of variables in the list. */
Tcl_Size varIndexes[TCLFLEXARRAY];
/* An array of the indexes ("slot numbers")
* for each variable in the procedure's array
* of local variables. Only scalar variables
* are supported. The actual size of this
* field will be large enough to numVars
* indexes. THIS MUST BE THE LAST FIELD IN THE
* STRUCTURE! */
} ForeachVarList;
/*
* Structure used to hold information about a foreach command that is needed
* during program execution. These structures are stored in CompileEnv and
* ByteCode structures as auxiliary data.
*/
typedef struct ForeachInfo {
Tcl_Size numLists; /* The number of both the variable and value
* lists of the foreach command. */
Tcl_Size firstValueTemp; /* Index of the first temp var in a proc frame
* used to point to a value list. */
Tcl_Size loopCtTemp; /* Index of temp var in a proc frame holding
* the loop's iteration count. Used to
* determine next value list element to assign
* each loop var. */
ForeachVarList *varLists[TCLFLEXARRAY];
/* An array of pointers to ForeachVarList
* structures describing each var list. The
* actual size of this field will be large
* enough to numVars indexes. THIS MUST BE THE
* LAST FIELD IN THE STRUCTURE! */
} ForeachInfo;
/*
|
| ︙ | ︙ | |||
1037 1038 1039 1040 1041 1042 1043 |
* Structure used to hold information about a [dict update] command that is
* needed during program execution. These structures are stored in CompileEnv
* and ByteCode structures as auxiliary data.
*/
typedef struct {
Tcl_Size length; /* Size of array */
| | > | 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 |
* Structure used to hold information about a [dict update] command that is
* needed during program execution. These structures are stored in CompileEnv
* and ByteCode structures as auxiliary data.
*/
typedef struct {
Tcl_Size length; /* Size of array */
Tcl_Size varIndices[TCLFLEXARRAY];
/* Array of variable indices to manage when
* processing the start and end of a [dict
* update]. There is really more than one
* entry, and the structure is allocated to
* take account of this. MUST BE LAST FIELD IN
* STRUCTURE. */
} DictUpdateInfo;
|
| ︙ | ︙ | |||
1244 1245 1246 1247 1248 1249 1250 |
if ((int)(envPtr)->maxStackDepth < (int)(envPtr)->currStackDepth) { \
(envPtr)->maxStackDepth = (envPtr)->currStackDepth; \
} \
} \
(envPtr)->currStackDepth += (delta); \
} while (0)
| | | | | 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 |
if ((int)(envPtr)->maxStackDepth < (int)(envPtr)->currStackDepth) { \
(envPtr)->maxStackDepth = (envPtr)->currStackDepth; \
} \
} \
(envPtr)->currStackDepth += (delta); \
} while (0)
#define TclGetStackDepth(envPtr) \
((envPtr)->currStackDepth)
#define TclSetStackDepth(depth, envPtr) \
(envPtr)->currStackDepth = (depth)
#define TclCheckStackDepth(depth, envPtr) \
do { \
size_t _dd = (depth); \
if (_dd != (size_t)(envPtr)->currStackDepth) { \
Tcl_Panic("bad stack depth computations: is %" TCL_Z_MODIFIER "u, should be %" TCL_Z_MODIFIER "u", \
(size_t)(envPtr)->currStackDepth, _dd); \
} \
} while (0)
/*
* Macro used to update the stack requirements. It is called by the macros
|
| ︙ | ︙ | |||
1276 1277 1278 1279 1280 1281 1282 |
#define TclUpdateStackReqs(op, i, envPtr) \
do { \
int _delta = tclInstructionTable[(op)].stackEffect; \
if (_delta) { \
if (_delta == INT_MIN) { \
_delta = 1 - (i); \
} \
| | | 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 |
#define TclUpdateStackReqs(op, i, envPtr) \
do { \
int _delta = tclInstructionTable[(op)].stackEffect; \
if (_delta) { \
if (_delta == INT_MIN) { \
_delta = 1 - (i); \
} \
TclAdjustStackDepth(_delta, envPtr); \
} \
} while (0)
/*
* Macros used to update the flag that indicates if we are at the start of a
* command, based on whether the opcode is INST_START_COMMAND.
*
|
| ︙ | ︙ | |||
1389 1390 1391 1392 1393 1394 1395 | * These support, respectively, a maximum of 256 (2**8) and 2**32 objects in a * CompileEnv. The ANSI C "prototype" for this macro is: * * void TclEmitPush(int objIndex, CompileEnv *envPtr); */ #define TclEmitPush(objIndex, envPtr) \ | | | | | | | 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 |
* These support, respectively, a maximum of 256 (2**8) and 2**32 objects in a
* CompileEnv. The ANSI C "prototype" for this macro is:
*
* void TclEmitPush(int objIndex, CompileEnv *envPtr);
*/
#define TclEmitPush(objIndex, envPtr) \
do { \
int _objIndexCopy = (objIndex); \
if (_objIndexCopy <= 255) { \
TclEmitInstInt1(INST_PUSH1, _objIndexCopy, (envPtr)); \
} else { \
TclEmitInstInt4(INST_PUSH4, _objIndexCopy, (envPtr)); \
} \
} while (0)
/*
* Macros to update a (signed or unsigned) integer starting at a pointer. The
* two variants depend on the number of bytes. The ANSI C "prototypes" for
* these macros are:
*
|
| ︙ | ︙ | |||
1603 1604 1605 1606 1607 1608 1609 |
/*
* Macros for making it easier to deal with tokens and DStrings.
*/
#define TclDStringAppendToken(dsPtr, tokenPtr) \
Tcl_DStringAppend((dsPtr), (tokenPtr)->start, (tokenPtr)->size)
#define TclRegisterDStringLiteral(envPtr, dsPtr) \
| | | 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 |
/*
* Macros for making it easier to deal with tokens and DStrings.
*/
#define TclDStringAppendToken(dsPtr, tokenPtr) \
Tcl_DStringAppend((dsPtr), (tokenPtr)->start, (tokenPtr)->size)
#define TclRegisterDStringLiteral(envPtr, dsPtr) \
TclRegisterLiteral(envPtr, Tcl_DStringValue(dsPtr), \
Tcl_DStringLength(dsPtr), /*flags*/ 0)
/*
* Macro that encapsulates an efficiency trick that avoids a function call for
* the simplest of compiles. The ANSI C "prototype" for this macro is:
*
* static void CompileWord(CompileEnv *envPtr, Tcl_Token *tokenPtr,
|
| ︙ | ︙ |
Changes to generic/tclDictObj.c.
| ︙ | ︙ | |||
127 128 129 130 131 132 133 |
* dictionary. Used for doing traversal of the
* entries in the order that they are
* created. */
ChainEntry *entryChainTail; /* Other end of linked list of all entries in
* the dictionary. Used for doing traversal of
* the entries in the order that they are
* created. */
| | | 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
* dictionary. Used for doing traversal of the
* entries in the order that they are
* created. */
ChainEntry *entryChainTail; /* Other end of linked list of all entries in
* the dictionary. Used for doing traversal of
* the entries in the order that they are
* created. */
size_t epoch; /* Epoch counter */
size_t refCount; /* Reference counter (see above) */
Tcl_Obj *chain; /* Linked list used for invalidating the
* string representations of updated nested
* dictionaries. */
} Dict;
/*
|
| ︙ | ︙ | |||
2054 2055 2056 2057 2058 2059 2060 |
DictSizeCmd(
TCL_UNUSED(void *),
Tcl_Interp *interp,
int objc,
Tcl_Obj *const *objv)
{
int result;
| | | 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 |
DictSizeCmd(
TCL_UNUSED(void *),
Tcl_Interp *interp,
int objc,
Tcl_Obj *const *objv)
{
int result;
Tcl_Size size;
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, "dictionary");
return TCL_ERROR;
}
result = Tcl_DictObjSize(interp, objv[1], &size);
if (result == TCL_OK) {
|
| ︙ | ︙ |
Changes to generic/tclDisassemble.c.
| ︙ | ︙ | |||
320 321 322 323 324 325 326 |
*/
if (codePtr->procPtr != NULL) {
Proc *procPtr = codePtr->procPtr;
Tcl_Size numCompiledLocals = procPtr->numCompiledLocals;
Tcl_AppendPrintfToObj(bufferObj,
| | > > | 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 |
*/
if (codePtr->procPtr != NULL) {
Proc *procPtr = codePtr->procPtr;
Tcl_Size numCompiledLocals = procPtr->numCompiledLocals;
Tcl_AppendPrintfToObj(bufferObj,
" Proc %p, refCt %" TCL_SIZE_MODIFIER "d, "
"args %" TCL_SIZE_MODIFIER "d, "
"compiled locals %" TCL_SIZE_MODIFIER "d\n",
procPtr, procPtr->refCount, procPtr->numArgs,
numCompiledLocals);
if (numCompiledLocals > 0) {
CompiledLocal *localPtr = procPtr->firstLocalPtr;
for (i = 0; i < numCompiledLocals; i++) {
Tcl_AppendPrintfToObj(bufferObj,
|
| ︙ | ︙ | |||
351 352 353 354 355 356 357 |
}
/*
* Print the ExceptionRange array.
*/
if ((int)codePtr->numExceptRanges > 0) {
| | > > | > > | > > | > | 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 |
}
/*
* Print the ExceptionRange array.
*/
if ((int)codePtr->numExceptRanges > 0) {
Tcl_AppendPrintfToObj(bufferObj,
" Exception ranges %" TCL_SIZE_MODIFIER "d, "
"depth %" TCL_SIZE_MODIFIER "d:\n",
codePtr->numExceptRanges, codePtr->maxExceptDepth);
for (i = 0; i < (int)codePtr->numExceptRanges; i++) {
ExceptionRange *rangePtr = &codePtr->exceptArrayPtr[i];
Tcl_AppendPrintfToObj(bufferObj,
" %" TCL_SIZE_MODIFIER "d: "
"level %" TCL_SIZE_MODIFIER "d, %s, "
"pc %" TCL_SIZE_MODIFIER "d-%" TCL_SIZE_MODIFIER "d, ",
i, rangePtr->nestingLevel,
(rangePtr->type==LOOP_EXCEPTION_RANGE ? "loop" : "catch"),
rangePtr->codeOffset,
(rangePtr->codeOffset + rangePtr->numCodeBytes - 1));
switch (rangePtr->type) {
case LOOP_EXCEPTION_RANGE:
Tcl_AppendPrintfToObj(bufferObj,
"continue %" TCL_SIZE_MODIFIER "d, "
"break %" TCL_SIZE_MODIFIER "d\n",
rangePtr->continueOffset, rangePtr->breakOffset);
break;
case CATCH_EXCEPTION_RANGE:
Tcl_AppendPrintfToObj(bufferObj,
"catch %" TCL_SIZE_MODIFIER "d\n",
rangePtr->catchOffset);
break;
default:
Tcl_Panic("DisassembleByteCodeObj: bad ExceptionRange type %d",
rangePtr->type);
}
}
|
| ︙ | ︙ | |||
442 443 444 445 446 447 448 |
srcLen = TclGetInt4AtPtr(srcLengthNext);
srcLengthNext += 4;
} else {
srcLen = TclGetInt1AtPtr(srcLengthNext);
srcLengthNext++;
}
| | > | 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 |
srcLen = TclGetInt4AtPtr(srcLengthNext);
srcLengthNext += 4;
} else {
srcLen = TclGetInt1AtPtr(srcLengthNext);
srcLengthNext++;
}
Tcl_AppendPrintfToObj(bufferObj,
"%s%4" TCL_SIZE_MODIFIER "d: pc %d-%d, src %d-%d",
((i % 2)? " " : "\n "),
(i+1), codeOffset, (codeOffset + codeLen - 1),
srcOffset, (srcOffset + srcLen - 1));
}
if (numCmds > 0) {
Tcl_AppendToObj(bufferObj, "\n", -1);
}
|
| ︙ | ︙ | |||
501 502 503 504 505 506 507 |
*/
while ((pc-codeStart) < codeOffset) {
Tcl_AppendToObj(bufferObj, " ", -1);
pc += FormatInstruction(codePtr, pc, bufferObj);
}
| | > | 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 |
*/
while ((pc-codeStart) < codeOffset) {
Tcl_AppendToObj(bufferObj, " ", -1);
pc += FormatInstruction(codePtr, pc, bufferObj);
}
Tcl_AppendPrintfToObj(bufferObj,
" Command %" TCL_SIZE_MODIFIER "d: ", i+1);
PrintSourceToObj(bufferObj, (codePtr->source + srcOffset),
TclMin(srcLen, 55));
Tcl_AppendToObj(bufferObj, "\n", -1);
}
if (pc < codeLimit) {
/*
* Print instructions after the last command.
|
| ︙ | ︙ | |||
568 569 570 571 572 573 574 |
case OPERAND_UINT1:
opnd = TclGetUInt1AtPtr(pc+numBytes); numBytes++;
Tcl_AppendPrintfToObj(bufferObj, "%u ", opnd);
break;
case OPERAND_UINT4:
opnd = TclGetUInt4AtPtr(pc+numBytes); numBytes += 4;
if (opCode == INST_START_CMD) {
| > | | > | > | > | 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 |
case OPERAND_UINT1:
opnd = TclGetUInt1AtPtr(pc+numBytes); numBytes++;
Tcl_AppendPrintfToObj(bufferObj, "%u ", opnd);
break;
case OPERAND_UINT4:
opnd = TclGetUInt4AtPtr(pc+numBytes); numBytes += 4;
if (opCode == INST_START_CMD) {
snprintf(suffixBuffer + strlen(suffixBuffer),
sizeof(suffixBuffer) - strlen(suffixBuffer),
", %u cmds start here", opnd);
}
Tcl_AppendPrintfToObj(bufferObj, "%u ", opnd);
break;
case OPERAND_OFFSET1:
opnd = TclGetInt1AtPtr(pc+numBytes); numBytes++;
snprintf(suffixBuffer, sizeof(suffixBuffer),
"pc %u", pcOffset+opnd);
Tcl_AppendPrintfToObj(bufferObj, "%+d ", opnd);
break;
case OPERAND_OFFSET4:
opnd = TclGetInt4AtPtr(pc+numBytes); numBytes += 4;
if (opCode == INST_START_CMD) {
snprintf(suffixBuffer, sizeof(suffixBuffer),
"next cmd at pc %u", pcOffset+opnd);
} else {
snprintf(suffixBuffer, sizeof(suffixBuffer),
"pc %u", pcOffset+opnd);
}
Tcl_AppendPrintfToObj(bufferObj, "%+d ", opnd);
break;
case OPERAND_LIT1:
opnd = TclGetUInt1AtPtr(pc+numBytes); numBytes++;
suffixObj = codePtr->objArrayPtr[opnd];
Tcl_AppendPrintfToObj(bufferObj, "%u ", opnd);
|
| ︙ | ︙ | |||
622 623 624 625 626 627 628 |
goto printLVTindex;
case OPERAND_LVT4:
opnd = TclGetUInt4AtPtr(pc+numBytes);
numBytes += 4;
printLVTindex:
if (localPtr != NULL) {
if (opnd >= localCt) {
| | > | 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 |
goto printLVTindex;
case OPERAND_LVT4:
opnd = TclGetUInt4AtPtr(pc+numBytes);
numBytes += 4;
printLVTindex:
if (localPtr != NULL) {
if (opnd >= localCt) {
Tcl_Panic("FormatInstruction: bad local var index "
"%u (%" TCL_SIZE_MODIFIER "d locals)",
opnd, localCt);
}
for (j = 0; j < opnd; j++) {
localPtr = localPtr->nextPtr;
}
if (TclIsVarTemporary(localPtr)) {
snprintf(suffixBuffer, sizeof(suffixBuffer), "temp var %u", opnd);
|
| ︙ | ︙ | |||
1265 1266 1267 1268 1269 1270 1271 | * in order to disassemble them. * *---------------------------------------------------------------------- */ int Tcl_DisassembleObjCmd( | | | 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 |
* in order to disassemble them.
*
*----------------------------------------------------------------------
*/
int
Tcl_DisassembleObjCmd(
void *clientData, /* What type of operation. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
static const char *const types[] = {
"constructor", "destructor",
"lambda", "method", "objmethod", "proc", "script", NULL
|
| ︙ | ︙ |
Changes to generic/tclEncoding.c.
| ︙ | ︙ | |||
30 31 32 33 34 35 36 |
* into UTF-8. */
Tcl_EncodingConvertProc *fromUtfProc;
/* Function to convert from UTF-8 into
* external encoding. */
Tcl_EncodingFreeProc *freeProc;
/* If non-NULL, function to call when this
* encoding is deleted. */
| | | | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
* into UTF-8. */
Tcl_EncodingConvertProc *fromUtfProc;
/* Function to convert from UTF-8 into
* external encoding. */
Tcl_EncodingFreeProc *freeProc;
/* If non-NULL, function to call when this
* encoding is deleted. */
void *clientData; /* Arbitrary value associated with encoding
* type. Passed to conversion functions. */
Tcl_Size nullSize; /* Number of 0x00 bytes that signify
* end-of-string in this encoding. This number
* is used to determine the source string
* length when the srcLen argument is
* negative. This number can be 1, 2, or 4. */
LengthProc *lengthProc; /* Function to compute length of
* null-terminated strings in this encoding.
* If nullSize is 1, this is strlen; if
|
| ︙ | ︙ | |||
1153 1154 1155 1156 1157 1158 1159 |
int
Tcl_ExternalToUtfDStringEx(
Tcl_Interp *interp, /* For error messages. May be NULL. */
Tcl_Encoding encoding, /* The encoding for the source string, or NULL
* for the default system encoding. */
const char *src, /* Source string in specified encoding. */
| | | | < | 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 |
int
Tcl_ExternalToUtfDStringEx(
Tcl_Interp *interp, /* For error messages. May be NULL. */
Tcl_Encoding encoding, /* The encoding for the source string, or NULL
* for the default system encoding. */
const char *src, /* Source string in specified encoding. */
Tcl_Size srcLen, /* Source string length in bytes, or < 0 for
* encoding-specific string length. */
int flags, /* Conversion control flags. */
Tcl_DString *dstPtr, /* Uninitialized or free DString in which the
* converted string is stored. */
Tcl_Size *errorLocPtr) /* Where to store the error location (or
* TCL_INDEX_NONE if no error). May be NULL. */
{
char *dst;
Tcl_EncodingState state;
const Encoding *encodingPtr;
int result;
Tcl_Size dstLen, soFar;
const char *srcStart = src;
|
| ︙ | ︙ | |||
1488 1489 1490 1491 1492 1493 1494 |
* NULL for the default system encoding. */
const char *src, /* Source string in UTF-8. */
Tcl_Size srcLen, /* Source string length in bytes, or < 0 for
* strlen(). */
int flags, /* Conversion control flags. */
Tcl_DString *dstPtr, /* Uninitialized or free DString in which the
* converted string is stored. */
| | | < | 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 |
* NULL for the default system encoding. */
const char *src, /* Source string in UTF-8. */
Tcl_Size srcLen, /* Source string length in bytes, or < 0 for
* strlen(). */
int flags, /* Conversion control flags. */
Tcl_DString *dstPtr, /* Uninitialized or free DString in which the
* converted string is stored. */
Tcl_Size *errorLocPtr) /* Where to store the error location (or
* TCL_INDEX_NONE if no error). May be NULL. */
{
char *dst;
Tcl_EncodingState state;
const Encoding *encodingPtr;
int result;
const char *srcStart = src;
Tcl_Size dstLen, soFar;
|
| ︙ | ︙ | |||
2629 2630 2631 2632 2633 2634 2635 | * None. * *------------------------------------------------------------------------- */ static int Utf32ToUtfProc( | | | 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 |
* None.
*
*-------------------------------------------------------------------------
*/
static int
Utf32ToUtfProc(
void *clientData, /* additional flags, e.g. TCL_ENCODING_LE */
const char *src, /* Source string in Unicode. */
int srcLen, /* Source string length in bytes. */
int flags, /* Conversion control flags. */
TCL_UNUSED(Tcl_EncodingState *),
char *dst, /* Output buffer in which converted string is
* stored. */
int dstLen, /* The maximum length of output buffer in
|
| ︙ | ︙ | |||
2757 2758 2759 2760 2761 2762 2763 | * None. * *------------------------------------------------------------------------- */ static int UtfToUtf32Proc( | | | 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 |
* None.
*
*-------------------------------------------------------------------------
*/
static int
UtfToUtf32Proc(
void *clientData, /* additional flags, e.g. TCL_ENCODING_LE */
const char *src, /* Source string in UTF-8. */
int srcLen, /* Source string length in bytes. */
int flags, /* Conversion control flags. */
TCL_UNUSED(Tcl_EncodingState *),
char *dst, /* Output buffer in which converted string is
* stored. */
int dstLen, /* The maximum length of output buffer in
|
| ︙ | ︙ | |||
2856 2857 2858 2859 2860 2861 2862 | * None. * *------------------------------------------------------------------------- */ static int Utf16ToUtfProc( | | | 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 |
* None.
*
*-------------------------------------------------------------------------
*/
static int
Utf16ToUtfProc(
void *clientData, /* additional flags, e.g. TCL_ENCODING_LE */
const char *src, /* Source string in Unicode. */
int srcLen, /* Source string length in bytes. */
int flags, /* Conversion control flags. */
TCL_UNUSED(Tcl_EncodingState *),
char *dst, /* Output buffer in which converted string is
* stored. */
int dstLen, /* The maximum length of output buffer in
|
| ︙ | ︙ | |||
3034 3035 3036 3037 3038 3039 3040 | * None. * *------------------------------------------------------------------------- */ static int UtfToUtf16Proc( | | | 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 |
* None.
*
*-------------------------------------------------------------------------
*/
static int
UtfToUtf16Proc(
void *clientData, /* additional flags, e.g. TCL_ENCODING_LE */
const char *src, /* Source string in UTF-8. */
int srcLen, /* Source string length in bytes. */
int flags, /* Conversion control flags. */
TCL_UNUSED(Tcl_EncodingState *),
char *dst, /* Output buffer in which converted string is
* stored. */
int dstLen, /* The maximum length of output buffer in
|
| ︙ | ︙ | |||
3142 3143 3144 3145 3146 3147 3148 | * None. * *------------------------------------------------------------------------- */ static int UtfToUcs2Proc( | | | 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 |
* None.
*
*-------------------------------------------------------------------------
*/
static int
UtfToUcs2Proc(
void *clientData, /* additional flags, e.g. TCL_ENCODING_LE */
const char *src, /* Source string in UTF-8. */
int srcLen, /* Source string length in bytes. */
int flags, /* Conversion control flags. */
TCL_UNUSED(Tcl_EncodingState *),
char *dst, /* Output buffer in which converted string is
* stored. */
int dstLen, /* The maximum length of output buffer in
|
| ︙ | ︙ | |||
3246 3247 3248 3249 3250 3251 3252 | * None. * *------------------------------------------------------------------------- */ static int TableToUtfProc( | | | 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 |
* None.
*
*-------------------------------------------------------------------------
*/
static int
TableToUtfProc(
void *clientData, /* TableEncodingData that specifies
* encoding. */
const char *src, /* Source string in specified encoding. */
int srcLen, /* Source string length in bytes. */
int flags, /* Conversion control flags. */
TCL_UNUSED(Tcl_EncodingState *),
char *dst, /* Output buffer in which converted string is
* stored. */
|
| ︙ | ︙ | |||
3371 3372 3373 3374 3375 3376 3377 | * None. * *------------------------------------------------------------------------- */ static int TableFromUtfProc( | | | 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 |
* None.
*
*-------------------------------------------------------------------------
*/
static int
TableFromUtfProc(
void *clientData, /* TableEncodingData that specifies
* encoding. */
const char *src, /* Source string in UTF-8. */
int srcLen, /* Source string length in bytes. */
int flags, /* Conversion control flags. */
TCL_UNUSED(Tcl_EncodingState *),
char *dst, /* Output buffer in which converted string is
* stored. */
|
| ︙ | ︙ | |||
3663 3664 3665 3666 3667 3668 3669 | * Memory freed. * *--------------------------------------------------------------------------- */ static void TableFreeProc( | | | 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 |
* Memory freed.
*
*---------------------------------------------------------------------------
*/
static void
TableFreeProc(
void *clientData) /* TableEncodingData that specifies
* encoding. */
{
TableEncodingData *dataPtr = (TableEncodingData *)clientData;
/*
* Make sure we aren't freeing twice on shutdown. [Bug 219314]
*/
|
| ︙ | ︙ | |||
3698 3699 3700 3701 3702 3703 3704 | * None. * *------------------------------------------------------------------------- */ static int EscapeToUtfProc( | | | 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 |
* None.
*
*-------------------------------------------------------------------------
*/
static int
EscapeToUtfProc(
void *clientData, /* EscapeEncodingData that specifies
* encoding. */
const char *src, /* Source string in specified encoding. */
int srcLen, /* Source string length in bytes. */
int flags, /* Conversion control flags. */
Tcl_EncodingState *statePtr,/* Place for conversion routine to store state
* information used during a piecewise
* conversion. Contents of statePtr are
|
| ︙ | ︙ | |||
3911 3912 3913 3914 3915 3916 3917 | * None. * *------------------------------------------------------------------------- */ static int EscapeFromUtfProc( | | | 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 |
* None.
*
*-------------------------------------------------------------------------
*/
static int
EscapeFromUtfProc(
void *clientData, /* EscapeEncodingData that specifies
* encoding. */
const char *src, /* Source string in UTF-8. */
int srcLen, /* Source string length in bytes. */
int flags, /* Conversion control flags. */
Tcl_EncodingState *statePtr,/* Place for conversion routine to store state
* information used during a piecewise
* conversion. Contents of statePtr are
|
| ︙ | ︙ | |||
4122 4123 4124 4125 4126 4127 4128 | * Memory is freed. * *--------------------------------------------------------------------------- */ static void EscapeFreeProc( | | | 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 |
* Memory is freed.
*
*---------------------------------------------------------------------------
*/
static void
EscapeFreeProc(
void *clientData) /* EscapeEncodingData that specifies
* encoding. */
{
EscapeEncodingData *dataPtr = (EscapeEncodingData *)clientData;
EscapeSubTable *subTablePtr;
int i;
if (dataPtr == NULL) {
|
| ︙ | ︙ | |||
4327 4328 4329 4330 4331 4332 4333 |
*
*------------------------------------------------------------------------
*/
int
TclEncodingProfileNameToId(
Tcl_Interp *interp, /* For error messages. May be NULL */
const char *profileName, /* Name of profile */
| | | 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 |
*
*------------------------------------------------------------------------
*/
int
TclEncodingProfileNameToId(
Tcl_Interp *interp, /* For error messages. May be NULL */
const char *profileName, /* Name of profile */
int *profilePtr) /* Output */
{
size_t i;
size_t numProfiles = sizeof(encodingProfiles) / sizeof(encodingProfiles[0]);
for (i = 0; i < numProfiles; ++i) {
if (!strcmp(profileName, encodingProfiles[i].name)) {
*profilePtr = encodingProfiles[i].value;
|
| ︙ | ︙ |
Changes to generic/tclEnsemble.c.
| ︙ | ︙ | |||
81 82 83 84 85 86 87 |
FreeEnsembleCmdRep, /* freeIntRepProc */
DupEnsembleCmdRep, /* dupIntRepProc */
NULL, /* updateStringProc */
NULL, /* setFromAnyProc */
TCL_OBJTYPE_V0
};
| | | | | | | | | | | | | | | 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
FreeEnsembleCmdRep, /* freeIntRepProc */
DupEnsembleCmdRep, /* dupIntRepProc */
NULL, /* updateStringProc */
NULL, /* setFromAnyProc */
TCL_OBJTYPE_V0
};
#define ECRSetInternalRep(objPtr, ecRepPtr) \
do { \
Tcl_ObjInternalRep ir; \
ir.twoPtrValue.ptr1 = (ecRepPtr); \
ir.twoPtrValue.ptr2 = NULL; \
Tcl_StoreInternalRep((objPtr), &ensembleCmdType, &ir); \
} while (0)
#define ECRGetInternalRep(objPtr, ecRepPtr) \
do { \
const Tcl_ObjInternalRep *irPtr; \
irPtr = TclFetchInternalRep((objPtr), &ensembleCmdType); \
(ecRepPtr) = irPtr ? (EnsembleCmdRep *)irPtr->twoPtrValue.ptr1 : NULL; \
} while (0)
/*
* The internal rep for caching ensemble subcommand lookups and spelling
* corrections.
*/
typedef struct {
Tcl_Size epoch; /* Used to confirm when the data in this
* really structure matches up with the
* ensemble. */
Command *token; /* Reference to the command for which this
* structure is a cache of the resolution. */
Tcl_Obj *fix; /* Corrected spelling, if needed. */
Tcl_HashEntry *hPtr; /* Direct link to entry in the subcommand hash
* table. */
} EnsembleCmdRep;
static inline Tcl_Obj *
NewNsObj(
Tcl_Namespace *namespacePtr)
{
Namespace *nsPtr = (Namespace *) namespacePtr;
|
| ︙ | ︙ | |||
1814 1815 1816 1817 1818 1819 1820 |
} else {
/*
* If the command isn't yet confirmed with the hash as part of building
* the export table, scan the sorted array for matches.
*/
const char *subcmdName; /* Name of the subcommand or unique prefix of
| | < | 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 |
} else {
/*
* If the command isn't yet confirmed with the hash as part of building
* the export table, scan the sorted array for matches.
*/
const char *subcmdName; /* Name of the subcommand or unique prefix of
* it (a non-unique prefix produces an error). */
char *fullName = NULL; /* Full name of the subcommand. */
Tcl_Size stringLength, i;
Tcl_Size tableLength = ensemblePtr->subcommandTable.numEntries;
Tcl_Obj *fix;
subcmdName = Tcl_GetStringFromObj(subObj, &stringLength);
for (i=0 ; i<tableLength ; i++) {
|
| ︙ | ︙ | |||
2224 2225 2226 2227 2228 2229 2230 | } /* *---------------------------------------------------------------------- * * TclFetchEnsembleRoot -- * | | | | 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 | } /* *---------------------------------------------------------------------- * * TclFetchEnsembleRoot -- * * Returns the root of ensemble rewriting, if any. If no root exists, * returns objv instead. * * Results: * None. * * Side effects: * None. * |
| ︙ | ︙ |
Changes to generic/tclEnv.c.
| ︙ | ︙ | |||
34 35 36 37 38 39 40 | # define utf2tenvirondstr(str, dsPtr) \ Tcl_UtfToExternalDString(NULL, str, -1, dsPtr) # define techar char #endif /* MODULE_SCOPE */ | | | | 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# define utf2tenvirondstr(str, dsPtr) \
Tcl_UtfToExternalDString(NULL, str, -1, dsPtr)
# define techar char
#endif
/* MODULE_SCOPE */
size_t TclEnvEpoch = 0; /* Epoch of the tcl environment
* (if changed with tcl-env). */
static struct {
Tcl_Size cacheSize; /* Number of env strings in cache. */
char **cache; /* Array containing all of the environment
* strings that Tcl has allocated. */
#ifndef USE_PUTENV
techar **ourEnviron; /* Cache of the array that we allocate. We
* need to track this in case another
* subsystem swaps around the environ array
* like we do. */
Tcl_Size ourEnvironSize; /* Non-zero means that the environ array was
* malloced and has this many total entries
* allocated to it (not all may be in use at
* once). Zero means that the environment
|
| ︙ | ︙ |
Changes to generic/tclEvent.c.
| ︙ | ︙ | |||
65 66 67 68 69 70 71 |
/*
* For each exit handler created with a call to Tcl_Create(Late)ExitHandler
* there is a structure of the following type:
*/
typedef struct ExitHandler {
Tcl_ExitProc *proc; /* Function to call when process exits. */
| | | 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
/*
* For each exit handler created with a call to Tcl_Create(Late)ExitHandler
* there is a structure of the following type:
*/
typedef struct ExitHandler {
Tcl_ExitProc *proc; /* Function to call when process exits. */
void *clientData; /* One word of information to pass to proc. */
struct ExitHandler *nextPtr;/* Next in list of all exit handlers for this
* application, or NULL for end of list. */
} ExitHandler;
/*
* There is both per-process and per-thread exit handlers. The first list is
* controlled by a mutex. The other is in thread local storage.
|
| ︙ | ︙ | |||
115 116 117 118 119 120 121 |
* standard channels. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
#if TCL_THREADS
typedef struct {
Tcl_ThreadCreateProc *proc; /* Main() function of the thread */
| | | 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
* standard channels. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
#if TCL_THREADS
typedef struct {
Tcl_ThreadCreateProc *proc; /* Main() function of the thread */
void *clientData; /* The one argument to Main() */
} ThreadClientData;
static Tcl_ThreadCreateType NewThreadProc(void *clientData);
#endif /* TCL_THREADS */
/*
* Prototypes for functions referenced only in this file:
*/
|
| ︙ | ︙ | |||
609 610 611 612 613 614 615 | * reports, they are canceled. * *---------------------------------------------------------------------- */ static void BgErrorDeleteProc( | | | 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 |
* reports, they are canceled.
*
*----------------------------------------------------------------------
*/
static void
BgErrorDeleteProc(
void *clientData, /* Pointer to ErrAssocData structure. */
TCL_UNUSED(Tcl_Interp *))
{
ErrAssocData *assocPtr = (ErrAssocData *)clientData;
BgError *errPtr;
while (assocPtr->firstBgPtr != NULL) {
errPtr = assocPtr->firstBgPtr;
|
| ︙ | ︙ | |||
648 649 650 651 652 653 654 |
*
*----------------------------------------------------------------------
*/
void
Tcl_CreateExitHandler(
Tcl_ExitProc *proc, /* Function to invoke. */
| | | | 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 |
*
*----------------------------------------------------------------------
*/
void
Tcl_CreateExitHandler(
Tcl_ExitProc *proc, /* Function to invoke. */
void *clientData) /* Arbitrary value to pass to proc. */
{
ExitHandler *exitPtr = (ExitHandler*) Tcl_Alloc(sizeof(ExitHandler));
exitPtr->proc = proc;
exitPtr->clientData = clientData;
Tcl_MutexLock(&exitMutex);
exitPtr->nextPtr = firstExitPtr;
firstExitPtr = exitPtr;
Tcl_MutexUnlock(&exitMutex);
|
| ︙ | ︙ | |||
681 682 683 684 685 686 687 |
*
*----------------------------------------------------------------------
*/
void
TclCreateLateExitHandler(
Tcl_ExitProc *proc, /* Function to invoke. */
| | | | 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 |
*
*----------------------------------------------------------------------
*/
void
TclCreateLateExitHandler(
Tcl_ExitProc *proc, /* Function to invoke. */
void *clientData) /* Arbitrary value to pass to proc. */
{
ExitHandler *exitPtr = (ExitHandler*) Tcl_Alloc(sizeof(ExitHandler));
exitPtr->proc = proc;
exitPtr->clientData = clientData;
Tcl_MutexLock(&exitMutex);
exitPtr->nextPtr = firstLateExitPtr;
firstLateExitPtr = exitPtr;
Tcl_MutexUnlock(&exitMutex);
|
| ︙ | ︙ | |||
714 715 716 717 718 719 720 |
*
*----------------------------------------------------------------------
*/
void
Tcl_DeleteExitHandler(
Tcl_ExitProc *proc, /* Function that was previously registered. */
| | | 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 |
*
*----------------------------------------------------------------------
*/
void
Tcl_DeleteExitHandler(
Tcl_ExitProc *proc, /* Function that was previously registered. */
void *clientData) /* Arbitrary value to pass to proc. */
{
ExitHandler *exitPtr, *prevPtr;
Tcl_MutexLock(&exitMutex);
for (prevPtr = NULL, exitPtr = firstExitPtr; exitPtr != NULL;
prevPtr = exitPtr, exitPtr = exitPtr->nextPtr) {
if ((exitPtr->proc == proc)
|
| ︙ | ︙ | |||
757 758 759 760 761 762 763 |
*
*----------------------------------------------------------------------
*/
void
TclDeleteLateExitHandler(
Tcl_ExitProc *proc, /* Function that was previously registered. */
| | | 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 |
*
*----------------------------------------------------------------------
*/
void
TclDeleteLateExitHandler(
Tcl_ExitProc *proc, /* Function that was previously registered. */
void *clientData) /* Arbitrary value to pass to proc. */
{
ExitHandler *exitPtr, *prevPtr;
Tcl_MutexLock(&exitMutex);
for (prevPtr = NULL, exitPtr = firstLateExitPtr; exitPtr != NULL;
prevPtr = exitPtr, exitPtr = exitPtr->nextPtr) {
if ((exitPtr->proc == proc)
|
| ︙ | ︙ | |||
800 801 802 803 804 805 806 |
*
*----------------------------------------------------------------------
*/
void
Tcl_CreateThreadExitHandler(
Tcl_ExitProc *proc, /* Function to invoke. */
| | | 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 |
*
*----------------------------------------------------------------------
*/
void
Tcl_CreateThreadExitHandler(
Tcl_ExitProc *proc, /* Function to invoke. */
void *clientData) /* Arbitrary value to pass to proc. */
{
ExitHandler *exitPtr;
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
exitPtr = (ExitHandler*)Tcl_Alloc(sizeof(ExitHandler));
exitPtr->proc = proc;
exitPtr->clientData = clientData;
|
| ︙ | ︙ | |||
833 834 835 836 837 838 839 |
*
*----------------------------------------------------------------------
*/
void
Tcl_DeleteThreadExitHandler(
Tcl_ExitProc *proc, /* Function that was previously registered. */
| | | 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 |
*
*----------------------------------------------------------------------
*/
void
Tcl_DeleteThreadExitHandler(
Tcl_ExitProc *proc, /* Function that was previously registered. */
void *clientData) /* Arbitrary value to pass to proc. */
{
ExitHandler *exitPtr, *prevPtr;
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
for (prevPtr = NULL, exitPtr = tsdPtr->firstExitPtr; exitPtr != NULL;
prevPtr = exitPtr, exitPtr = exitPtr->nextPtr) {
if ((exitPtr->proc == proc)
|
| ︙ | ︙ | |||
2051 2052 2053 2054 2055 2056 2057 |
*/
int
Tcl_CreateThread(
Tcl_ThreadId *idPtr, /* Return, the ID of the thread */
Tcl_ThreadCreateProc *proc, /* Main() function of the thread */
void *clientData, /* The one argument to Main() */
| | | 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 |
*/
int
Tcl_CreateThread(
Tcl_ThreadId *idPtr, /* Return, the ID of the thread */
Tcl_ThreadCreateProc *proc, /* Main() function of the thread */
void *clientData, /* The one argument to Main() */
size_t stackSize, /* Size of stack for the new thread */
int flags) /* Flags controlling behaviour of the new
* thread. */
{
#if TCL_THREADS
ThreadClientData *cdPtr = (ThreadClientData *)Tcl_Alloc(sizeof(ThreadClientData));
int result;
|
| ︙ | ︙ |
Changes to generic/tclExecute.c.
| ︙ | ︙ | |||
3950 3951 3952 3953 3954 3955 3956 |
cleanup = 2;
part1Ptr = OBJ_UNDER_TOS;
objPtr = OBJ_AT_TOS;
TRACE(("\"%.30s\" \"%.30s\" => ", O2S(part1Ptr), O2S(objPtr)));
varPtr = TclObjLookupVarEx(interp, part1Ptr, NULL, 0, NULL,
/*createPart1*/1, /*createPart2*/0, &arrayPtr);
doConst:
| | | 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 |
cleanup = 2;
part1Ptr = OBJ_UNDER_TOS;
objPtr = OBJ_AT_TOS;
TRACE(("\"%.30s\" \"%.30s\" => ", O2S(part1Ptr), O2S(objPtr)));
varPtr = TclObjLookupVarEx(interp, part1Ptr, NULL, 0, NULL,
/*createPart1*/1, /*createPart2*/0, &arrayPtr);
doConst:
if (TclIsVarConstant(varPtr)) {
TRACE_APPEND(("\n"));
NEXT_INST_V(pcAdjustment, cleanup, 0);
}
if (TclIsVarArray(varPtr)) {
msgPart = "variable is array";
goto constError;
} else if (TclIsVarArrayElement(varPtr)) {
|
| ︙ | ︙ | |||
8002 8003 8004 8005 8006 8007 8008 |
Tcl_Interp *interp, /* Where to report errors. */
int opcode, /* What operation to perform. */
Tcl_Obj **constants, /* The execution environment's constants. */
Tcl_Obj *valuePtr, /* The first operand on the stack. */
Tcl_Obj *value2Ptr) /* The second operand on the stack. */
{
#define WIDE_RESULT(w) \
| | | | | | | | | | | | | | | | | | 8002 8003 8004 8005 8006 8007 8008 8009 8010 8011 8012 8013 8014 8015 8016 8017 8018 8019 8020 8021 8022 8023 8024 8025 8026 8027 8028 8029 8030 8031 8032 8033 8034 8035 |
Tcl_Interp *interp, /* Where to report errors. */
int opcode, /* What operation to perform. */
Tcl_Obj **constants, /* The execution environment's constants. */
Tcl_Obj *valuePtr, /* The first operand on the stack. */
Tcl_Obj *value2Ptr) /* The second operand on the stack. */
{
#define WIDE_RESULT(w) \
if (Tcl_IsShared(valuePtr)) { \
return Tcl_NewWideIntObj(w); \
} else { \
TclSetIntObj(valuePtr, (w)); \
return NULL; \
}
#define BIG_RESULT(b) \
if (Tcl_IsShared(valuePtr)) { \
return Tcl_NewBignumObj(b); \
} else { \
Tcl_SetBignumObj(valuePtr, (b)); \
return NULL; \
}
#define DOUBLE_RESULT(d) \
if (Tcl_IsShared(valuePtr)) { \
TclNewDoubleObj(objResultPtr, (d)); \
return objResultPtr; \
} else { \
Tcl_SetDoubleObj(valuePtr, (d)); \
return NULL; \
}
int type1, type2;
void *ptr1, *ptr2;
double d1, d2, dResult;
Tcl_WideInt w1, w2, wResult;
mp_int big1, big2, bigResult, bigRemainder;
|
| ︙ | ︙ | |||
8987 8988 8989 8990 8991 8992 8993 |
PrintByteCodeInfo(
ByteCode *codePtr) /* The bytecode whose summary is printed to
* stdout. */
{
Proc *procPtr = codePtr->procPtr;
Interp *iPtr = (Interp *) *codePtr->interpHandle;
| > | > > > > > | > > | > | > | > > | 8987 8988 8989 8990 8991 8992 8993 8994 8995 8996 8997 8998 8999 9000 9001 9002 9003 9004 9005 9006 9007 9008 9009 9010 9011 9012 9013 9014 9015 9016 9017 9018 9019 9020 9021 9022 9023 9024 9025 9026 9027 9028 9029 9030 9031 9032 9033 9034 9035 9036 9037 9038 9039 9040 9041 9042 |
PrintByteCodeInfo(
ByteCode *codePtr) /* The bytecode whose summary is printed to
* stdout. */
{
Proc *procPtr = codePtr->procPtr;
Interp *iPtr = (Interp *) *codePtr->interpHandle;
fprintf(stdout,
"\nExecuting ByteCode 0x%p, refCt %" TCL_Z_MODIFIER "u, "
"epoch %" TCL_Z_MODIFIER "u, interp 0x%p "
"(epoch %" TCL_Z_MODIFIER "u)\n",
codePtr, codePtr->refCount, codePtr->compileEpoch, iPtr,
iPtr->compileEpoch);
fprintf(stdout, " Source: ");
TclPrintSource(stdout, codePtr->source, 60);
fprintf(stdout,
"\n Cmds %" TCL_Z_MODIFIER "u, "
"src %" TCL_Z_MODIFIER "u, inst %" TCL_Z_MODIFIER "u, "
"litObjs %" TCL_Z_MODIFIER "u, aux %" TCL_Z_MODIFIER "u, "
"stkDepth %" TCL_Z_MODIFIER "u, code/src %.2f\n",
codePtr->numCommands, codePtr->numSrcBytes,
codePtr->numCodeBytes, codePtr->numLitObjects,
codePtr->numAuxDataItems, codePtr->maxStackDepth,
#ifdef TCL_COMPILE_STATS
codePtr->numSrcBytes?
((float)codePtr->structureSize)/codePtr->numSrcBytes :
#endif
0.0);
#ifdef TCL_COMPILE_STATS
fprintf(stdout,
" Code %" TCL_Z_MODIFIER "u = header %" TCL_Z_MODIFIER "u+"
"inst %" TCL_Z_MODIFIER "u+litObj %" TCL_Z_MODIFIER "u+"
"exc %" TCL_Z_MODIFIER "u+aux %" TCL_Z_MODIFIER "u+"
"cmdMap %" TCL_Z_MODIFIER "u\n",
codePtr->structureSize,
offsetof(ByteCode, localCachePtr),
codePtr->numCodeBytes,
codePtr->numLitObjects * sizeof(Tcl_Obj *),
codePtr->numExceptRanges*sizeof(ExceptionRange),
codePtr->numAuxDataItems * sizeof(AuxData),
codePtr->numCmdLocBytes);
#endif /* TCL_COMPILE_STATS */
if (procPtr != NULL) {
fprintf(stdout,
" Proc 0x%p, refCt %" TCL_Z_MODIFIER "u, "
"args %" TCL_Z_MODIFIER "u, c"
"ompiled locals %" TCL_Z_MODIFIER "u\n",
procPtr, procPtr->refCount, procPtr->numArgs,
procPtr->numCompiledLocals);
}
}
#endif /* TCL_COMPILE_DEBUG */
/*
|
| ︙ | ︙ | |||
9069 9070 9071 9072 9073 9074 9075 |
if ((PTR2UINT(pc) < codeStart) || (PTR2UINT(pc) > codeEnd)) {
fprintf(stderr, "\nBad instruction pc 0x%p in TclNRExecuteByteCode\n",
pc);
Tcl_Panic("TclNRExecuteByteCode execution failure: bad pc");
}
if (opCode >= LAST_INST_OPCODE) {
| > | < | > | > | 9081 9082 9083 9084 9085 9086 9087 9088 9089 9090 9091 9092 9093 9094 9095 9096 9097 9098 9099 9100 9101 9102 9103 9104 9105 9106 |
if ((PTR2UINT(pc) < codeStart) || (PTR2UINT(pc) > codeEnd)) {
fprintf(stderr, "\nBad instruction pc 0x%p in TclNRExecuteByteCode\n",
pc);
Tcl_Panic("TclNRExecuteByteCode execution failure: bad pc");
}
if (opCode >= LAST_INST_OPCODE) {
fprintf(stderr,
"\nBad opcode %u at pc %" TCL_Z_MODIFIER "u in TclNRExecuteByteCode\n",
opCode, relativePc);
Tcl_Panic("TclNRExecuteByteCode execution failure: bad opcode");
}
if (checkStack && (stackTop > stackUpperBound)) {
Tcl_Size numChars;
const char *cmd = GetSrcInfoForPc(pc, codePtr, &numChars, NULL, NULL);
fprintf(stderr,
"\nBad stack top %" TCL_Z_MODIFIER "u at pc %" TCL_Z_MODIFIER "u "
"in TclNRExecuteByteCode (min 0, max %" TCL_Z_MODIFIER "u)",
stackTop, relativePc, stackUpperBound);
if (cmd != NULL) {
Tcl_Obj *message;
TclNewLiteralStringObj(message, "\n executing ");
Tcl_IncrRefCount(message);
Tcl_AppendLimitedToObj(message, cmd, numChars, 100, NULL);
|
| ︙ | ︙ | |||
9686 9687 9688 9689 9690 9691 9692 |
statsPtr->totalSrcBytes);
Tcl_AppendPrintfToObj(objPtr, " Code bytes\t\t\t%.6g\n",
totalCodeBytes);
Tcl_AppendPrintfToObj(objPtr, " ByteCode bytes\t\t%.6g\n",
statsPtr->totalByteCodeBytes);
Tcl_AppendPrintfToObj(objPtr, " Literal bytes\t\t%.6g\n",
totalLiteralBytes);
| > > | > > | | 9700 9701 9702 9703 9704 9705 9706 9707 9708 9709 9710 9711 9712 9713 9714 9715 9716 9717 9718 9719 9720 9721 9722 9723 9724 9725 9726 9727 9728 9729 9730 9731 9732 9733 9734 9735 9736 9737 9738 9739 |
statsPtr->totalSrcBytes);
Tcl_AppendPrintfToObj(objPtr, " Code bytes\t\t\t%.6g\n",
totalCodeBytes);
Tcl_AppendPrintfToObj(objPtr, " ByteCode bytes\t\t%.6g\n",
statsPtr->totalByteCodeBytes);
Tcl_AppendPrintfToObj(objPtr, " Literal bytes\t\t%.6g\n",
totalLiteralBytes);
Tcl_AppendPrintfToObj(objPtr,
" table %" TCL_Z_MODIFIER "u + bkts %" TCL_Z_MODIFIER "u + "
"entries %" TCL_Z_MODIFIER "u + objects %" TCL_Z_MODIFIER "u + strings %.6g\n",
sizeof(LiteralTable),
iPtr->literalTable.numBuckets * sizeof(LiteralEntry *),
statsPtr->numLiteralsCreated * sizeof(LiteralEntry),
statsPtr->numLiteralsCreated * sizeof(Tcl_Obj),
statsPtr->totalLitStringBytes);
Tcl_AppendPrintfToObj(objPtr, " Mean code/compile\t\t%.1f\n",
totalCodeBytes / statsPtr->numCompilations);
Tcl_AppendPrintfToObj(objPtr, " Mean code/source\t\t%.1f\n",
totalCodeBytes / statsPtr->totalSrcBytes);
Tcl_AppendPrintfToObj(objPtr, "\nCurrent (active) ByteCodes\t%" TCL_Z_MODIFIER "u\n",
numCurrentByteCodes);
Tcl_AppendPrintfToObj(objPtr, " Source bytes\t\t\t%.6g\n",
statsPtr->currentSrcBytes);
Tcl_AppendPrintfToObj(objPtr, " Code bytes\t\t\t%.6g\n",
currentCodeBytes);
Tcl_AppendPrintfToObj(objPtr, " ByteCode bytes\t\t%.6g\n",
statsPtr->currentByteCodeBytes);
Tcl_AppendPrintfToObj(objPtr, " Literal bytes\t\t%.6g\n",
currentLiteralBytes);
Tcl_AppendPrintfToObj(objPtr,
" table %" TCL_Z_MODIFIER "u + bkts %" TCL_Z_MODIFIER "u + "
"entries %" TCL_Z_MODIFIER "u + objects %" TCL_Z_MODIFIER "u + strings %.6g\n",
sizeof(LiteralTable),
iPtr->literalTable.numBuckets * sizeof(LiteralEntry *),
iPtr->literalTable.numEntries * sizeof(LiteralEntry),
iPtr->literalTable.numEntries * sizeof(Tcl_Obj),
statsPtr->currentLitStringBytes);
Tcl_AppendPrintfToObj(objPtr, " Mean code/source\t\t%.1f\n",
currentCodeBytes / statsPtr->currentSrcBytes);
|
| ︙ | ︙ |
Changes to generic/tclHash.c.
| ︙ | ︙ | |||
653 654 655 656 657 658 659 |
*
*----------------------------------------------------------------------
*/
static Tcl_HashEntry *
AllocArrayEntry(
Tcl_HashTable *tablePtr, /* Hash table. */
| | | 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 |
*
*----------------------------------------------------------------------
*/
static Tcl_HashEntry *
AllocArrayEntry(
Tcl_HashTable *tablePtr, /* Hash table. */
void *keyPtr) /* Key to store in the hash table entry. */
{
Tcl_HashEntry *hPtr;
size_t count = tablePtr->keyType * sizeof(int);
size_t size = offsetof(Tcl_HashEntry, key) + count;
if (size < sizeof(Tcl_HashEntry)) {
size = sizeof(Tcl_HashEntry);
|
| ︙ | ︙ | |||
689 690 691 692 693 694 695 | * None. * *---------------------------------------------------------------------- */ static int CompareArrayKeys( | | | 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 |
* None.
*
*----------------------------------------------------------------------
*/
static int
CompareArrayKeys(
void *keyPtr, /* New key to compare. */
Tcl_HashEntry *hPtr) /* Existing key to compare. */
{
size_t count = hPtr->tablePtr->keyType * sizeof(int);
return !memcmp(keyPtr, hPtr->key.string, count);
}
|
| ︙ | ︙ | |||
718 719 720 721 722 723 724 |
*
*----------------------------------------------------------------------
*/
static size_t
HashArrayKey(
Tcl_HashTable *tablePtr, /* Hash table. */
| | | 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 |
*
*----------------------------------------------------------------------
*/
static size_t
HashArrayKey(
Tcl_HashTable *tablePtr, /* Hash table. */
void *keyPtr) /* Key from which to compute hash value. */
{
const int *array = (const int *) keyPtr;
size_t result;
int count;
for (result = 0, count = tablePtr->keyType; count > 0;
count--, array++) {
|
| ︙ | ︙ | |||
750 751 752 753 754 755 756 |
*
*----------------------------------------------------------------------
*/
static Tcl_HashEntry *
AllocStringEntry(
TCL_UNUSED(Tcl_HashTable *),
| | | 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 |
*
*----------------------------------------------------------------------
*/
static Tcl_HashEntry *
AllocStringEntry(
TCL_UNUSED(Tcl_HashTable *),
void *keyPtr) /* Key to store in the hash table entry. */
{
const char *string = (const char *) keyPtr;
Tcl_HashEntry *hPtr;
size_t size, allocsize;
allocsize = size = strlen(string) + 1;
if (size < sizeof(hPtr->key)) {
|
| ︙ | ︙ | |||
786 787 788 789 790 791 792 | * None. * *---------------------------------------------------------------------- */ static int CompareStringKeys( | | | 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 |
* None.
*
*----------------------------------------------------------------------
*/
static int
CompareStringKeys(
void *keyPtr, /* New key to compare. */
Tcl_HashEntry *hPtr) /* Existing key to compare. */
{
return !strcmp((char *)keyPtr, hPtr->key.string);
}
/*
*----------------------------------------------------------------------
|
| ︙ | ︙ | |||
812 813 814 815 816 817 818 |
*
*----------------------------------------------------------------------
*/
static size_t
HashStringKey(
TCL_UNUSED(Tcl_HashTable *),
| | | 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 |
*
*----------------------------------------------------------------------
*/
static size_t
HashStringKey(
TCL_UNUSED(Tcl_HashTable *),
void *keyPtr) /* Key from which to compute hash value. */
{
const char *string = (const char *)keyPtr;
size_t result;
char c;
/*
* I tried a zillion different hash functions and asked many other people
|
| ︙ | ︙ |
Changes to generic/tclIO.c.
| ︙ | ︙ | |||
24 25 26 27 28 29 30 |
*/
typedef struct ChannelHandler {
Channel *chanPtr; /* The channel structure for this channel. */
int mask; /* Mask of desired events. */
Tcl_ChannelProc *proc; /* Procedure to call in the type of
* Tcl_CreateChannelHandler. */
| | | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
*/
typedef struct ChannelHandler {
Channel *chanPtr; /* The channel structure for this channel. */
int mask; /* Mask of desired events. */
Tcl_ChannelProc *proc; /* Procedure to call in the type of
* Tcl_CreateChannelHandler. */
void *clientData; /* Argument to pass to procedure. */
struct ChannelHandler *nextPtr;
/* Next one in list of registered handlers. */
} ChannelHandler;
/*
* This structure keeps track of the current ChannelHandler being invoked in
* the current invocation of Tcl_NotifyChannel. There is a potential
|
| ︙ | ︙ | |||
99 100 101 102 103 104 105 |
int readFlags; /* Original read channel flags. */
int writeFlags; /* Original write channel flags. */
Tcl_WideInt toRead; /* Number of bytes to copy, or -1. */
Tcl_WideInt total; /* Total bytes transferred (written). */
Tcl_Interp *interp; /* Interp that started the copy. */
Tcl_Obj *cmdPtr; /* Command to be invoked at completion. */
Tcl_Size bufSize; /* Size of appended buffer. */
| | | 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
int readFlags; /* Original read channel flags. */
int writeFlags; /* Original write channel flags. */
Tcl_WideInt toRead; /* Number of bytes to copy, or -1. */
Tcl_WideInt total; /* Total bytes transferred (written). */
Tcl_Interp *interp; /* Interp that started the copy. */
Tcl_Obj *cmdPtr; /* Command to be invoked at completion. */
Tcl_Size bufSize; /* Size of appended buffer. */
char buffer[TCLFLEXARRAY]; /* Copy buffer, this must be the last
* field. */
} CopyState;
/*
* All static variables used in this file are collected into a single instance
* of the following structure. For multi-threaded implementations, there is
* one instance of this structure for each thread.
|
| ︙ | ︙ | |||
137 138 139 140 141 142 143 |
/*
* Structure to record a close callback. One such record exists for
* each close callback registered for a channel.
*/
typedef struct CloseCallback {
| | | | > | 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
/*
* Structure to record a close callback. One such record exists for
* each close callback registered for a channel.
*/
typedef struct CloseCallback {
Tcl_CloseProc *proc; /* The procedure to call. */
void *clientData; /* Arbitrary one-word data to pass
* to the callback. */
struct CloseCallback *nextPtr;
/* For chaining close callbacks. */
} CloseCallback;
/*
* Static functions in this file:
*/
static ChannelBuffer * AllocChannelBuffer(Tcl_Size length);
|
| ︙ | ︙ | |||
170 171 172 173 174 175 176 | int errorCode); static int CloseChannelPart(Tcl_Interp *interp, Channel *chanPtr, int errorCode, int flags); static int CloseWrite(Tcl_Interp *interp, Channel *chanPtr); static void CommonGetsCleanup(Channel *chanPtr); static int CopyData(CopyState *csPtr, int mask); static void DeleteTimerHandler(ChannelState *statePtr); | | | 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | int errorCode); static int CloseChannelPart(Tcl_Interp *interp, Channel *chanPtr, int errorCode, int flags); static int CloseWrite(Tcl_Interp *interp, Channel *chanPtr); static void CommonGetsCleanup(Channel *chanPtr); static int CopyData(CopyState *csPtr, int mask); static void DeleteTimerHandler(ChannelState *statePtr); int Lossless(ChannelState *inStatePtr, ChannelState *outStatePtr, long long toRead); static int MoveBytes(CopyState *csPtr); static void MBCallback(CopyState *csPtr, Tcl_Obj *errObj); static void MBError(CopyState *csPtr, int mask, int errorCode); static int MBRead(CopyState *csPtr); static int MBWrite(CopyState *csPtr); |
| ︙ | ︙ | |||
227 228 229 230 231 232 233 | Tcl_Size srcLen, Tcl_Encoding encoding); static Tcl_Obj * FixLevelCode(Tcl_Obj *msg); static void SpliceChannel(Tcl_Channel chan); static void CutChannel(Tcl_Channel chan); static int WillRead(Channel *chanPtr); #define WriteChars(chanPtr, src, srcLen) \ | | | | 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 | Tcl_Size srcLen, Tcl_Encoding encoding); static Tcl_Obj * FixLevelCode(Tcl_Obj *msg); static void SpliceChannel(Tcl_Channel chan); static void CutChannel(Tcl_Channel chan); static int WillRead(Channel *chanPtr); #define WriteChars(chanPtr, src, srcLen) \ Write(chanPtr, src, srcLen, chanPtr->state->encoding) #define WriteBytes(chanPtr, src, srcLen) \ Write(chanPtr, src, srcLen, tclIdentityEncoding) /* * Simplifying helper macros. All may use their argument(s) multiple times. * The ANSI C "prototypes" for the macros are listed below, together with a * short description of what the macro does. * * -------------------------------------------------------------------------- |
| ︙ | ︙ | |||
329 330 331 332 333 334 335 |
} ResolvedChanName;
static void DupChannelInternalRep(Tcl_Obj *objPtr, Tcl_Obj *copyPtr);
static void FreeChannelInternalRep(Tcl_Obj *objPtr);
static const Tcl_ObjType chanObjType = {
"channel", /* name for this type */
| | | | | | | | | | 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 |
} ResolvedChanName;
static void DupChannelInternalRep(Tcl_Obj *objPtr, Tcl_Obj *copyPtr);
static void FreeChannelInternalRep(Tcl_Obj *objPtr);
static const Tcl_ObjType chanObjType = {
"channel", /* name for this type */
FreeChannelInternalRep, /* freeIntRepProc */
DupChannelInternalRep, /* dupIntRepProc */
NULL, /* updateStringProc */
NULL, /* setFromAnyProc */
TCL_OBJTYPE_V0
};
#define GetIso88591() \
(binaryEncoding ? Tcl_GetEncoding(NULL, "iso8859-1") : binaryEncoding)
#define ChanSetInternalRep(objPtr, resPtr) \
do { \
Tcl_ObjInternalRep ir; \
(resPtr)->refCount++; \
ir.twoPtrValue.ptr1 = (resPtr); \
ir.twoPtrValue.ptr2 = NULL; \
Tcl_StoreInternalRep((objPtr), &chanObjType, &ir); \
} while (0)
#define ChanGetInternalRep(objPtr, resPtr) \
do { \
const Tcl_ObjInternalRep *irPtr; \
irPtr = TclFetchInternalRep((objPtr), &chanObjType); \
(resPtr) = irPtr ? (ResolvedChanName *)irPtr->twoPtrValue.ptr1 : NULL; \
} while (0)
#define BUSY_STATE(st, fl) \
((((st)->csPtrR) && ((fl) & TCL_READABLE)) || \
(((st)->csPtrW) && ((fl) & TCL_WRITABLE)))
#define MAX_CHANNEL_BUFFER_SIZE (1024*1024)
/*
*---------------------------------------------------------------------------
*
|
| ︙ | ︙ | |||
843 844 845 846 847 848 849 |
void
Tcl_CreateCloseHandler(
Tcl_Channel chan, /* The channel for which to create the close
* callback. */
Tcl_CloseProc *proc, /* The callback routine to call when the
* channel will be closed. */
| | | 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 |
void
Tcl_CreateCloseHandler(
Tcl_Channel chan, /* The channel for which to create the close
* callback. */
Tcl_CloseProc *proc, /* The callback routine to call when the
* channel will be closed. */
void *clientData) /* Arbitrary data to pass to the close
* callback. */
{
ChannelState *statePtr = ((Channel *) chan)->state;
CloseCallback *cbPtr;
cbPtr = (CloseCallback *)Tcl_Alloc(sizeof(CloseCallback));
cbPtr->proc = proc;
|
| ︙ | ︙ | |||
881 882 883 884 885 886 887 |
void
Tcl_DeleteCloseHandler(
Tcl_Channel chan, /* The channel for which to cancel the close
* callback. */
Tcl_CloseProc *proc, /* The procedure for the callback to
* remove. */
| | | 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 |
void
Tcl_DeleteCloseHandler(
Tcl_Channel chan, /* The channel for which to cancel the close
* callback. */
Tcl_CloseProc *proc, /* The procedure for the callback to
* remove. */
void *clientData) /* The callback data for the callback to
* remove. */
{
ChannelState *statePtr = ((Channel *) chan)->state;
CloseCallback *cbPtr, *cbPrevPtr;
for (cbPtr = statePtr->closeCbPtr, cbPrevPtr = NULL;
cbPtr != NULL; cbPtr = cbPtr->nextPtr) {
|
| ︙ | ︙ | |||
980 981 982 983 984 985 986 | * registered in this interpreter. * *---------------------------------------------------------------------- */ static void DeleteChannelTable( | | | 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 |
* registered in this interpreter.
*
*----------------------------------------------------------------------
*/
static void
DeleteChannelTable(
void *clientData, /* The per-interpreter data structure. */
Tcl_Interp *interp) /* The interpreter being deleted. */
{
Tcl_HashTable *hTblPtr; /* The hash table. */
Tcl_HashSearch hSearch; /* Search variable. */
Tcl_HashEntry *hPtr; /* Search variable. */
Channel *chanPtr; /* Channel being deleted. */
ChannelState *statePtr; /* State of Channel being deleted. */
|
| ︙ | ︙ | |||
1523 1524 1525 1526 1527 1528 1529 |
if (interp == NULL) {
return TCL_ERROR;
}
ChanGetInternalRep(objPtr, resPtr);
if (resPtr) {
/*
| | | | 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 |
if (interp == NULL) {
return TCL_ERROR;
}
ChanGetInternalRep(objPtr, resPtr);
if (resPtr) {
/*
* Confirm validity of saved lookup results.
*/
statePtr = resPtr->statePtr;
if ((resPtr->interp == interp) /* Same interp context */
/* No epoch change in channel since lookup */
&& (resPtr->epoch == statePtr->epoch)) {
/*
* Have a valid saved lookup. Jump to end to return it.
|
| ︙ | ︙ | |||
1594 1595 1596 1597 1598 1599 1600 |
*----------------------------------------------------------------------
*/
Tcl_Channel
Tcl_CreateChannel(
const Tcl_ChannelType *typePtr, /* The channel type record. */
const char *chanName, /* Name of channel to record. */
| | | 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 |
*----------------------------------------------------------------------
*/
Tcl_Channel
Tcl_CreateChannel(
const Tcl_ChannelType *typePtr, /* The channel type record. */
const char *chanName, /* Name of channel to record. */
void *instanceData, /* Instance specific data. */
int mask) /* TCL_READABLE & TCL_WRITABLE to indicate if
* the channel is readable, writable. */
{
Channel *chanPtr; /* The channel structure newly created. */
ChannelState *statePtr; /* The stack-level independent state info for
* the channel. */
const char *name;
|
| ︙ | ︙ | |||
1813 1814 1815 1816 1817 1818 1819 |
Tcl_Channel
Tcl_StackChannel(
Tcl_Interp *interp, /* The interpreter we are working in */
const Tcl_ChannelType *typePtr,
/* The channel type record for the new
* channel. */
| | | 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 |
Tcl_Channel
Tcl_StackChannel(
Tcl_Interp *interp, /* The interpreter we are working in */
const Tcl_ChannelType *typePtr,
/* The channel type record for the new
* channel. */
void *instanceData, /* Instance specific data for the new
* channel. */
int mask, /* TCL_READABLE & TCL_WRITABLE to indicate if
* the channel is readable, writable. */
Tcl_Channel prevChan) /* The channel structure to replace */
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
Channel *chanPtr, *prevChanPtr;
|
| ︙ | ︙ | |||
2411 2412 2413 2414 2415 2416 2417 |
*----------------------------------------------------------------------
*/
int
Tcl_GetChannelHandle(
Tcl_Channel chan, /* The channel to get file from. */
int direction, /* TCL_WRITABLE or TCL_READABLE. */
| | | 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 |
*----------------------------------------------------------------------
*/
int
Tcl_GetChannelHandle(
Tcl_Channel chan, /* The channel to get file from. */
int direction, /* TCL_WRITABLE or TCL_READABLE. */
void **handlePtr) /* Where to store handle */
{
Channel *chanPtr; /* The actual channel. */
void *handle;
int result;
chanPtr = ((Channel *) chan)->state->bottomChanPtr;
if (!chanPtr->typePtr->getHandleProc) {
|
| ︙ | ︙ | |||
2506 2507 2508 2509 2510 2511 2512 | * None. * *--------------------------------------------------------------------------- */ static ChannelBuffer * AllocChannelBuffer( | | | 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 |
* None.
*
*---------------------------------------------------------------------------
*/
static ChannelBuffer *
AllocChannelBuffer(
Tcl_Size length) /* Desired length of channel buffer. */
{
ChannelBuffer *bufPtr;
Tcl_Size n;
n = length + CHANNELBUFFER_HEADER_SIZE + BUFFER_PADDING + BUFFER_PADDING;
bufPtr = (ChannelBuffer *)Tcl_Alloc(n);
bufPtr->nextAdded = BUFFER_PADDING;
|
| ︙ | ︙ | |||
4045 4046 4047 4048 4049 4050 4051 |
*----------------------------------------------------------------------
*/
Tcl_Size
Tcl_Write(
Tcl_Channel chan, /* The channel to buffer output for. */
const char *src, /* Data to queue in output buffer. */
| | | 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 |
*----------------------------------------------------------------------
*/
Tcl_Size
Tcl_Write(
Tcl_Channel chan, /* The channel to buffer output for. */
const char *src, /* Data to queue in output buffer. */
Tcl_Size srcLen) /* Length of data in bytes, or TCL_INDEX_NONE for
* strlen(). */
{
/*
* Always use the topmost channel of the stack
*/
Channel *chanPtr;
|
| ︙ | ︙ | |||
4157 4158 4159 4160 4161 4162 4163 |
*/
Tcl_Size
Tcl_WriteChars(
Tcl_Channel chan, /* The channel to buffer output for. */
const char *src, /* UTF-8 characters to queue in output
* buffer. */
| | | 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 |
*/
Tcl_Size
Tcl_WriteChars(
Tcl_Channel chan, /* The channel to buffer output for. */
const char *src, /* UTF-8 characters to queue in output
* buffer. */
Tcl_Size len) /* Length of string in bytes, or TCL_INDEX_NONE for
* strlen(). */
{
Channel *chanPtr = (Channel *) chan;
ChannelState *statePtr = chanPtr->state; /* State info for channel */
Tcl_Size result;
Tcl_Obj *objPtr;
|
| ︙ | ︙ | |||
4491 4492 4493 4494 4495 4496 4497 |
if (IsBufferFull(bufPtr)) {
if (FlushChannel(NULL, chanPtr, 0) != 0) {
return -1;
}
flushed += statePtr->bufSize;
/*
| | | | | | | | | | | 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 |
if (IsBufferFull(bufPtr)) {
if (FlushChannel(NULL, chanPtr, 0) != 0) {
return -1;
}
flushed += statePtr->bufSize;
/*
* We just flushed. So if we have needNlFlush set to record that
* we need to flush because there is a (translated) newline in the
* buffer, that's likely not true any more. But there is a tricky
* exception. If we have saved bytes that did not really get
* flushed and those bytes came from a translation of a newline as
* the last thing taken from the src array, then needNlFlush needs
* to remain set to flag that the next buffer still needs a
* newline flush.
*/
if (needNlFlush && (saved == 0 || src[-1] != '\n')) {
needNlFlush = 0;
}
}
}
if (((flushed < total) && GotFlag(statePtr, CHANNEL_UNBUFFERED)) ||
|
| ︙ | ︙ | |||
5702 5703 5704 5705 5706 5707 5708 |
*----------------------------------------------------------------------
*/
Tcl_Size
Tcl_Read(
Tcl_Channel chan, /* The channel from which to read. */
char *dst, /* Where to store input read. */
| | | 5703 5704 5705 5706 5707 5708 5709 5710 5711 5712 5713 5714 5715 5716 5717 |
*----------------------------------------------------------------------
*/
Tcl_Size
Tcl_Read(
Tcl_Channel chan, /* The channel from which to read. */
char *dst, /* Where to store input read. */
Tcl_Size bytesToRead) /* Maximum number of bytes to read. */
{
Channel *chanPtr = (Channel *) chan;
ChannelState *statePtr = chanPtr->state;
/* State info for channel */
/*
* This operation should occur at the top of a channel stack.
|
| ︙ | ︙ | |||
5747 5748 5749 5750 5751 5752 5753 |
*----------------------------------------------------------------------
*/
Tcl_Size
Tcl_ReadRaw(
Tcl_Channel chan, /* The channel from which to read. */
char *readBuf, /* Where to store input read. */
| | | 5748 5749 5750 5751 5752 5753 5754 5755 5756 5757 5758 5759 5760 5761 5762 |
*----------------------------------------------------------------------
*/
Tcl_Size
Tcl_ReadRaw(
Tcl_Channel chan, /* The channel from which to read. */
char *readBuf, /* Where to store input read. */
Tcl_Size bytesToRead) /* Maximum number of bytes to read. */
{
Channel *chanPtr = (Channel *) chan;
ChannelState *statePtr = chanPtr->state;
/* State info for channel */
int copied = 0;
assert(bytesToRead > 0);
|
| ︙ | ︙ | |||
6789 6790 6791 6792 6793 6794 6795 |
*----------------------------------------------------------------------
*/
Tcl_Size
Tcl_Ungets(
Tcl_Channel chan, /* The channel for which to add the input. */
const char *str, /* The input itself. */
| | | 6790 6791 6792 6793 6794 6795 6796 6797 6798 6799 6800 6801 6802 6803 6804 |
*----------------------------------------------------------------------
*/
Tcl_Size
Tcl_Ungets(
Tcl_Channel chan, /* The channel for which to add the input. */
const char *str, /* The input itself. */
Tcl_Size len, /* The length of the input. */
int atEnd) /* If non-zero, add at end of queue; otherwise
* add at head of queue. */
{
Channel *chanPtr; /* The real IO channel. */
ChannelState *statePtr; /* State of actual channel. */
ChannelBuffer *bufPtr; /* Buffer to contain the data. */
int flags;
|
| ︙ | ︙ | |||
7737 7738 7739 7740 7741 7742 7743 |
*
*----------------------------------------------------------------------
*/
void
Tcl_SetChannelBufferSize(
Tcl_Channel chan, /* The channel whose buffer size to set. */
| | | 7738 7739 7740 7741 7742 7743 7744 7745 7746 7747 7748 7749 7750 7751 7752 |
*
*----------------------------------------------------------------------
*/
void
Tcl_SetChannelBufferSize(
Tcl_Channel chan, /* The channel whose buffer size to set. */
Tcl_Size sz) /* The size to set. */
{
ChannelState *statePtr; /* State of real channel structure. */
/*
* Clip the buffer size to force it into the [1,1M] range
*/
|
| ︙ | ︙ | |||
8846 8847 8848 8849 8850 8851 8852 |
int mask, /* OR'ed combination of TCL_READABLE,
* TCL_WRITABLE, and TCL_EXCEPTION: indicates
* conditions under which proc should be
* called. Use 0 to disable a registered
* handler. */
Tcl_ChannelProc *proc, /* Procedure to call for each selected
* event. */
| | | 8847 8848 8849 8850 8851 8852 8853 8854 8855 8856 8857 8858 8859 8860 8861 |
int mask, /* OR'ed combination of TCL_READABLE,
* TCL_WRITABLE, and TCL_EXCEPTION: indicates
* conditions under which proc should be
* called. Use 0 to disable a registered
* handler. */
Tcl_ChannelProc *proc, /* Procedure to call for each selected
* event. */
void *clientData) /* Arbitrary data to pass to proc. */
{
ChannelHandler *chPtr;
Channel *chanPtr = (Channel *) chan;
ChannelState *statePtr = chanPtr->state;
/* State info for channel */
/*
|
| ︙ | ︙ | |||
8918 8919 8920 8921 8922 8923 8924 |
*/
void
Tcl_DeleteChannelHandler(
Tcl_Channel chan, /* The channel for which to remove the
* callback. */
Tcl_ChannelProc *proc, /* The procedure in the callback to delete. */
| | | 8919 8920 8921 8922 8923 8924 8925 8926 8927 8928 8929 8930 8931 8932 8933 |
*/
void
Tcl_DeleteChannelHandler(
Tcl_Channel chan, /* The channel for which to remove the
* callback. */
Tcl_ChannelProc *proc, /* The procedure in the callback to delete. */
void *clientData) /* The client data in the callback to
* delete. */
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
ChannelHandler *chPtr, *prevChPtr;
Channel *chanPtr = (Channel *) chan;
ChannelState *statePtr = chanPtr->state;
/* State info for channel */
|
| ︙ | ︙ | |||
9124 9125 9126 9127 9128 9129 9130 | * Whatever the script does. * *---------------------------------------------------------------------- */ void TclChannelEventScriptInvoker( | | | 9125 9126 9127 9128 9129 9130 9131 9132 9133 9134 9135 9136 9137 9138 9139 |
* Whatever the script does.
*
*----------------------------------------------------------------------
*/
void
TclChannelEventScriptInvoker(
void *clientData, /* The script+interp record. */
TCL_UNUSED(int) /*mask*/)
{
EventScriptRecord *esPtr = (EventScriptRecord *)clientData;
/* The event script + interpreter to eval it
* in. */
Channel *chanPtr = esPtr->chanPtr;
/* The channel for which this handler is
|
| ︙ | ︙ | |||
10010 10011 10012 10013 10014 10015 10016 | * Stores up to "bytesToRead" bytes in memory pointed to by "dst". * These bytes come from reading the channel "chanPtr" and * performing the configured translations. No encoding conversions * are applied to the bytes being read. * * Results: * The number of bytes actually stored (<= bytesToRead), | | | | | | 10011 10012 10013 10014 10015 10016 10017 10018 10019 10020 10021 10022 10023 10024 10025 10026 10027 10028 10029 10030 10031 10032 10033 10034 10035 10036 10037 10038 10039 10040 10041 10042 10043 10044 10045 10046 |
* Stores up to "bytesToRead" bytes in memory pointed to by "dst".
* These bytes come from reading the channel "chanPtr" and
* performing the configured translations. No encoding conversions
* are applied to the bytes being read.
*
* Results:
* The number of bytes actually stored (<= bytesToRead),
* or TCL_INDEX_NONE if there is an error in reading the channel. Use
* Tcl_GetErrno() to retrieve the error code for the error
* that occurred.
*
* The number of bytes stored can be less than the number
* requested when
* - EOF is reached on the channel; or
* - the channel is non-blocking, and we've read all we can
* without blocking.
* - a channel reading error occurs (and we return TCL_INDEX_NONE)
*
* Side effects:
* May cause input to be buffered.
*
*----------------------------------------------------------------------
*/
static Tcl_Size
DoRead(
Channel *chanPtr, /* The channel from which to read. */
char *dst, /* Where to store input read. */
Tcl_Size bytesToRead, /* Maximum number of bytes to read. */
int allowShortReads) /* Allow half-blocking (pipes,sockets) */
{
ChannelState *statePtr = chanPtr->state;
char *p = dst;
/*
* Early out when we know a read will get the eofchar.
|
| ︙ | ︙ | |||
10094 10095 10096 10097 10098 10099 10100 | ChannelBuffer *bufPtr = statePtr->inQueueHead; /* * Don't read more data if we have what we need. */ while (!bufPtr || /* We got no buffer! OR */ | | | 10095 10096 10097 10098 10099 10100 10101 10102 10103 10104 10105 10106 10107 10108 10109 |
ChannelBuffer *bufPtr = statePtr->inQueueHead;
/*
* Don't read more data if we have what we need.
*/
while (!bufPtr || /* We got no buffer! OR */
(!IsBufferFull(bufPtr) && /* Our buffer has room AND */
((Tcl_Size) BytesLeft(bufPtr) < bytesToRead))) {
/* Not enough bytes in it yet
* to fill the dst */
int code;
moreData:
code = GetInput(chanPtr);
|
| ︙ | ︙ |
Changes to generic/tclIO.h.
| ︙ | ︙ | |||
35 36 37 38 39 40 41 |
* Buffers data being sent to or from a channel.
*/
typedef struct ChannelBuffer {
Tcl_Size refCount; /* Current uses count */
Tcl_Size nextAdded; /* The next position into which a character
* will be put in the buffer. */
| | | | | 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
* Buffers data being sent to or from a channel.
*/
typedef struct ChannelBuffer {
Tcl_Size refCount; /* Current uses count */
Tcl_Size nextAdded; /* The next position into which a character
* will be put in the buffer. */
Tcl_Size nextRemoved; /* Position of next byte to be removed from
* the buffer. */
Tcl_Size bufLength; /* How big is the buffer? */
struct ChannelBuffer *nextPtr;
/* Next buffer in chain. */
char buf[TCLFLEXARRAY]; /* Placeholder for real buffer. The real
* buffer occupies this space + bufSize-1
* bytes. This must be the last field in the
* structure. */
} ChannelBuffer;
#define CHANNELBUFFER_HEADER_SIZE offsetof(ChannelBuffer, buf)
|
| ︙ | ︙ | |||
92 93 94 95 96 97 98 |
* data specific to the channel but which belongs to the generic part of the
* Tcl channel mechanism, and it points at an instance specific (and type
* specific) instance data, and at a channel type structure.
*/
typedef struct Channel {
struct ChannelState *state; /* Split out state information */
| | | 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
* data specific to the channel but which belongs to the generic part of the
* Tcl channel mechanism, and it points at an instance specific (and type
* specific) instance data, and at a channel type structure.
*/
typedef struct Channel {
struct ChannelState *state; /* Split out state information */
void *instanceData; /* Instance-specific data provided by creator
* of channel. */
const Tcl_ChannelType *typePtr; /* Pointer to channel type structure. */
struct Channel *downChanPtr;/* Refers to channel this one was stacked
* upon. This reference is NULL for normal
* channels. See Tcl_StackChannel. */
struct Channel *upChanPtr; /* Refers to the channel above stacked this
* one. NULL for the top most channel. */
|
| ︙ | ︙ | |||
156 157 158 159 160 161 162 |
TclEolTranslation outputTranslation;
/* What translation to use for generating end
* of line sequences in output? */
int inEofChar; /* If nonzero, use this as a signal of EOF on
* input. */
#if TCL_MAJOR_VERSION < 9
int outEofChar; /* If nonzero, append this to the channel when
| | > | 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
TclEolTranslation outputTranslation;
/* What translation to use for generating end
* of line sequences in output? */
int inEofChar; /* If nonzero, use this as a signal of EOF on
* input. */
#if TCL_MAJOR_VERSION < 9
int outEofChar; /* If nonzero, append this to the channel when
* it is closed if it is open for writing.
* For Tcl 8.x only */
#endif
int unreportedError; /* Non-zero if an error report was deferred
* because it happened in the background. The
* value is the POSIX error code. */
Tcl_Size refCount; /* How many interpreters hold references to
* this IO channel? */
struct CloseCallback *closeCbPtr;
|
| ︙ | ︙ | |||
187 188 189 190 191 192 193 |
* handlers for. */
EventScriptRecord *scriptRecordPtr;
/* Chain of all scripts registered for event
* handlers ("fileevent") on this channel. */
Tcl_Size bufSize; /* What size buffers to allocate? */
Tcl_TimerToken timer; /* Handle to wakeup timer for this channel. */
Channel *timerChanPtr; /* Needed in order to decrement the refCount of
| | | | 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
* handlers for. */
EventScriptRecord *scriptRecordPtr;
/* Chain of all scripts registered for event
* handlers ("fileevent") on this channel. */
Tcl_Size bufSize; /* What size buffers to allocate? */
Tcl_TimerToken timer; /* Handle to wakeup timer for this channel. */
Channel *timerChanPtr; /* Needed in order to decrement the refCount of
* the right channel when the timer is
* deleted. */
struct CopyState *csPtrR; /* State of background copy for which channel
* is input, or NULL. */
struct CopyState *csPtrW; /* State of background copy for which channel
* is output, or NULL. */
Channel *topChanPtr; /* Refers to topmost channel in a stack. Never
* NULL. */
Channel *bottomChanPtr; /* Refers to bottommost channel in a stack.
|
| ︙ | ︙ | |||
210 211 212 213 214 215 216 |
/*
* TIP #219 ... Info for the I/O system ...
* Error message set by channel drivers, for the propagation of arbitrary
* Tcl errors. This information, if present (chanMsg not NULL), takes
* precedence over a Posix error code returned by a channel operation.
*/
| | | | 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 |
/*
* TIP #219 ... Info for the I/O system ...
* Error message set by channel drivers, for the propagation of arbitrary
* Tcl errors. This information, if present (chanMsg not NULL), takes
* precedence over a Posix error code returned by a channel operation.
*/
Tcl_Obj *chanMsg;
Tcl_Obj *unreportedMsg; /* Non-NULL if an error report was deferred
* because it happened in the background. The
* value is the chanMg, if any. #219's
* companion to 'unreportedError'. */
size_t epoch; /* Used to test validity of stored channelname
* lookup results. */
int maxPerms; /* TIP #220: Max access privileges
* the channel was created with. */
|
| ︙ | ︙ |
Changes to generic/tclIOCmd.c.
| ︙ | ︙ | |||
34 35 36 37 38 39 40 | static Tcl_ThreadDataKey dataKey; /* * Static functions for this file: */ static Tcl_ExitProc FinalizeIOCmdTSD; | | | 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | static Tcl_ThreadDataKey dataKey; /* * Static functions for this file: */ 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 Tcl_InterpDeleteProc TcpAcceptCallbacksDeleteProc; static void TcpServerCloseProc(void *callbackData); |
| ︙ | ︙ | |||
364 365 366 367 368 369 370 |
TCL_UNUSED(void *),
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
Tcl_Channel chan; /* The channel to read from. */
int newline, i; /* Discard newline at end? */
| | | | 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 |
TCL_UNUSED(void *),
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
Tcl_Channel chan; /* The channel to read from. */
int newline, i; /* Discard newline at end? */
Tcl_WideInt toRead; /* How many bytes to read? */
Tcl_Size charactersRead; /* How many characters were read? */
int mode; /* Mode in which channel is opened. */
Tcl_Obj *resultPtr, *chanObjPtr;
if ((objc != 2) && (objc != 3)) {
Interp *iPtr;
argerror:
|
| ︙ | ︙ | |||
1195 1196 1197 1198 1199 1200 1201 | * subsequently to eval accept scripts. * *---------------------------------------------------------------------- */ static void TcpAcceptCallbacksDeleteProc( | | | 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 |
* subsequently to eval accept scripts.
*
*----------------------------------------------------------------------
*/
static void
TcpAcceptCallbacksDeleteProc(
void *clientData, /* Data which was passed when the assocdata
* was registered. */
TCL_UNUSED(Tcl_Interp *))
{
Tcl_HashTable *hTblPtr = (Tcl_HashTable *)clientData;
Tcl_HashEntry *hPtr;
Tcl_HashSearch hSearch;
|
| ︙ | ︙ | |||
1323 1324 1325 1326 1327 1328 1329 | * Whatever the script does. * *---------------------------------------------------------------------- */ static void AcceptCallbackProc( | | | 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 |
* Whatever the script does.
*
*----------------------------------------------------------------------
*/
static void
AcceptCallbackProc(
void *callbackData, /* The data stored when the callback was
* created in the call to
* Tcl_OpenTcpServer. */
Tcl_Channel chan, /* Channel for the newly accepted
* connection. */
char *address, /* Address of client that was accepted. */
int port) /* Port of client that was accepted. */
{
|
| ︙ | ︙ | |||
1414 1415 1416 1417 1418 1419 1420 | * longer be informed. * *---------------------------------------------------------------------- */ static void TcpServerCloseProc( | | | 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 |
* longer be informed.
*
*----------------------------------------------------------------------
*/
static void
TcpServerCloseProc(
void *callbackData) /* The data passed in the call to
* Tcl_CreateCloseHandler. */
{
AcceptCallback *acceptCallbackPtr = (AcceptCallback *)callbackData;
/* The actual data. */
if (acceptCallbackPtr->interp != NULL) {
UnregisterTcpServerInterpCleanupProc(acceptCallbackPtr->interp,
|
| ︙ | ︙ |
Changes to generic/tclIOGT.c.
| ︙ | ︙ | |||
511 512 513 514 515 516 517 | * 0 if successful, errno when failed. * *---------------------------------------------------------------------- */ static int TransformBlockModeProc( | | | 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 |
* 0 if successful, errno when failed.
*
*----------------------------------------------------------------------
*/
static int
TransformBlockModeProc(
void *instanceData, /* State of transformation. */
int mode) /* New blocking mode. */
{
TransformChannelData *dataPtr = (TransformChannelData *)instanceData;
if (mode == TCL_MODE_NONBLOCKING) {
dataPtr->flags |= CHANNEL_ASYNC;
} else {
|
| ︙ | ︙ | |||
545 546 547 548 549 550 551 |
*----------------------------------------------------------------------
*/
static int
TransformCloseProc(
void *instanceData,
Tcl_Interp *interp,
| | | 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 |
*----------------------------------------------------------------------
*/
static int
TransformCloseProc(
void *instanceData,
Tcl_Interp *interp,
int flags)
{
TransformChannelData *dataPtr = (TransformChannelData *)instanceData;
if ((flags & (TCL_CLOSE_READ | TCL_CLOSE_WRITE)) != 0) {
return EINVAL;
}
|
| ︙ | ︙ | |||
846 847 848 849 850 851 852 | * contains the POSIX error code if an error occurred, or zero. * *---------------------------------------------------------------------- */ static long long TransformWideSeekProc( | | | 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 |
* contains the POSIX error code if an error occurred, or zero.
*
*----------------------------------------------------------------------
*/
static long long
TransformWideSeekProc(
void *instanceData, /* The channel to manipulate. */
long long offset, /* Size of movement. */
int mode, /* How to move. */
int *errorCodePtr) /* Location of error flag. */
{
TransformChannelData *dataPtr = (TransformChannelData *)instanceData;
Tcl_Channel parent = Tcl_GetStackedChannel(dataPtr->self);
const Tcl_ChannelType *parentType = Tcl_GetChannelType(parent);
|
| ︙ | ︙ | |||
1009 1010 1011 1012 1013 1014 1015 | * None. * *---------------------------------------------------------------------- */ static void TransformWatchProc( | | | 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 |
* None.
*
*----------------------------------------------------------------------
*/
static void
TransformWatchProc(
void *instanceData, /* Channel to watch. */
int mask) /* Events of interest. */
{
TransformChannelData *dataPtr = (TransformChannelData *)instanceData;
Tcl_Channel downChan;
/*
* The caller expressed interest in events occurring for this channel. We
|
| ︙ | ︙ | |||
1087 1088 1089 1090 1091 1092 1093 | * The appropriate Tcl_File or NULL if not present. * *---------------------------------------------------------------------- */ static int TransformGetFileHandleProc( | | | | 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 |
* The appropriate Tcl_File or NULL if not present.
*
*----------------------------------------------------------------------
*/
static int
TransformGetFileHandleProc(
void *instanceData, /* Channel to query. */
int direction, /* Direction of interest. */
void **handlePtr) /* Place to store the handle into. */
{
TransformChannelData *dataPtr = (TransformChannelData *)instanceData;
/*
* Return the handle belonging to parent channel. IOW, pass the request
* down and the result up.
*/
|
| ︙ | ︙ | |||
1121 1122 1123 1124 1125 1126 1127 | * None. * *---------------------------------------------------------------------- */ static int TransformNotifyProc( | | | 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 |
* None.
*
*----------------------------------------------------------------------
*/
static int
TransformNotifyProc(
void *clientData, /* The state of the notified
* transformation. */
int mask) /* The mask of occurring events. */
{
TransformChannelData *dataPtr = (TransformChannelData *)clientData;
/*
* An event occurred in the underlying channel. This transformation doesn't
|
| ︙ | ︙ | |||
1166 1167 1168 1169 1170 1171 1172 | * None. * *---------------------------------------------------------------------- */ static void TransformChannelHandlerTimer( | | | 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 |
* None.
*
*----------------------------------------------------------------------
*/
static void
TransformChannelHandlerTimer(
void *clientData) /* Transformation to query. */
{
TransformChannelData *dataPtr = (TransformChannelData *)clientData;
dataPtr->timer = NULL;
if (!(dataPtr->watchMask&TCL_READABLE) || ResultEmpty(&dataPtr->result)) {
/*
* The timer fired, but either is there no (more) interest in the
|
| ︙ | ︙ |
Changes to generic/tclIORChan.c.
| ︙ | ︙ | |||
60 61 62 63 64 65 66 |
/*
* The C layer channel type/driver definition used by the reflection.
*/
static const Tcl_ChannelType tclRChannelType = {
"tclrchannel", /* Type name. */
TCL_CHANNEL_VERSION_5, /* v5 channel */
| | | 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
/*
* The C layer channel type/driver definition used by the reflection.
*/
static const Tcl_ChannelType tclRChannelType = {
"tclrchannel", /* Type name. */
TCL_CHANNEL_VERSION_5, /* v5 channel */
NULL, /* Close channel, clean instance data */
ReflectInput, /* Handle read request */
ReflectOutput, /* Handle write request */
NULL,
ReflectSetOption, /* Set options. NULL'able */
ReflectGetOption, /* Get options. NULL'able */
ReflectWatch, /* Initialize notifier */
NULL, /* Get OS handle from the channel. NULL'able */
|
| ︙ | ︙ | |||
92 93 94 95 96 97 98 |
typedef struct {
Tcl_Channel chan; /* Back reference to generic channel
* structure. */
Tcl_Interp *interp; /* Reference to the interpreter containing the
* Tcl level part of the channel. NULL here
* signals the channel is dead because the
* interpreter/thread containing its Tcl
| | < | < | | < | < | | < | 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
typedef struct {
Tcl_Channel chan; /* Back reference to generic channel
* structure. */
Tcl_Interp *interp; /* Reference to the interpreter containing the
* Tcl level part of the channel. NULL here
* signals the channel is dead because the
* 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 */
#endif
Tcl_Obj *cmd; /* Callback command prefix */
Tcl_Obj *methods; /* Methods to append to command prefix */
Tcl_Obj *name; /* Name of the channel as created */
int mode; /* Mask of R/W mode */
int interest; /* Mask of events the channel is interested
* in. */
int dead; /* Boolean signal that some operations
* should no longer be attempted. */
Tcl_TimerToken readTimer; /* A token for the timer that is scheduled in
* order to call Tcl_NotifyChannel when the
* channel is readable. */
Tcl_TimerToken writeTimer; /* A token for the timer that is scheduled in
* order to call Tcl_NotifyChannel when the
* channel is writable. */
/*
* Note regarding the usage of timers.
*
* Most channel implementations need a timer in the C level to ensure that
* data in buffers is flushed out through the generation of fake file
* events.
|
| ︙ | ︙ | |||
262 263 264 265 266 267 268 |
* ForwardParamBase. Where an operation does not need any special types, it
* has no "subtype" and just uses ForwardParamBase, as listed above.)
*/
struct ForwardParamInput {
ForwardParamBase base; /* "Supertype". MUST COME FIRST. */
char *buf; /* O: Where to store the read bytes */
| | | 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 |
* ForwardParamBase. Where an operation does not need any special types, it
* has no "subtype" and just uses ForwardParamBase, as listed above.)
*/
struct ForwardParamInput {
ForwardParamBase base; /* "Supertype". MUST COME FIRST. */
char *buf; /* O: Where to store the read bytes */
Tcl_Size toRead; /* I: #bytes to read,
* O: #bytes actually read */
};
struct ForwardParamOutput {
ForwardParamBase base; /* "Supertype". MUST COME FIRST. */
const char *buf; /* I: Where the bytes to write come from */
Tcl_Size toWrite; /* I: #bytes to write,
* O: #bytes actually written */
|
| ︙ | ︙ | |||
399 400 401 402 403 404 405 | static void ForwardOpToHandlerThread(ReflectedChannel *rcPtr, ForwardedOperation op, const void *param); static int ForwardProc(Tcl_Event *evPtr, int mask); static void SrcExitProc(void *clientData); #define FreeReceivedError(p) \ | | | | | | | | | | | | | | | 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 |
static void ForwardOpToHandlerThread(ReflectedChannel *rcPtr,
ForwardedOperation op, const void *param);
static int ForwardProc(Tcl_Event *evPtr, int mask);
static void SrcExitProc(void *clientData);
#define FreeReceivedError(p) \
if ((p)->base.mustFree) { \
Tcl_Free((p)->base.msgStr); \
}
#define PassReceivedErrorInterp(i, p) \
if ((i) != NULL) { \
Tcl_SetChannelErrorInterp((i), \
Tcl_NewStringObj((p)->base.msgStr, -1)); \
} \
FreeReceivedError(p)
#define PassReceivedError(c,p) \
Tcl_SetChannelError((c), Tcl_NewStringObj((p)->base.msgStr, -1)); \
FreeReceivedError(p)
#define ForwardSetStaticError(p, emsg) \
(p)->base.code = TCL_ERROR; \
(p)->base.mustFree = 0; \
(p)->base.msgStr = (char *) (emsg)
#define ForwardSetDynamicError(p, emsg) \
(p)->base.code = TCL_ERROR; \
(p)->base.mustFree = 1; \
(p)->base.msgStr = (char *) (emsg)
static void ForwardSetObjError(ForwardParam *p, Tcl_Obj *objPtr);
static ReflectedChannelMap * GetThreadReflectedChannelMap(void);
static Tcl_ExitProc DeleteThreadReflectedChannelMap;
|
| ︙ | ︙ | |||
509 510 511 512 513 514 515 |
Tcl_Obj *rcId; /* Handle of the new channel */
int mode; /* R/W mode of new channel. Has to match
* abilities of handler commands */
Tcl_Obj *cmdObj; /* Command prefix, list of words */
Tcl_Obj *cmdNameObj; /* Command name */
Tcl_Channel chan; /* Token for the new channel */
Tcl_Obj *modeObj; /* mode in obj form for method call */
| | | 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 |
Tcl_Obj *rcId; /* Handle of the new channel */
int mode; /* R/W mode of new channel. Has to match
* abilities of handler commands */
Tcl_Obj *cmdObj; /* Command prefix, list of words */
Tcl_Obj *cmdNameObj; /* Command name */
Tcl_Channel chan; /* Token for the new channel */
Tcl_Obj *modeObj; /* mode in obj form for method call */
Tcl_Size listc; /* Result of 'initialize', and of */
Tcl_Obj **listv; /* its sublist in the 2nd element */
int methIndex; /* Encoded method name */
int result; /* Result code for 'initialize' */
Tcl_Obj *resObj; /* Result data for 'initialize' */
int methods; /* Bitmask for supported methods. */
Channel *chanPtr; /* 'chan' resolved to internal struct. */
Tcl_Obj *err; /* Error message */
|
| ︙ | ︙ | |||
1165 1166 1167 1168 1169 1170 1171 |
*----------------------------------------------------------------------
*/
static int
ReflectClose(
void *clientData,
Tcl_Interp *interp,
| | | 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 |
*----------------------------------------------------------------------
*/
static int
ReflectClose(
void *clientData,
Tcl_Interp *interp,
int flags)
{
ReflectedChannel *rcPtr = (ReflectedChannel *)clientData;
int result; /* Result code for 'close' */
Tcl_Obj *resObj; /* Result data for 'close' */
ReflectedChannelMap *rcmPtr;/* Map of reflected channels with handlers in
* this interp */
Tcl_HashEntry *hPtr; /* Entry in the above map */
|
| ︙ | ︙ | |||
1831 1832 1833 1834 1835 1836 1837 | * Arbitrary, as it calls upon a Tcl script. * *---------------------------------------------------------------------- */ static int ReflectSetOption( | | | 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 |
* Arbitrary, as it calls upon a Tcl script.
*
*----------------------------------------------------------------------
*/
static int
ReflectSetOption(
void *clientData, /* Channel to query */
Tcl_Interp *interp, /* Interpreter to leave error messages in */
const char *optionName, /* Name of requested option */
const char *newValue) /* The new value */
{
ReflectedChannel *rcPtr = (ReflectedChannel *)clientData;
Tcl_Obj *optionObj, *valueObj;
int result; /* Result code for 'configure' */
|
| ︙ | ︙ | |||
1903 1904 1905 1906 1907 1908 1909 | * Arbitrary, as it calls upon a Tcl script. * *---------------------------------------------------------------------- */ static int ReflectGetOption( | | | 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 |
* Arbitrary, as it calls upon a Tcl script.
*
*----------------------------------------------------------------------
*/
static int
ReflectGetOption(
void *clientData, /* Channel to query */
Tcl_Interp *interp, /* Interpreter to leave error messages in */
const char *optionName, /* Name of reuqested option */
Tcl_DString *dsPtr) /* String to place the result into */
{
/*
* This code is special. It has regular passing of Tcl result, and errors.
* The bypass functions are not required.
|
| ︙ | ︙ | |||
2056 2057 2058 2059 2060 2061 2062 | * Arbitrary, as it calls upon a Tcl script. * *---------------------------------------------------------------------- */ static int ReflectTruncate( | | | 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 |
* Arbitrary, as it calls upon a Tcl script.
*
*----------------------------------------------------------------------
*/
static int
ReflectTruncate(
void *clientData, /* Channel to query */
long long length) /* Length to truncate to. */
{
ReflectedChannel *rcPtr = (ReflectedChannel *)clientData;
Tcl_Obj *lenObj;
int errorNum; /* EINVAL or EOK (success). */
Tcl_Obj *resObj; /* Result for 'truncate' */
|
| ︙ | ︙ | |||
2139 2140 2141 2142 2143 2144 2145 |
EncodeEventMask(
Tcl_Interp *interp,
const char *objName,
Tcl_Obj *obj,
int *mask)
{
int events; /* Mask of events to post */
| | | 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 |
EncodeEventMask(
Tcl_Interp *interp,
const char *objName,
Tcl_Obj *obj,
int *mask)
{
int events; /* Mask of events to post */
Tcl_Size listc; /* #elements in eventspec list */
Tcl_Obj **listv; /* Elements of eventspec list */
int evIndex; /* Id of event for an element of the eventspec
* list. */
if (TclListObjGetElementsM(interp, obj, &listc, &listv) != TCL_OK) {
return TCL_ERROR;
}
|
| ︙ | ︙ | |||
2615 2616 2617 2618 2619 2620 2621 |
rcPtr->cmd = NULL;
}
rcPtr->dead = 1;
}
static void
DeleteReflectedChannelMap(
| | | | | 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 |
rcPtr->cmd = NULL;
}
rcPtr->dead = 1;
}
static void
DeleteReflectedChannelMap(
void *clientData, /* The per-interpreter data structure. */
Tcl_Interp *interp) /* The interpreter being deleted. */
{
ReflectedChannelMap *rcmPtr = (ReflectedChannelMap *)clientData;
/* The map */
Tcl_HashSearch hSearch; /* Search variable. */
Tcl_HashEntry *hPtr; /* Search variable. */
ReflectedChannel *rcPtr;
Tcl_Channel chan;
#if TCL_THREADS
ForwardingResult *resultPtr;
ForwardingEvent *evPtr;
ForwardParam *paramPtr;
#endif
|
| ︙ | ︙ | |||
2766 2767 2768 2769 2770 2771 2772 |
static ReflectedChannelMap *
GetThreadReflectedChannelMap(void)
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
if (!tsdPtr->rcmPtr) {
| | > | 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 |
static ReflectedChannelMap *
GetThreadReflectedChannelMap(void)
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
if (!tsdPtr->rcmPtr) {
tsdPtr->rcmPtr = (ReflectedChannelMap *)
Tcl_Alloc(sizeof(ReflectedChannelMap));
Tcl_InitHashTable(&tsdPtr->rcmPtr->map, TCL_STRING_KEYS);
Tcl_CreateThreadExitHandler(DeleteThreadReflectedChannelMap, NULL);
}
return tsdPtr->rcmPtr;
}
|
| ︙ | ︙ | |||
2885 2886 2887 2888 2889 2890 2891 |
*/
rcmPtr = GetThreadReflectedChannelMap();
tsdPtr->rcmPtr = NULL;
for (hPtr = Tcl_FirstHashEntry(&rcmPtr->map, &hSearch);
hPtr != NULL;
hPtr = Tcl_FirstHashEntry(&rcmPtr->map, &hSearch)) {
| | | > | 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 |
*/
rcmPtr = GetThreadReflectedChannelMap();
tsdPtr->rcmPtr = NULL;
for (hPtr = Tcl_FirstHashEntry(&rcmPtr->map, &hSearch);
hPtr != NULL;
hPtr = Tcl_FirstHashEntry(&rcmPtr->map, &hSearch)) {
Tcl_Channel chan = (Tcl_Channel) Tcl_GetHashValue(hPtr);
ReflectedChannel *rcPtr = (ReflectedChannel *)
Tcl_GetChannelInstanceData(chan);
MarkDead(rcPtr);
Tcl_DeleteHashEntry(hPtr);
}
Tcl_Free(rcmPtr);
}
|
| ︙ | ︙ | |||
2931 2932 2933 2934 2935 2936 2937 |
return;
}
/*
* Create and initialize the event and data structures.
*/
| | | | 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 |
return;
}
/*
* Create and initialize the event and data structures.
*/
evPtr = (ForwardingEvent *) Tcl_Alloc(sizeof(ForwardingEvent));
resultPtr = (ForwardingResult *) Tcl_Alloc(sizeof(ForwardingResult));
evPtr->event.proc = ForwardProc;
evPtr->resultPtr = resultPtr;
evPtr->op = op;
evPtr->rcPtr = rcPtr;
evPtr->param = (ForwardParam *) param;
|
| ︙ | ︙ |
Changes to generic/tclIORTrans.c.
| ︙ | ︙ | |||
507 508 509 510 511 512 513 |
int mode; /* R/W mode of parent, later the new channel.
* Has to match the abilities of the handler
* commands */
Tcl_Obj *cmdObj; /* Command prefix, list of words */
Tcl_Obj *cmdNameObj; /* Command name */
Tcl_Obj *rtId; /* Handle of the new transform (channel) */
Tcl_Obj *modeObj; /* mode in obj form for method call */
| | | 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 |
int mode; /* R/W mode of parent, later the new channel.
* Has to match the abilities of the handler
* commands */
Tcl_Obj *cmdObj; /* Command prefix, list of words */
Tcl_Obj *cmdNameObj; /* Command name */
Tcl_Obj *rtId; /* Handle of the new transform (channel) */
Tcl_Obj *modeObj; /* mode in obj form for method call */
Tcl_Size listc; /* Result of 'initialize', and of */
Tcl_Obj **listv; /* its sublist in the 2nd element */
int methIndex; /* Encoded method name */
int result; /* Result code for 'initialize' */
Tcl_Obj *resObj; /* Result data for 'initialize' */
int methods; /* Bitmask for supported methods. */
ReflectedTransformMap *rtmPtr;
/* Map of reflected transforms with handlers
|
| ︙ | ︙ | |||
1373 1374 1375 1376 1377 1378 1379 |
* non-NULL...
*/
if (Tcl_ChannelWideSeekProc(parent->typePtr) == NULL) {
*errorCodePtr = EINVAL;
curPos = -1;
} else {
| | | | 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 |
* non-NULL...
*/
if (Tcl_ChannelWideSeekProc(parent->typePtr) == NULL) {
*errorCodePtr = EINVAL;
curPos = -1;
} else {
curPos = Tcl_ChannelWideSeekProc(parent->typePtr)(parent->instanceData, offset,
seekMode, errorCodePtr);
}
if (curPos == -1) {
Tcl_SetErrno(*errorCodePtr);
}
*errorCodePtr = EOK;
Tcl_Release(rtPtr);
|
| ︙ | ︙ | |||
1488 1489 1490 1491 1492 1493 1494 | * Arbitrary, per the parent channel. * *---------------------------------------------------------------------- */ static int ReflectSetOption( | | | 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 |
* Arbitrary, per the parent channel.
*
*----------------------------------------------------------------------
*/
static int
ReflectSetOption(
void *clientData, /* Channel to query */
Tcl_Interp *interp, /* Interpreter to leave error messages in */
const char *optionName, /* Name of requested option */
const char *newValue) /* The new value */
{
ReflectedTransform *rtPtr = (ReflectedTransform *)clientData;
/*
|
| ︙ | ︙ | |||
1530 1531 1532 1533 1534 1535 1536 | * Arbitrary, per the parent channel. * *---------------------------------------------------------------------- */ static int ReflectGetOption( | | | 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 |
* Arbitrary, per the parent channel.
*
*----------------------------------------------------------------------
*/
static int
ReflectGetOption(
void *clientData, /* Channel to query */
Tcl_Interp *interp, /* Interpreter to leave error messages in */
const char *optionName, /* Name of requested option */
Tcl_DString *dsPtr) /* String to place the result into */
{
ReflectedTransform *rtPtr = (ReflectedTransform *)clientData;
/*
|
| ︙ | ︙ | |||
2104 2105 2106 2107 2108 2109 2110 | * registered in this interpreter. * *---------------------------------------------------------------------- */ static void DeleteReflectedTransformMap( | | | 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 |
* registered in this interpreter.
*
*----------------------------------------------------------------------
*/
static void
DeleteReflectedTransformMap(
void *clientData, /* The per-interpreter data structure. */
Tcl_Interp *interp) /* The interpreter being deleted. */
{
ReflectedTransformMap *rtmPtr; /* The map */
Tcl_HashSearch hSearch; /* Search variable. */
Tcl_HashEntry *hPtr; /* Search variable. */
ReflectedTransform *rtPtr;
#if TCL_THREADS
|
| ︙ | ︙ |
Changes to generic/tclIOUtil.c.
| ︙ | ︙ | |||
30 31 32 33 34 35 36 |
/*
* struct FilesystemRecord --
*
* An item in a linked list of registered filesystems
*/
typedef struct FilesystemRecord {
| | > > | < | < | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
/*
* struct FilesystemRecord --
*
* An item in a linked list of registered filesystems
*/
typedef struct FilesystemRecord {
void *clientData; /* Client-specific data for the filesystem
* (can be NULL) */
const Tcl_Filesystem *fsPtr;/* Pointer to filesystem dispatch table. */
struct FilesystemRecord *nextPtr;
/* The next registered filesystem, or NULL to
* indicate the end of the list. */
struct FilesystemRecord *prevPtr;
/* The previous filesystem, or NULL to indicate
* the ned of the list */
} FilesystemRecord;
/*
* Cache of CWD info per thread so we don't need to hold a global lock so
* often.
*/
typedef struct {
int initialized;
size_t cwdPathEpoch; /* Compared with the global cwdPathEpoch to
* determine whether cwdPathPtr is stale. */
size_t filesystemEpoch;
Tcl_Obj *cwdPathPtr; /* A private copy of cwdPathPtr. Updated when
* the value is accessed and cwdPathEpoch has
* changed. */
void *cwdClientData;
FilesystemRecord *filesystemList;
size_t claims;
} ThreadSpecificData;
/*
* Forward declarations.
|
| ︙ | ︙ | |||
196 197 198 199 200 201 202 | */ static size_t theFilesystemEpoch = 1; /* * The linked list of filesystems. To minimize locking each thread maintains a * local copy of this list. | < | 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | */ static size_t theFilesystemEpoch = 1; /* * The linked list of filesystems. To minimize locking each thread maintains a * local copy of this list. */ static FilesystemRecord *filesystemList = &nativeFilesystemRecord; TCL_DECLARE_MUTEX(filesystemMutex) /* * A files-system indepent sense of the current directory. |
| ︙ | ︙ | |||
324 325 326 327 328 329 330 |
}
return ret;
}
/* Obsolete */
int
Tcl_Access(
| | | | 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 |
}
return ret;
}
/* Obsolete */
int
Tcl_Access(
const char *path, /* Pathname of file to access (in
* current CP). */
int mode) /* Permission setting. */
{
int ret;
Tcl_Obj *pathPtr = Tcl_NewStringObj(path,-1);
Tcl_IncrRefCount(pathPtr);
ret = Tcl_FSAccess(pathPtr,mode);
|
| ︙ | ︙ | |||
455 456 457 458 459 460 461 |
return 1;
} else {
return 0;
}
}
/*
| | > | | 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 |
return 1;
} else {
return 0;
}
}
/*
* ----------------------------------------------------------------------
*
* TclFSCwdPointerEquals --
* Determine whether the given pathname is equal to the current working
* directory.
*
* Results:
* 1 if equal, 0 otherwise.
*
* Side effects:
* Updates TSD if needed.
*
* Stores a pointer to the current directory in *pathPtrPtr if it is not
* already there and the current directory is not NULL.
*
* If *pathPtrPtr is not null its reference count is decremented
* before it is replaced.
*
* ----------------------------------------------------------------------
*/
int
TclFSCwdPointerEquals(
Tcl_Obj **pathPtrPtr)
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey);
|
| ︙ | ︙ | |||
712 713 714 715 716 717 718 |
tsdPtr->cwdPathPtr = Tcl_NewStringObj(str, len);
tsdPtr->cwdClientData = clientData;
Tcl_IncrRefCount(tsdPtr->cwdPathPtr);
}
}
/*
| | | | | 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 |
tsdPtr->cwdPathPtr = Tcl_NewStringObj(str, len);
tsdPtr->cwdClientData = clientData;
Tcl_IncrRefCount(tsdPtr->cwdPathPtr);
}
}
/*
* ----------------------------------------------------------------------
*
* TclFinalizeFilesystem --
*
* Clean up the filesystem. After this, any call to a Tcl_FS... function
* fails.
*
* If TclResetFilesystem is called later, it restores the filesystem to a
* pristine state.
*
* Results:
* None.
*
* Side effects:
* Frees memory allocated for the filesystem.
*
* ----------------------------------------------------------------------
*/
void
TclFinalizeFilesystem(void)
{
FilesystemRecord *fsRecPtr;
/*
* Assume that only one thread is active. Otherwise mutexes would be needed
* around this code.
* TODO: This assumption is false, isn't it?
*/
if (cwdPathPtr != NULL) {
Tcl_DecrRefCount(cwdPathPtr);
cwdPathPtr = NULL;
cwdPathEpoch = 0;
}
|
| ︙ | ︙ | |||
840 841 842 843 844 845 846 | * registered filesystems. * *---------------------------------------------------------------------- */ int Tcl_FSRegister( | | | 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 |
* registered filesystems.
*
*----------------------------------------------------------------------
*/
int
Tcl_FSRegister(
void *clientData, /* Client-specific data for this filesystem. */
const Tcl_Filesystem *fsPtr)/* The filesystem record for the new fs. */
{
FilesystemRecord *newFilesystemPtr;
if (fsPtr == NULL) {
return TCL_ERROR;
}
|
| ︙ | ︙ | |||
1095 1096 1097 1098 1099 1100 1101 | * Stores a result in resultPtr. * *---------------------------------------------------------------------- */ static void FsAddMountsToGlobResult( | | | | | | | 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 |
* Stores a result in resultPtr.
*
*----------------------------------------------------------------------
*/
static void
FsAddMountsToGlobResult(
Tcl_Obj *resultPtr, /* The current list of matching pathnames.
* Must not be shared. */
Tcl_Obj *pathPtr, /* The directory that was searched. */
const char *pattern, /* Pattern to match mounts against. */
Tcl_GlobTypeData *types) /* Acceptable types. May be NULL. The
* directory flag is particularly
* significant. */
{
Tcl_Size mLength, gLength, i;
int dir = (types == NULL || (types->type & TCL_GLOB_TYPE_DIR));
Tcl_Obj *mounts = FsListMounts(pathPtr, pattern);
if (mounts == NULL) {
return;
|
| ︙ | ︙ | |||
1146 1147 1148 1149 1150 1151 1152 |
}
}
if (!found && dir) {
Tcl_Obj *norm;
Tcl_Size len, mlen;
/*
| | | | | 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 |
}
}
if (!found && dir) {
Tcl_Obj *norm;
Tcl_Size len, mlen;
/*
* mElt is normalized and lies inside pathPtr so add to the
* result the right representation of mElt, i.e. the
* representation relative to pathPtr.
*/
norm = Tcl_FSGetNormalizedPath(NULL, pathPtr);
if (norm != NULL) {
const char *path, *mount;
mount = Tcl_GetStringFromObj(mElt, &mlen);
|
| ︙ | ︙ | |||
2905 2906 2907 2908 2909 2910 2911 |
}
}
} else {
Tcl_SetErrno(ENOENT);
}
if (retVal == 0) {
| < | 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 |
}
}
} else {
Tcl_SetErrno(ENOENT);
}
if (retVal == 0) {
/* Assume that the cwd was actually changed to the normalized value
* just calculated, and cache that information. */
/*
* If the filesystem epoch changed recently, the normalized pathname or
* its internal handle may be different from what was found above.
* This can easily be the case with scripted documents . Therefore get
|
| ︙ | ︙ | |||
3008 3009 3010 3011 3012 3013 3014 |
*
*----------------------------------------------------------------------
*/
int
Tcl_FSLoadFile(
Tcl_Interp *interp, /* Used for error reporting. */
| | | | 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 |
*
*----------------------------------------------------------------------
*/
int
Tcl_FSLoadFile(
Tcl_Interp *interp, /* Used for error reporting. */
Tcl_Obj *pathPtr, /* Pathname of the file containing the dynamic
* shared object. */
const char *sym1, const char *sym2,
/* Names of two functions to find in the
* dynamic shared object. */
Tcl_LibraryInitProc **proc1Ptr, Tcl_LibraryInitProc **proc2Ptr,
/* Places to store pointers to the functions
* named by sym1 and sym2. */
Tcl_LoadHandle *handlePtr, /* A place to store the token for the loaded
|
| ︙ | ︙ | |||
3078 3079 3080 3081 3082 3083 3084 | * from getting properly loaded. Only the first is ok. Work around the issue * by not unlinking, i.e., emulating the behaviour of the older HPUX which * denied removal. * * Doing the unlink is also an issue within docker containers, whose AUFS * bungles this as well, see * https://github.com/dotcloud/docker/issues/1911 | < < | | < | < > < > | | | > | | | | 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 |
* from getting properly loaded. Only the first is ok. Work around the issue
* by not unlinking, i.e., emulating the behaviour of the older HPUX which
* denied removal.
*
* Doing the unlink is also an issue within docker containers, whose AUFS
* bungles this as well, see
* https://github.com/dotcloud/docker/issues/1911
*/
#ifdef _WIN32
#define getenv(x) _wgetenv(L##x)
#define atoi(x) _wtoi(x)
#else
#define WCHAR char
#endif
static int
skipUnlink(
Tcl_Obj *shlibFile)
{
/*
* Unlinking is not performed in the following cases:
*
* 1. The operating system is HPUX.
* 2. If the environment variable TCL_TEMPLOAD_NO_UNLINK is present and
* set to true (an integer > 0)
* 3. TCL_TEMPLOAD_NO_UNLINK is not true (an integer > 0) and AUFS
* filesystem can be detected (using statfs, if available).
*/
#ifdef hpux
(void)shlibFile;
return 1;
#else
WCHAR *skipstr = getenv("TCL_TEMPLOAD_NO_UNLINK");
if (skipstr && (skipstr[0] != '\0')) {
return atoi(skipstr);
}
#ifndef TCL_TEMPLOAD_NO_UNLINK
(void)shlibFile;
#else
/*
* At built time TCL_TEMPLOAD_NO_UNLINK can be set manually to control
* whether this automatic overriding of unlink is included.
*/
#ifndef NO_FSTATFS
{
struct statfs fs;
/*
* Have fstatfs. May not have the AUFS super magic ... Indeed our build
* box is too old to have it directly in the headers. Define taken from
* http://mooon.googlecode.com/svn/trunk/linux_include/linux/aufs_type.h
* http://aufs.sourceforge.net/
* Better reference will be gladly accepted.
*/
#ifndef AUFS_SUPER_MAGIC
/*
* AUFS_SUPER_MAGIC can disable/override the AUFS detection, i.e. for
* testing if a newer AUFS does not have the bug any more.
*/
#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's')
#endif /* AUFS_SUPER_MAGIC */
if ((statfs(TclGetString(shlibFile), &fs) == 0)
&& (fs.f_type == AUFS_SUPER_MAGIC)) {
return 1;
}
}
|
| ︙ | ︙ | |||
3458 3459 3460 3461 3462 3463 3464 | * from the virtual filesystem to a native filesystem. * *---------------------------------------------------------------------- */ static void * DivertFindSymbol( | | | 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 |
* from the virtual filesystem to a native filesystem.
*
*----------------------------------------------------------------------
*/
static void *
DivertFindSymbol(
Tcl_Interp *interp, /* The relevant interpreter. */
Tcl_LoadHandle loadHandle, /* A handle to the diverted module. */
const char *symbol) /* The name of symbol to resolve. */
{
FsDivertLoad *tvdlPtr = (FsDivertLoad *) loadHandle->clientData;
Tcl_LoadHandle originalHandle = tvdlPtr->loadHandle;
return originalHandle->findSymbolProcPtr(interp, originalHandle, symbol);
|
| ︙ | ︙ | |||
3643 3644 3645 3646 3647 3648 3649 |
*
*---------------------------------------------------------------------------
*/
Tcl_Obj *
Tcl_FSLink(
Tcl_Obj *pathPtr, /* Pathaname of file. */
| < | < | 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 |
*
*---------------------------------------------------------------------------
*/
Tcl_Obj *
Tcl_FSLink(
Tcl_Obj *pathPtr, /* Pathaname of file. */
Tcl_Obj *toPtr, /* NULL or the pathname of a file to link to. */
int linkAction) /* Action to perform. */
{
const Tcl_Filesystem *fsPtr = Tcl_FSGetFileSystemForPath(pathPtr);
if (fsPtr) {
if (fsPtr->linkProc == NULL) {
Tcl_SetErrno(ENOTSUP);
|
| ︙ | ︙ | |||
3895 3896 3897 3898 3899 3900 3901 |
Tcl_PathType
TclGetPathType(
Tcl_Obj *pathPtr, /* Pathname to determine type of. */
const Tcl_Filesystem **filesystemPtrPtr,
/* If not NULL, a place in which to store a
* pointer to the filesystem for this pathname
* if it is absolute. */
| | > | 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 |
Tcl_PathType
TclGetPathType(
Tcl_Obj *pathPtr, /* Pathname to determine type of. */
const Tcl_Filesystem **filesystemPtrPtr,
/* If not NULL, a place in which to store a
* pointer to the filesystem for this pathname
* if it is absolute. */
Tcl_Size *driveNameLengthPtr,
/* If not NULL, a place in which to store the
* length of the volume name. */
Tcl_Obj **driveNameRef) /* If not NULL, for an absolute pathname, a
* place to store a pointer to an object with a
* refCount of 1, and whose value is the name
* of the volume. */
{
Tcl_Size pathLen;
|
| ︙ | ︙ | |||
3950 3951 3952 3953 3954 3955 3956 |
const char *path, /* Pathname to determine the type of. */
Tcl_Size pathLen, /* Length of the pathname. */
const Tcl_Filesystem **filesystemPtrPtr,
/* If not NULL, a place to store a pointer to
* the filesystem for this pathname when it is
* an absolute pathname. */
Tcl_Size *driveNameLengthPtr,/* If not NULL, a place to store the length of
| | < | 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 |
const char *path, /* Pathname to determine the type of. */
Tcl_Size pathLen, /* Length of the pathname. */
const Tcl_Filesystem **filesystemPtrPtr,
/* If not NULL, a place to store a pointer to
* the filesystem for this pathname when it is
* an absolute pathname. */
Tcl_Size *driveNameLengthPtr,/* If not NULL, a place to store the length of
* the volume name if the pathname is absolute. */
Tcl_Obj **driveNameRef) /* If not NULL, a place to store a pointer to
* an object having its its refCount already
* incremented, and contining the name of the
* volume if the pathname is absolute. */
{
FilesystemRecord *fsRecPtr;
Tcl_PathType type = TCL_PATH_RELATIVE;
|
| ︙ | ︙ | |||
4067 4068 4069 4070 4071 4072 4073 |
*
*---------------------------------------------------------------------------
*/
int
Tcl_FSRenameFile(
Tcl_Obj *srcPathPtr, /* The pathname of a file or directory to be
| | | 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 |
*
*---------------------------------------------------------------------------
*/
int
Tcl_FSRenameFile(
Tcl_Obj *srcPathPtr, /* The pathname of a file or directory to be
* renamed. */
Tcl_Obj *destPathPtr) /* The new pathname for the file. */
{
int retVal = -1;
const Tcl_Filesystem *fsPtr, *fsPtr2;
fsPtr = Tcl_FSGetFileSystemForPath(srcPathPtr);
fsPtr2 = Tcl_FSGetFileSystemForPath(destPathPtr);
|
| ︙ | ︙ | |||
4342 4343 4344 4345 4346 4347 4348 | * removeDirectoryProc is found. * *--------------------------------------------------------------------------- */ int Tcl_FSRemoveDirectory( | | < | < | 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 |
* removeDirectoryProc is found.
*
*---------------------------------------------------------------------------
*/
int
Tcl_FSRemoveDirectory(
Tcl_Obj *pathPtr, /* The pathname of the directory to be removed. */
int recursive, /* If zero, removes only an empty directory.
* Otherwise, removes the directory and all its
* contents. */
Tcl_Obj **errorPtr) /* If not NULL and an error occurs, stores a
* place to store a a pointer to a new
* object having a refCount of 1 and containing
* the name of the file that produced an error. */
{
const Tcl_Filesystem *fsPtr = Tcl_FSGetFileSystemForPath(pathPtr);
if (fsPtr == NULL) {
Tcl_SetErrno(ENOENT);
return -1;
}
|
| ︙ | ︙ |
Changes to generic/tclIndexObj.c.
| ︙ | ︙ | |||
51 52 53 54 55 56 57 |
* pointer to one of these structures.
*
* Keep this structure declaration in sync with tclTestObj.c
*/
typedef struct {
void *tablePtr; /* Pointer to the table of strings */
| | | 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
* pointer to one of these structures.
*
* Keep this structure declaration in sync with tclTestObj.c
*/
typedef struct {
void *tablePtr; /* Pointer to the table of strings */
Tcl_Size offset; /* Offset between table entries */
Tcl_Size index; /* Selected index into table. */
} IndexRep;
/*
* The following macros greatly simplify moving through a table...
*/
|
| ︙ | ︙ | |||
802 803 804 805 806 807 808 |
*
*----------------------------------------------------------------------
*/
void
Tcl_WrongNumArgs(
Tcl_Interp *interp, /* Current interpreter. */
| | | 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 |
*
*----------------------------------------------------------------------
*/
void
Tcl_WrongNumArgs(
Tcl_Interp *interp, /* Current interpreter. */
Tcl_Size objc, /* Number of arguments to print from objv. */
Tcl_Obj *const objv[], /* Initial argument objects, which should be
* included in the error message. */
const char *message) /* Error message to print after the leading
* objects in objv. The message may be
* NULL. */
{
Tcl_Obj *objPtr;
|
| ︙ | ︙ | |||
1005 1006 1007 1008 1009 1010 1011 |
const Tcl_ArgvInfo *infoPtr;
/* Pointer to the current entry in the table
* of argument descriptions. */
const Tcl_ArgvInfo *matchPtr;
/* Descriptor that matches current argument */
Tcl_Obj *curArg; /* Current argument */
const char *str = NULL;
| | | | | 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 |
const Tcl_ArgvInfo *infoPtr;
/* Pointer to the current entry in the table
* of argument descriptions. */
const Tcl_ArgvInfo *matchPtr;
/* Descriptor that matches current argument */
Tcl_Obj *curArg; /* Current argument */
const char *str = NULL;
char c; /* Second character of current arg (used for
* quick check for matching; use 2nd char.
* because first char. will almost always be
* '-'). */
Tcl_Size srcIndex; /* Location from which to read next argument
* from objv. */
Tcl_Size dstIndex; /* Used to keep track of current arguments
* being processed, primarily for error
* reporting. */
Tcl_Size objc; /* # arguments in objv still to process. */
Tcl_Size length; /* Number of characters in current argument */
if (remObjv != NULL) {
/*
|
| ︙ | ︙ |
Changes to generic/tclInt.h.
| ︙ | ︙ | |||
253 254 255 256 257 258 259 |
typedef struct Namespace {
char *name; /* The namespace's simple (unqualified) name.
* This contains no ::'s. The name of the
* global namespace is "" although "::" is an
* synonym. */
char *fullName; /* The namespace's fully qualified name. This
* starts with ::. */
| | | 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 |
typedef struct Namespace {
char *name; /* The namespace's simple (unqualified) name.
* This contains no ::'s. The name of the
* global namespace is "" although "::" is an
* synonym. */
char *fullName; /* The namespace's fully qualified name. This
* starts with ::. */
void *clientData; /* An arbitrary value associated with this
* namespace. */
Tcl_NamespaceDeleteProc *deleteProc;
/* Procedure invoked when deleting the
* namespace to, e.g., free clientData. */
struct Namespace *parentPtr;/* Points to the namespace that contains this
* one. NULL if this is the global
* namespace. */
|
| ︙ | ︙ | |||
275 276 277 278 279 280 281 |
* NULL, there are no children. */
#endif
#if TCL_MAJOR_VERSION > 8
size_t nsId; /* Unique id for the namespace. */
#else
unsigned long nsId;
#endif
| | | 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 |
* NULL, there are no children. */
#endif
#if TCL_MAJOR_VERSION > 8
size_t nsId; /* Unique id for the namespace. */
#else
unsigned long nsId;
#endif
Tcl_Interp *interp; /* The interpreter containing this
* namespace. */
int flags; /* OR-ed combination of the namespace status
* flags NS_DYING and NS_DEAD listed below. */
Tcl_Size activationCount; /* Number of "activations" or active call
* frames for this namespace that are on the
* Tcl call stack. The namespace won't be
* freed until activationCount becomes zero. */
|
| ︙ | ︙ | |||
308 309 310 311 312 313 314 |
* commands; however, no namespace qualifiers
* are allowed. NULL if no export patterns are
* registered. */
Tcl_Size numExportPatterns; /* Number of export patterns currently
* registered using "namespace export". */
Tcl_Size maxExportPatterns; /* Number of export patterns for which space
* is currently allocated. */
| | | | 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 |
* commands; however, no namespace qualifiers
* are allowed. NULL if no export patterns are
* registered. */
Tcl_Size numExportPatterns; /* Number of export patterns currently
* registered using "namespace export". */
Tcl_Size maxExportPatterns; /* Number of export patterns for which space
* is currently allocated. */
Tcl_Size cmdRefEpoch; /* Incremented if a newly added command
* shadows a command for which this namespace
* has already cached a Command* pointer; this
* causes all its cached Command* pointers to
* be invalidated. */
Tcl_Size resolverEpoch; /* Incremented whenever (a) the name
* resolution rules change for this namespace
* or (b) a newly added command shadows a
* command that is compiled to bytecodes. This
* invalidates all byte codes compiled in the
* namespace, causing the code to be
* recompiled under the new rules.*/
Tcl_ResolveCmdProc *cmdResProc;
|
| ︙ | ︙ | |||
440 441 442 443 444 445 446 |
typedef struct EnsembleConfig {
Namespace *nsPtr; /* The namespace backing this ensemble up. */
Tcl_Command token; /* The token for the command that provides
* ensemble support for the namespace, or NULL
* if the command has been deleted (or never
* existed; the global namespace never has an
* ensemble command.) */
| | | 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 |
typedef struct EnsembleConfig {
Namespace *nsPtr; /* The namespace backing this ensemble up. */
Tcl_Command token; /* The token for the command that provides
* ensemble support for the namespace, or NULL
* if the command has been deleted (or never
* existed; the global namespace never has an
* ensemble command.) */
Tcl_Size epoch; /* The epoch at which this ensemble's table of
* exported commands is valid. */
char **subcommandArrayPtr; /* Array of ensemble subcommand names. At all
* consistent points, this will have the same
* number of entries as there are entries in
* the subcommandTable hash. */
Tcl_HashTable subcommandTable;
/* Hash table of ensemble subcommand names,
|
| ︙ | ︙ | |||
497 498 499 500 501 502 503 |
* results passed directly back to the caller
* (including the error code) unless the code
* is TCL_CONTINUE in which case the
* subcommand will be re-parsed by the ensemble
* core, presumably because the ensemble
* itself has been updated. */
Tcl_Obj *parameterList; /* List of ensemble parameter names. */
| | | 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 |
* results passed directly back to the caller
* (including the error code) unless the code
* is TCL_CONTINUE in which case the
* subcommand will be re-parsed by the ensemble
* core, presumably because the ensemble
* itself has been updated. */
Tcl_Obj *parameterList; /* List of ensemble parameter names. */
Tcl_Size numParameters; /* Cached number of parameters. This is either
* 0 (if the parameterList field is NULL) or
* the length of the list in the parameterList
* field. */
} EnsembleConfig;
/*
* Various bits for the EnsembleConfig.flags field.
|
| ︙ | ︙ | |||
527 528 529 530 531 532 533 |
* specific C procedure whenever certain operations are performed on a
* variable.
*/
typedef struct VarTrace {
Tcl_VarTraceProc *traceProc;/* Procedure to call when operations given by
* flags are performed on variable. */
| | | | 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 |
* specific C procedure whenever certain operations are performed on a
* variable.
*/
typedef struct VarTrace {
Tcl_VarTraceProc *traceProc;/* Procedure to call when operations given by
* flags are performed on variable. */
void *clientData; /* Argument to pass to proc. */
int flags; /* What events the trace procedure is
* interested in: OR-ed combination of
* TCL_TRACE_READS, TCL_TRACE_WRITES,
* TCL_TRACE_UNSETS and TCL_TRACE_ARRAY. */
struct VarTrace *nextPtr; /* Next in list of traces associated with a
* particular variable. */
} VarTrace;
/*
* The following structure defines a command trace, which is used to invoke a
* specific C procedure whenever certain operations are performed on a
* command.
*/
typedef struct CommandTrace {
Tcl_CommandTraceProc *traceProc;
/* Procedure to call when operations given by
* flags are performed on command. */
void *clientData; /* Argument to pass to proc. */
int flags; /* What events the trace procedure is
* interested in: OR-ed combination of
* TCL_TRACE_RENAME, TCL_TRACE_DELETE. */
struct CommandTrace *nextPtr;
/* Next in list of traces associated with a
* particular command. */
Tcl_Size refCount; /* Used to ensure this structure is not
|
| ︙ | ︙ | |||
783 784 785 786 787 788 789 |
#define TclSetVarConstant(varPtr) \
(varPtr)->flags = ((varPtr)->flags & ~(VAR_ARRAY|VAR_LINK)) | VAR_CONSTANT
#define TclSetVarArrayElement(varPtr) \
(varPtr)->flags = ((varPtr)->flags & ~VAR_ARRAY) | VAR_ARRAY_ELEMENT
#define TclSetVarUndefined(varPtr) \
| | | | | | | | | | | | | 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 |
#define TclSetVarConstant(varPtr) \
(varPtr)->flags = ((varPtr)->flags & ~(VAR_ARRAY|VAR_LINK)) | VAR_CONSTANT
#define TclSetVarArrayElement(varPtr) \
(varPtr)->flags = ((varPtr)->flags & ~VAR_ARRAY) | VAR_ARRAY_ELEMENT
#define TclSetVarUndefined(varPtr) \
(varPtr)->flags &= ~(VAR_ARRAY|VAR_LINK|VAR_CONSTANT); \
(varPtr)->value.objPtr = NULL
#define TclClearVarUndefined(varPtr)
#define TclSetVarTraceActive(varPtr) \
(varPtr)->flags |= VAR_TRACE_ACTIVE
#define TclClearVarTraceActive(varPtr) \
(varPtr)->flags &= ~VAR_TRACE_ACTIVE
#define TclSetVarNamespaceVar(varPtr) \
if (!TclIsVarNamespaceVar(varPtr)) { \
(varPtr)->flags |= VAR_NAMESPACE_VAR; \
if (TclIsVarInHash(varPtr)) { \
((VarInHash *)(varPtr))->refCount++; \
} \
}
#define TclClearVarNamespaceVar(varPtr) \
if (TclIsVarNamespaceVar(varPtr)) { \
(varPtr)->flags &= ~VAR_NAMESPACE_VAR; \
if (TclIsVarInHash(varPtr)) { \
((VarInHash *)(varPtr))->refCount--; \
} \
}
/*
* Macros to read various flag bits of variables.
* The ANSI C "prototypes" for these macros are:
*
* MODULE_SCOPE int TclIsVarScalar(Var *varPtr);
|
| ︙ | ︙ | |||
966 967 968 969 970 971 972 |
*/
typedef struct CompiledLocal {
struct CompiledLocal *nextPtr;
/* Next compiler-recognized local variable for
* this procedure, or NULL if this is the last
* local. */
| | | | | 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 |
*/
typedef struct CompiledLocal {
struct CompiledLocal *nextPtr;
/* Next compiler-recognized local variable for
* this procedure, or NULL if this is the last
* local. */
Tcl_Size nameLength; /* The number of bytes in local variable's name.
* Among others used to speed up var lookups. */
Tcl_Size frameIndex; /* Index in the array of compiler-assigned
* variables in the procedure call frame. */
#if TCL_MAJOR_VERSION < 9
int flags;
#endif
Tcl_Obj *defValuePtr; /* Pointer to the default value of an
* argument, if any. NULL if not an argument
* or, if an argument, no default value. */
Tcl_ResolvedVarInfo *resolveInfo;
/* Customized variable resolution info
* supplied by the Tcl_ResolveCompiledVarProc
* associated with a namespace. Each variable
* is marked by a unique tag during
* compilation, and that same tag is used to
* find the variable at runtime. */
#if TCL_MAJOR_VERSION > 8
int flags; /* Flag bits for the local variable. Same as
* the flags for the Var structure above,
* although only VAR_ARGUMENT, VAR_TEMPORARY,
* and VAR_RESOLVED make sense. */
#endif
char name[TCLFLEXARRAY]; /* Name of the local variable starts here. If
* the name is NULL, this will just be '\0'.
* The actual size of this field will be large
* enough to hold the name. MUST BE THE LAST
* FIELD IN THE STRUCTURE! */
} CompiledLocal;
/*
|
| ︙ | ︙ | |||
1051 1052 1053 1054 1055 1056 1057 |
Tcl_Size level; /* Only trace commands at nesting level less
* than or equal to this. */
#if TCL_MAJOR_VERSION > 8
Tcl_CmdObjTraceProc2 *proc; /* Procedure to call to trace command. */
#else
Tcl_CmdObjTraceProc *proc; /* Procedure to call to trace command. */
#endif
| | | 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 |
Tcl_Size level; /* Only trace commands at nesting level less
* than or equal to this. */
#if TCL_MAJOR_VERSION > 8
Tcl_CmdObjTraceProc2 *proc; /* Procedure to call to trace command. */
#else
Tcl_CmdObjTraceProc *proc; /* Procedure to call to trace command. */
#endif
void *clientData; /* Arbitrary value to pass to proc. */
struct Trace *nextPtr; /* Next in list of traces for this interp. */
int flags; /* Flags governing the trace - see
* Tcl_CreateObjTrace for details. */
Tcl_CmdObjTraceDeleteProc *delProc;
/* Procedure to call when trace is deleted. */
} Trace;
|
| ︙ | ︙ | |||
1084 1085 1086 1087 1088 1089 1090 | } ActiveInterpTrace; /* * Flag values designating types of execution traces. See tclTrace.c for * related flag values. * * TCL_TRACE_ENTER_EXEC - triggers enter/enterstep traces. | | | | 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 | } ActiveInterpTrace; /* * Flag values designating types of execution traces. See tclTrace.c for * related flag values. * * TCL_TRACE_ENTER_EXEC - triggers enter/enterstep traces. * - passed to Tcl_CreateObjTrace to set up * "enterstep" traces. * TCL_TRACE_LEAVE_EXEC - triggers leave/leavestep traces. * - passed to Tcl_CreateObjTrace to set up * "leavestep" traces. */ #define TCL_TRACE_ENTER_EXEC 1 #define TCL_TRACE_LEAVE_EXEC 2 #if TCL_MAJOR_VERSION > 8 |
| ︙ | ︙ | |||
1199 1200 1201 1202 1203 1204 1205 |
* associated with an interpreter. The entry contains a pointer to a function
* to call when the interpreter is deleted, and a pointer to a user-defined
* piece of data.
*/
typedef struct AssocData {
Tcl_InterpDeleteProc *proc; /* Proc to call when deleting. */
| | | 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 |
* associated with an interpreter. The entry contains a pointer to a function
* to call when the interpreter is deleted, and a pointer to a user-defined
* piece of data.
*/
typedef struct AssocData {
Tcl_InterpDeleteProc *proc; /* Proc to call when deleting. */
void *clientData; /* Value to pass to proc. */
} AssocData;
/*
* The structure below defines a call frame. A call frame defines a naming
* context for a procedure call: its local naming scope (for local variables)
* and its global naming scope (a namespace, perhaps the global :: namespace).
* A call frame can also define the naming context for a namespace eval or
|
| ︙ | ︙ | |||
1243 1244 1245 1246 1247 1248 1249 |
int isProcCallFrame; /* If 0, the frame was pushed to execute a
* namespace command and var references are
* treated as references to namespace vars;
* varTablePtr and compiledLocals are ignored.
* If FRAME_IS_PROC is set, the frame was
* pushed to execute a Tcl procedure and may
* have local vars. */
| | | | | 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 |
int isProcCallFrame; /* If 0, the frame was pushed to execute a
* namespace command and var references are
* treated as references to namespace vars;
* varTablePtr and compiledLocals are ignored.
* If FRAME_IS_PROC is set, the frame was
* pushed to execute a Tcl procedure and may
* have local vars. */
Tcl_Size objc; /* This and objv below describe the arguments
* for this procedure call. */
Tcl_Obj *const *objv; /* Array of argument objects. */
struct CallFrame *callerPtr;
/* Value of interp->framePtr when this
* procedure was invoked (i.e. next higher in
* stack of all active procedures). */
struct CallFrame *callerVarPtr;
/* Value of interp->varFramePtr when this
* procedure was invoked (i.e. determines
* variable scoping within caller). Same as
* callerPtr unless an "uplevel" command or
* something equivalent was active in the
* caller). */
Tcl_Size level; /* Level of this procedure, for "uplevel"
* purposes (i.e. corresponds to nesting of
* callerVarPtr's, not callerPtr's). 1 for
* outermost procedure, 0 for top-level. */
Proc *procPtr; /* Points to the structure defining the called
* procedure. Used to get information such as
* the number of compiled local variables
* (local variables assigned entries ["slots"]
* in the compiledLocals array below). */
TclVarHashTable *varTablePtr;
/* Hash table containing local variables not
* recognized by the compiler, or created at
* execution time through, e.g., upvar.
* Initially NULL and created if needed. */
Tcl_Size numCompiledLocals; /* Count of local variables recognized
* by the compiler including arguments. */
Var *compiledLocals; /* Points to the array of local variables
* recognized by the compiler. The compiler
* emits code that refers to these variables
* using an index into this array. */
void *clientData; /* Pointer to some context that is used by
* object systems. The meaning of the contents
* of this field is defined by the code that
* sets it, and it should only ever be set by
* the code that is pushing the frame. In that
* case, the code that sets it should also
* have some means of discovering what the
* meaning of the value is, which we do not
|
| ︙ | ︙ | |||
1377 1378 1379 1380 1381 1382 1383 |
struct {
const void *codePtr;/* Byte code currently executed... */
const char *pc; /* ... and instruction pointer. */
} tebc;
} data;
Tcl_Obj *cmdObj;
const char *cmd; /* The executed command, if possible... */
| | | | | | 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 |
struct {
const void *codePtr;/* Byte code currently executed... */
const char *pc; /* ... and instruction pointer. */
} tebc;
} data;
Tcl_Obj *cmdObj;
const char *cmd; /* The executed command, if possible... */
Tcl_Size len; /* ... and its length. */
const struct CFWordBC *litarg;
/* Link to set of literal arguments which have
* ben pushed on the lineLABCPtr stack by
* TclArgumentBCEnter(). These will be removed
* by TclArgumentBCRelease. */
} CmdFrame;
typedef struct CFWord {
CmdFrame *framePtr; /* CmdFrame to access. */
Tcl_Size word; /* Index of the word in the command. */
Tcl_Size refCount; /* Number of times the word is on the
* stack. */
} CFWord;
typedef struct CFWordBC {
CmdFrame *framePtr; /* CmdFrame to access. */
Tcl_Size pc; /* Instruction pointer of a command in
* ExtCmdLoc.loc[.] */
Tcl_Size word; /* Index of word in
* ExtCmdLoc.loc[cmd]->line[.] */
struct CFWordBC *prevPtr; /* Previous entry in stack for same Tcl_Obj. */
struct CFWordBC *nextPtr; /* Next entry for same command call. See
* CmdFrame litarg field for the list start. */
Tcl_Obj *obj; /* Back reference to hash table key */
} CFWordBC;
|
| ︙ | ︙ | |||
1425 1426 1427 1428 1429 1430 1431 |
* released by the function TclFreeObj(), in the file "tclObj.c", and also by
* the function TclThreadFinalizeObjects(), in the same file.
*/
#define CLL_END (-1)
typedef struct ContLineLoc {
| | | | 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 |
* released by the function TclFreeObj(), in the file "tclObj.c", and also by
* the function TclThreadFinalizeObjects(), in the same file.
*/
#define CLL_END (-1)
typedef struct ContLineLoc {
Tcl_Size num; /* Number of entries in loc, not counting the
* final -1 marker entry. */
Tcl_Size loc[TCLFLEXARRAY]; /* Table of locations, as character offsets.
* The table is allocated as part of the
* structure, extending behind the nominal end
* of the structure. An entry containing the
* value -1 is put after the last location, as
* end-marker/sentinel. */
} ContLineLoc;
|
| ︙ | ︙ | |||
1468 1469 1470 1471 1472 1473 1474 |
* procedures (e.g. a lambda) so that their details can be reported correctly
* by [info frame]. Contains a sub-structure for each extra field.
*/
typedef Tcl_Obj * (GetFrameInfoValueProc)(void *clientData);
typedef struct {
const char *name; /* Name of this field. */
| | | | | 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 |
* procedures (e.g. a lambda) so that their details can be reported correctly
* by [info frame]. Contains a sub-structure for each extra field.
*/
typedef Tcl_Obj * (GetFrameInfoValueProc)(void *clientData);
typedef struct {
const char *name; /* Name of this field. */
GetFrameInfoValueProc *proc;/* Function to generate a Tcl_Obj* from the
* clientData, or just use the clientData
* directly (after casting) if NULL. */
void *clientData; /* Context for above function, or Tcl_Obj* if
* proc field is NULL. */
} ExtraFrameInfoField;
typedef struct {
Tcl_Size length; /* Length of array. */
ExtraFrameInfoField fields[2];
/* Really as long as necessary, but this is
* long enough for nearly anything. */
} ExtraFrameInfo;
/*
*----------------------------------------------------------------
|
| ︙ | ︙ | |||
1540 1541 1542 1543 1544 1545 1546 | /* * The type of procedures called by the Tcl bytecode compiler to compile * commands. Pointers to these procedures are kept in the Command structure * describing each command. The integer value returned by a CompileProc must * be one of the following: * * TCL_OK Compilation completed normally. | | | | | | | | | | | 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 | /* * The type of procedures called by the Tcl bytecode compiler to compile * commands. Pointers to these procedures are kept in the Command structure * describing each command. The integer value returned by a CompileProc must * be one of the following: * * TCL_OK Compilation completed normally. * TCL_ERROR Compilation could not be completed. This can be just a * judgment by the CompileProc that the command is too * complex to compile effectively, or it can indicate * that in the current state of the interp, the command * would raise an error. The bytecode compiler will not * do any error reporting at compiler time. Error * reporting is deferred until the actual runtime, * because by then changes in the interp state may allow * the command to be successfully evaluated. */ typedef int (CompileProc)(Tcl_Interp *interp, Tcl_Parse *parsePtr, struct Command *cmdPtr, struct CompileEnv *compEnvPtr); /* * The type of procedure called from the compilation hook point in |
| ︙ | ︙ | |||
1600 1601 1602 1603 1604 1605 1606 |
* etc.) for the coroutine. */
struct ExecEnv *callerEEPtr;/* The execution environment for the caller of
* the coroutine, which might be the
* interpreter global environment or another
* coroutine. */
CorContext caller;
CorContext running;
| | | | | > | | < | 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 |
* etc.) for the coroutine. */
struct ExecEnv *callerEEPtr;/* The execution environment for the caller of
* the coroutine, which might be the
* interpreter global environment or another
* coroutine. */
CorContext caller;
CorContext running;
Tcl_HashTable *lineLABCPtr; /* See Interp.lineLABCPtr */
void *stackLevel;
Tcl_Size auxNumLevels; /* While the coroutine is running the
* numLevels of the create/resume command is
* stored here; for suspended coroutines it
* holds the nesting numLevels at yield. */
Tcl_Size nargs; /* Number of args required for resuming this
* coroutine; COROUTINE_ARGUMENTS_SINGLE_OPTIONAL
* means "0 or 1" (default),
* COROUTINE_ARGUMENTS_ARBITRARY means "any" */
Tcl_Obj *yieldPtr; /* The command to yield to. Stored here in
* order to reset splice point in
* TclNRCoroutineActivateCallback if the
* coroutine is busy. */
} CoroutineData;
typedef struct ExecEnv {
ExecStack *execStackPtr; /* Points to the first item in the evaluation
* stack on the heap. */
Tcl_Obj *constants[2]; /* Pointers to constant "0" and "1" objs. */
struct Tcl_Interp *interp;
|
| ︙ | ︙ | |||
1670 1671 1672 1673 1674 1675 1676 |
typedef struct LiteralTable {
LiteralEntry **buckets; /* Pointer to bucket array. Each element
* points to first entry in bucket's hash
* chain, or NULL. */
LiteralEntry *staticBuckets[TCL_SMALL_HASH_TABLE];
/* Bucket array used for small tables to avoid
* mallocs and frees. */
| | | | | | > | | 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 |
typedef struct LiteralTable {
LiteralEntry **buckets; /* Pointer to bucket array. Each element
* points to first entry in bucket's hash
* chain, or NULL. */
LiteralEntry *staticBuckets[TCL_SMALL_HASH_TABLE];
/* Bucket array used for small tables to avoid
* mallocs and frees. */
TCL_HASH_TYPE numBuckets; /* Total number of buckets allocated at
* **buckets. */
TCL_HASH_TYPE numEntries; /* Total number of entries present in
* table. */
TCL_HASH_TYPE rebuildSize; /* Enlarge table when numEntries gets to be
* this large. */
TCL_HASH_TYPE mask; /* Mask value used in hashing function. */
} LiteralTable;
/*
* The following structure defines for each Tcl interpreter various
* statistics-related information about the bytecode compiler and
* interpreter's operation in that interpreter.
*/
#ifdef TCL_COMPILE_STATS
typedef struct ByteCodeStats {
size_t numExecutions; /* Number of ByteCodes executed. */
size_t numCompilations; /* Number of ByteCodes created. */
size_t numByteCodesFreed; /* Number of ByteCodes destroyed. */
size_t instructionCount[256];
/* Number of times each instruction was
* executed. */
double totalSrcBytes; /* Total source bytes ever compiled. */
double totalByteCodeBytes; /* Total bytes for all ByteCodes. */
double currentSrcBytes; /* Src bytes for all current ByteCodes. */
double currentByteCodeBytes;/* Code bytes in all current ByteCodes. */
size_t srcCount[32]; /* Source size distribution: # of srcs of
* size [2**(n-1)..2**n), n in [0..32). */
size_t byteCodeCount[32]; /* ByteCode size distribution. */
size_t lifetimeCount[32]; /* ByteCode lifetime distribution (ms). */
double currentInstBytes; /* Instruction bytes-current ByteCodes. */
double currentLitBytes; /* Current literal bytes. */
double currentExceptBytes; /* Current exception table bytes. */
|
| ︙ | ︙ | |||
1728 1729 1730 1731 1732 1733 1734 |
*/
typedef struct {
const char *name; /* The name of the subcommand. */
Tcl_ObjCmdProc *proc; /* The implementation of the subcommand. */
CompileProc *compileProc; /* The compiler for the subcommand. */
Tcl_ObjCmdProc *nreProc; /* NRE implementation of this command. */
| | | 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 |
*/
typedef struct {
const char *name; /* The name of the subcommand. */
Tcl_ObjCmdProc *proc; /* The implementation of the subcommand. */
CompileProc *compileProc; /* The compiler for the subcommand. */
Tcl_ObjCmdProc *nreProc; /* NRE implementation of this command. */
void *clientData; /* Any clientData to give the command. */
int unsafe; /* Whether this command is to be hidden by
* default in a safe interpreter. */
} EnsembleImplMap;
/*
*----------------------------------------------------------------
* Data structures related to commands.
|
| ︙ | ︙ | |||
1807 1808 1809 1810 1811 1812 1813 |
* that point to this command when it is
* renamed, deleted, hidden, or exposed. */
CompileProc *compileProc; /* Procedure called to compile command. NULL
* if no compile proc exists for command. */
Tcl_ObjCmdProc *objProc; /* Object-based command procedure. */
void *objClientData; /* Arbitrary value passed to object proc. */
Tcl_CmdProc *proc; /* String-based command procedure. */
| | | | 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 |
* that point to this command when it is
* renamed, deleted, hidden, or exposed. */
CompileProc *compileProc; /* Procedure called to compile command. NULL
* if no compile proc exists for command. */
Tcl_ObjCmdProc *objProc; /* Object-based command procedure. */
void *objClientData; /* Arbitrary value passed to object proc. */
Tcl_CmdProc *proc; /* String-based command procedure. */
void *clientData; /* Arbitrary value passed to string proc. */
Tcl_CmdDeleteProc *deleteProc;
/* Procedure invoked when deleting command to,
* e.g., free all client data. */
void *deleteData; /* Arbitrary value passed to deleteProc. */
int flags; /* Miscellaneous bits of information about
* command. See below for definitions. */
ImportRef *importRefPtr; /* List of each imported Command created in
* another namespace when this command is
* imported. These imported commands redirect
* invocations back to this command. The list
* is used to remove all those imported
|
| ︙ | ︙ | |||
1957 1958 1959 1960 1961 1962 1963 | /* Pointer to the exported Tcl stub table. In * ancient pre-8.1 versions of Tcl this was a * pointer to the objResultPtr or a pointer to a * buckets array in a hash table. Deployed stubs * enabled extensions check for a NULL pointer value * and for a TCL_STUBS_MAGIC value to verify they * are not [load]ing into one of those pre-stubs | | < | | 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 |
/* Pointer to the exported Tcl stub table. In
* ancient pre-8.1 versions of Tcl this was a
* pointer to the objResultPtr or a pointer to a
* buckets array in a hash table. Deployed stubs
* enabled extensions check for a NULL pointer value
* and for a TCL_STUBS_MAGIC value to verify they
* are not [load]ing into one of those pre-stubs
* interps. */
TclHandle handle; /* Handle used to keep track of when this
* interp is deleted. */
Namespace *globalNsPtr; /* The interpreter's global namespace. */
Tcl_HashTable *hiddenCmdTablePtr;
/* Hash table used by tclBasic.c to keep track
* of hidden commands on a per-interp
* basis. */
void *interpInfo; /* Information used by tclInterp.c to keep
* track of parent/child interps on a
* per-interp basis. */
#if TCL_MAJOR_VERSION > 8
void (*optimizer)(void *envPtr);
#else
union {
void (*optimizer)(void *envPtr);
|
| ︙ | ︙ | |||
2047 2048 2049 2050 2051 2052 2053 |
int unused1; /* No longer used (was termOffset) */
#endif
LiteralTable literalTable; /* Contains LiteralEntry's describing all Tcl
* objects holding literals of scripts
* compiled by the interpreter. Indexed by the
* string representations of literals. Used to
* avoid creating duplicate objects. */
| | | < | 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 |
int unused1; /* No longer used (was termOffset) */
#endif
LiteralTable literalTable; /* Contains LiteralEntry's describing all Tcl
* objects holding literals of scripts
* compiled by the interpreter. Indexed by the
* string representations of literals. Used to
* avoid creating duplicate objects. */
Tcl_Size compileEpoch; /* Holds the current "compilation epoch" for
* this interpreter. This is incremented to
* invalidate existing ByteCodes when, e.g., a
* command with a compile procedure is
* redefined. */
Proc *compiledProcPtr; /* If a procedure is being compiled, a pointer
* to its Proc structure; otherwise, this is
* NULL. Set by ObjInterpProc in tclProc.c and
* used by tclCompile.c to process local
* variables appropriately. */
ResolverScheme *resolverPtr;/* Linked list of name resolution schemes
* added to this interpreter. Schemes are
* added and removed by calling
* Tcl_AddInterpResolvers and
* Tcl_RemoveInterpResolver respectively. */
Tcl_Obj *scriptFile; /* NULL means there is no nested source
* command active; otherwise this points to
* pathPtr of the file being sourced. */
|
| ︙ | ︙ | |||
2094 2095 2096 2097 2098 2099 2100 |
ActiveCommandTrace *activeCmdTracePtr;
/* First in list of active command traces for
* interp, or NULL if no active traces. */
ActiveInterpTrace *activeInterpTracePtr;
/* First in list of active traces for interp,
* or NULL if no active traces. */
| | > | 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 |
ActiveCommandTrace *activeCmdTracePtr;
/* First in list of active command traces for
* interp, or NULL if no active traces. */
ActiveInterpTrace *activeInterpTracePtr;
/* First in list of active traces for interp,
* or NULL if no active traces. */
Tcl_Size tracesForbiddingInline;
/* Count of traces (in the list headed by
* tracePtr) that forbid inline bytecode
* compilation. */
/*
* Fields used to manage extensible return options (TIP 90).
*/
|
| ︙ | ︙ | |||
2124 2125 2126 2127 2128 2129 2130 | * set. */ int granularityTicker; /* Counter used to determine how often to * check the limits. */ int exceeded; /* Which limits have been exceeded, described * as flag values the same as the 'active' * field. */ | | | 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 | * set. */ int granularityTicker; /* Counter used to determine how often to * check the limits. */ int exceeded; /* Which limits have been exceeded, described * as flag values the same as the 'active' * field. */ Tcl_Size cmdCount; /* Limit for how many commands to execute in * the interpreter. */ LimitHandler *cmdHandlers; /* Handlers to execute when the limit is * reached. */ int cmdGranularity; /* Mod factor used to determine how often to * evaluate the limit check. */ |
| ︙ | ︙ | |||
2160 2161 2162 2163 2164 2165 2166 |
struct {
Tcl_Obj *const *sourceObjs;
/* What arguments were actually input into the
* *root* ensemble command? (Nested ensembles
* don't rewrite this.) NULL if we're not
* processing an ensemble. */
| | | > | 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 |
struct {
Tcl_Obj *const *sourceObjs;
/* What arguments were actually input into the
* *root* ensemble command? (Nested ensembles
* don't rewrite this.) NULL if we're not
* processing an ensemble. */
Tcl_Size numRemovedObjs;/* How many arguments have been stripped off
* because of ensemble processing. */
Tcl_Size numInsertedObjs;
/* How many of the current arguments were
* inserted by an ensemble. */
} ensembleRewrite;
/*
* TIP #219: Global info for the I/O system.
*/
|
| ︙ | ︙ | |||
2222 2223 2224 2225 2226 2227 2228 |
ContLineLoc *scriptCLLocPtr;/* This table points to the location data for
* invisible continuation lines in the script,
* if any. This pointer is set by the function
* TclEvalObjEx() in file "tclBasic.c", and
* used by function ...() in the same file.
* It does for the eval/direct path of script
* execution what CompileEnv.clLoc does for
| | < | 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 |
ContLineLoc *scriptCLLocPtr;/* This table points to the location data for
* invisible continuation lines in the script,
* if any. This pointer is set by the function
* TclEvalObjEx() in file "tclBasic.c", and
* used by function ...() in the same file.
* It does for the eval/direct path of script
* execution what CompileEnv.clLoc does for
* the bytecode compiler. */
/*
* TIP #268. The currently active selection mode, i.e. the package require
* preferences.
*/
int packagePrefer; /* Current package selection mode. */
|
| ︙ | ︙ | |||
2287 2288 2289 2290 2291 2292 2293 |
Tcl_Obj *asyncCancelMsg; /* Error message set by async cancel handler
* for the propagation of arbitrary Tcl
* errors. This information, if present
* (asyncCancelMsg not NULL), takes precedence
* over the default error messages returned by
* a script cancellation operation. */
| | | | > | 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 |
Tcl_Obj *asyncCancelMsg; /* Error message set by async cancel handler
* for the propagation of arbitrary Tcl
* errors. This information, if present
* (asyncCancelMsg not NULL), takes precedence
* over the default error messages returned by
* a script cancellation operation. */
/*
* TIP #348 IMPLEMENTATION - Substituted error stack
*/
Tcl_Obj *errorStack; /* [info errorstack] value (as a Tcl_Obj). */
Tcl_Obj *upLiteral; /* "UP" literal for [info errorstack] */
Tcl_Obj *callLiteral; /* "CALL" literal for [info errorstack] */
Tcl_Obj *innerLiteral; /* "INNER" literal for [info errorstack] */
Tcl_Obj *innerContext; /* cached list for fast reallocation */
int resetErrorStack; /* controls cleaning up of ::errorStack */
|
| ︙ | ︙ | |||
2322 2323 2324 2325 2326 2327 2328 |
/*
* Macros for script cancellation support (TIP #285).
*/
#define TclCanceled(iPtr) \
(((iPtr)->flags & CANCELED) || ((iPtr)->flags & TCL_CANCEL_UNWIND))
| | | | | | | | | | | | | | | | | | | 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 |
/*
* Macros for script cancellation support (TIP #285).
*/
#define TclCanceled(iPtr) \
(((iPtr)->flags & CANCELED) || ((iPtr)->flags & TCL_CANCEL_UNWIND))
#define TclSetCancelFlags(iPtr, cancelFlags) \
(iPtr)->flags |= CANCELED; \
if ((cancelFlags) & TCL_CANCEL_UNWIND) { \
(iPtr)->flags |= TCL_CANCEL_UNWIND; \
}
#define TclUnsetCancelFlags(iPtr) \
(iPtr)->flags &= (~(CANCELED | TCL_CANCEL_UNWIND))
/*
* Macros for splicing into and out of doubly linked lists. They assume
* existence of struct items 'prevPtr' and 'nextPtr'.
*
* a = element to add or remove.
* b = list head.
*
* TclSpliceIn adds to the head of the list.
*/
#define TclSpliceIn(a, b) \
(a)->nextPtr = (b); \
if ((b) != NULL) { \
(b)->prevPtr = (a); \
} \
(a)->prevPtr = NULL, (b) = (a);
#define TclSpliceOut(a, b) \
if ((a)->prevPtr != NULL) { \
(a)->prevPtr->nextPtr = (a)->nextPtr; \
} else { \
(b) = (a)->nextPtr; \
} \
if ((a)->nextPtr != NULL) { \
(a)->nextPtr->prevPtr = (a)->prevPtr; \
}
/*
* EvalFlag bits for Interp structures:
*
* TCL_ALLOW_EXCEPTIONS 1 means it's OK for the script to terminate with a
* code other than TCL_OK or TCL_ERROR; 0 means codes
|
| ︙ | ︙ | |||
2491 2492 2493 2494 2495 2496 2497 | (((x) + (TCL_ALIGN_BYTES - 1)) & ~(TCL_ALIGN_BYTES - 1)) /* * A common panic alert when memory allocation fails. */ #define TclOOM(ptr, size) \ | > | > | 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 |
(((x) + (TCL_ALIGN_BYTES - 1)) & ~(TCL_ALIGN_BYTES - 1))
/*
* A common panic alert when memory allocation fails.
*/
#define TclOOM(ptr, size) \
((size) && ((ptr)||( \
Tcl_Panic("unable to alloc %" TCL_Z_MODIFIER "u bytes", \
(size_t)(size)),1)))
/*
* The following enum values are used to specify the runtime platform setting
* of the tclPlatform variable.
*/
typedef enum {
|
| ︙ | ︙ | |||
2561 2562 2563 2564 2565 2566 2567 |
* define the content of the list. The ListSpan specifies the range of slots
* within the ListStore that hold elements for this list. The ListSpan is
* optional in which case the list includes all the "in-use" slots of the
* ListStore.
*
*/
typedef struct ListStore {
| | | | | | | > | | | | | | > | | > | | > | | | | | | > | | | | | | | < | > | | | | | | | | | | | | 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 |
* define the content of the list. The ListSpan specifies the range of slots
* within the ListStore that hold elements for this list. The ListSpan is
* optional in which case the list includes all the "in-use" slots of the
* ListStore.
*
*/
typedef struct ListStore {
Tcl_Size firstUsed; /* Index of first slot in use within slots[] */
Tcl_Size numUsed; /* Number of slots in use (starting firstUsed) */
Tcl_Size numAllocated; /* Total number of slots[] array slots. */
size_t refCount; /* Number of references to this instance */
int flags; /* LISTSTORE_* flags */
Tcl_Obj *slots[TCLFLEXARRAY];
/* Variable size array. Grown as needed */
} ListStore;
#define LISTSTORE_CANONICAL 0x1 /* All Tcl_Obj's referencing this store have
* their string representation derived from
* the list representation */
/* Max number of elements that can be contained in a list */
#define LIST_MAX \
((Tcl_Size)(((size_t)TCL_SIZE_MAX - offsetof(ListStore, slots)) \
/ sizeof(Tcl_Obj *)))
/* Memory size needed for a ListStore to hold numSlots_ elements */
#define LIST_SIZE(numSlots_) \
((Tcl_Size)(offsetof(ListStore, slots) + ((numSlots_) * sizeof(Tcl_Obj *))))
/*
* ListSpan --
* See comments above for ListStore
*/
typedef struct ListSpan {
Tcl_Size spanStart; /* Starting index of the span */
Tcl_Size spanLength; /* Number of elements in the span */
size_t refCount; /* Count of references to this span record */
} ListSpan;
#ifndef LIST_SPAN_THRESHOLD /* May be set on build line */
#define LIST_SPAN_THRESHOLD 101
#endif
/*
* ListRep --
* See comments above for ListStore
*/
typedef struct ListRep {
ListStore *storePtr; /* element array shared amongst different
* lists */
ListSpan *spanPtr; /* If not NULL, the span holds the range of
* slots within *storePtr that contain this
* list elements. */
} ListRep;
/*
* Macros used to get access list internal representations.
*
* Naming conventions:
* ListRep* - expect a pointer to a valid ListRep
* ListObj* - expect a pointer to a Tcl_Obj whose internal type is known to
* be a list (tclListType). Will crash otherwise.
* TclListObj* - expect a pointer to a Tcl_Obj whose internal type may or may not
* be tclListType. These will convert as needed and return error if
* conversion not possible.
*/
/* Returns the starting slot for this listRep in the contained ListStore */
#define ListRepStart(listRepPtr_) \
((listRepPtr_)->spanPtr ? (listRepPtr_)->spanPtr->spanStart \
: (listRepPtr_)->storePtr->firstUsed)
/* Returns the number of elements in this listRep */
#define ListRepLength(listRepPtr_) \
((listRepPtr_)->spanPtr ? (listRepPtr_)->spanPtr->spanLength \
: (listRepPtr_)->storePtr->numUsed)
/* Returns a pointer to the first slot containing this ListRep elements */
#define ListRepElementsBase(listRepPtr_) \
(&(listRepPtr_)->storePtr->slots[ListRepStart(listRepPtr_)])
/* Stores the number of elements and base address of the element array */
#define ListRepElements(listRepPtr_, objc_, objv_) \
(((objv_) = ListRepElementsBase(listRepPtr_)), \
((objc_) = ListRepLength(listRepPtr_)))
/* Returns 1/0 whether the ListRep's ListStore is shared. */
#define ListRepIsShared(listRepPtr_) \
((listRepPtr_)->storePtr->refCount > 1)
/* Returns a pointer to the ListStore component */
#define ListObjStorePtr(listObj_) \
((ListStore *)((listObj_)->internalRep.twoPtrValue.ptr1))
/* Returns a pointer to the ListSpan component */
#define ListObjSpanPtr(listObj_) \
((ListSpan *)((listObj_)->internalRep.twoPtrValue.ptr2))
/* Returns the ListRep internal representaton in a Tcl_Obj */
#define ListObjGetRep(listObj_, listRepPtr_) \
do { \
(listRepPtr_)->storePtr = ListObjStorePtr(listObj_); \
(listRepPtr_)->spanPtr = ListObjSpanPtr(listObj_); \
} while (0)
/* Returns the length of the list */
#define ListObjLength(listObj_, len_) \
((len_) = ListObjSpanPtr(listObj_) ? ListObjSpanPtr(listObj_)->spanLength \
: ListObjStorePtr(listObj_)->numUsed)
/* Returns the starting slot index of this list's elements in the ListStore */
#define ListObjStart(listObj_) \
(ListObjSpanPtr(listObj_) ? ListObjSpanPtr(listObj_)->spanStart \
: ListObjStorePtr(listObj_)->firstUsed)
/* Stores the element count and base address of this list's elements */
#define ListObjGetElements(listObj_, objc_, objv_) \
(((objv_) = &ListObjStorePtr(listObj_)->slots[ListObjStart(listObj_)]), \
(ListObjLength(listObj_, (objc_))))
/*
* Returns 1/0 whether the internal representation (not the Tcl_Obj itself)
* is shared. Note by intent this only checks for sharing of ListStore,
* not spans.
*/
#define ListObjRepIsShared(listObj_) \
(ListObjStorePtr(listObj_)->refCount > 1)
/*
* Certain commands like concat are optimized if an existing string
* representation of a list object is known to be in canonical format (i.e.
* generated from the list representation). There are three conditions when
* this will be the case:
* (1) No string representation exists which means it will obviously have
* to be generated from the list representation when needed
* (2) The ListStore flags is marked canonical. This is done at the time
* the string representation is generated from the list under certain
* conditions (see comments in UpdateStringOfList).
* (3) The list representation does not have a span component. This is
* because list Tcl_Obj's with spans are always created from existing lists
* and never from strings (see SetListFromAny) and thus their string
* representation will always be canonical.
*/
#define ListObjIsCanonical(listObj_) \
(((listObj_)->bytes == NULL) \
|| (ListObjStorePtr(listObj_)->flags & LISTSTORE_CANONICAL) \
|| ListObjSpanPtr(listObj_) != NULL)
/*
* Converts the Tcl_Obj to a list if it isn't one and stores the element
* count and base address of this list's elements in objcPtr_ and objvPtr_.
* Return TCL_OK on success or TCL_ERROR if the Tcl_Obj cannot be
* converted to a list.
*/
#define TclListObjGetElementsM(interp_, listObj_, objcPtr_, objvPtr_) \
(((listObj_)->typePtr == &tclListType) \
? ((ListObjGetElements((listObj_), *(objcPtr_), *(objvPtr_))), \
TCL_OK) \
: Tcl_ListObjGetElements( \
(interp_), (listObj_), (objcPtr_), (objvPtr_)))
/*
* Converts the Tcl_Obj to a list if it isn't one and stores the element
* count in lenPtr_. Returns TCL_OK on success or TCL_ERROR if the
* Tcl_Obj cannot be converted to a list.
*/
#define TclListObjLengthM(interp_, listObj_, lenPtr_) \
(((listObj_)->typePtr == &tclListType) \
? ((ListObjLength((listObj_), *(lenPtr_))), TCL_OK) \
: Tcl_ListObjLength((interp_), (listObj_), (lenPtr_)))
#define TclListObjIsCanonical(listObj_) \
(((listObj_)->typePtr == &tclListType) ? ListObjIsCanonical((listObj_)) : 0)
/*
* Modes for collecting (or not) in the implementations of TclNRForeachCmd,
|
| ︙ | ︙ | |||
2740 2741 2742 2743 2744 2745 2746 | * and Tcl_GetIntForIndex. * * WARNING: these macros eval their args more than once. */ #if TCL_MAJOR_VERSION > 8 #define TclGetBooleanFromObj(interp, objPtr, intPtr) \ | | | | | | | | | | | 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 |
* and Tcl_GetIntForIndex.
*
* WARNING: these macros eval their args more than once.
*/
#if TCL_MAJOR_VERSION > 8
#define TclGetBooleanFromObj(interp, objPtr, intPtr) \
(((objPtr)->typePtr == &tclIntType \
|| (objPtr)->typePtr == &tclBooleanType) \
? (*(intPtr) = ((objPtr)->internalRep.wideValue!=0), TCL_OK) \
: Tcl_GetBooleanFromObj((interp), (objPtr), (intPtr)))
#else
#define TclGetBooleanFromObj(interp, objPtr, intPtr) \
(((objPtr)->typePtr == &tclIntType) \
? (*(intPtr) = ((objPtr)->internalRep.wideValue!=0), TCL_OK) \
: ((objPtr)->typePtr == &tclBooleanType) \
? (*(intPtr) = ((objPtr)->internalRep.longValue!=0), TCL_OK) \
: Tcl_GetBooleanFromObj((interp), (objPtr), (intPtr)))
#endif
#ifdef TCL_WIDE_INT_IS_LONG
#define TclGetLongFromObj(interp, objPtr, longPtr) \
(((objPtr)->typePtr == &tclIntType) \
? ((*(longPtr) = (objPtr)->internalRep.wideValue), TCL_OK) \
: Tcl_GetLongFromObj((interp), (objPtr), (longPtr)))
#else
#define TclGetLongFromObj(interp, objPtr, longPtr) \
(((objPtr)->typePtr == &tclIntType \
&& (objPtr)->internalRep.wideValue >= (Tcl_WideInt)(LONG_MIN) \
&& (objPtr)->internalRep.wideValue <= (Tcl_WideInt)(LONG_MAX)) \
? ((*(longPtr) = (long)(objPtr)->internalRep.wideValue), TCL_OK) \
: Tcl_GetLongFromObj((interp), (objPtr), (longPtr)))
#endif
#define TclGetIntFromObj(interp, objPtr, intPtr) \
(((objPtr)->typePtr == &tclIntType \
&& (objPtr)->internalRep.wideValue >= (Tcl_WideInt)(INT_MIN) \
&& (objPtr)->internalRep.wideValue <= (Tcl_WideInt)(INT_MAX)) \
? ((*(intPtr) = (int)(objPtr)->internalRep.wideValue), TCL_OK) \
: Tcl_GetIntFromObj((interp), (objPtr), (intPtr)))
#define TclGetIntForIndexM(interp, objPtr, endValue, idxPtr) \
((((objPtr)->typePtr == &tclIntType) && ((objPtr)->internalRep.wideValue >= 0) \
&& ((objPtr)->internalRep.wideValue <= endValue)) \
? ((*(idxPtr) = (objPtr)->internalRep.wideValue), TCL_OK) \
: Tcl_GetIntForIndex((interp), (objPtr), (endValue), (idxPtr)))
/*
* Macro used to save a function call for common uses of
* Tcl_GetWideIntFromObj(). The ANSI C "prototype" is:
*
* MODULE_SCOPE int TclGetWideIntFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
|
| ︙ | ︙ | |||
2905 2906 2907 2908 2909 2910 2911 |
* to be shared among several threads. Each thread sees a (Tcl_Obj) copy of
* the value, and the gobal value is kept as a counted string, with epoch and
* mutex control. Each ProcessGlobalValue struct should be a static variable in
* some file.
*/
typedef struct ProcessGlobalValue {
| | | | | < | | | | | | | | > > | | | | | < | > | > > > > | > | | | | | | | | > | > > > | > > > | > > > > > | > > > | > > > > > > | > > > > > < | | | | | | | 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 |
* to be shared among several threads. Each thread sees a (Tcl_Obj) copy of
* the value, and the gobal value is kept as a counted string, with epoch and
* mutex control. Each ProcessGlobalValue struct should be a static variable in
* some file.
*/
typedef struct ProcessGlobalValue {
Tcl_Size epoch; /* Epoch counter to detect changes in the
* global value. */
TCL_HASH_TYPE numBytes; /* Length of the global string. */
char *value; /* The global string value. */
Tcl_Encoding encoding; /* system encoding when global string was
* initialized. */
TclInitProcessGlobalValueProc *proc;
/* A procedure to initialize the global string
* copy when a "get" request comes in before
* any "set" request has been received. */
Tcl_Mutex mutex; /* Enforce orderly access from multiple
* threads. */
Tcl_ThreadDataKey key; /* Key for per-thread data holding the
* (Tcl_Obj) copy for each thread. */
} ProcessGlobalValue;
/*
*----------------------------------------------------------------------
* Flags for TclParseNumber
*----------------------------------------------------------------------
*/
#define TCL_PARSE_DECIMAL_ONLY 1
/* Leading zero doesn't denote octal or
* hex. */
#define TCL_PARSE_OCTAL_ONLY 2 /* Parse octal even without prefix. */
#define TCL_PARSE_HEXADECIMAL_ONLY 4
/* Parse hexadecimal even without prefix. */
#define TCL_PARSE_INTEGER_ONLY 8
/* Disable floating point parsing. */
#define TCL_PARSE_SCAN_PREFIXES 16
/* Use [scan] rules dealing with 0?
* prefixes. */
#define TCL_PARSE_NO_WHITESPACE 32
/* Reject leading/trailing whitespace. */
#define TCL_PARSE_BINARY_ONLY 64
/* Parse binary even without prefix. */
#define TCL_PARSE_NO_UNDERSCORE 128
/* Reject underscore digit separator */
/*
*----------------------------------------------------------------------
* Internal convenience macros for manipulating encoding flags. See
* TCL_ENCODING_PROFILE_* in tcl.h
*----------------------------------------------------------------------
*/
#define ENCODING_PROFILE_MASK 0xFF000000
#define ENCODING_PROFILE_GET(flags_) ((flags_) & ENCODING_PROFILE_MASK)
#define ENCODING_PROFILE_SET(flags_, profile_) \
do { \
(flags_) &= ~ENCODING_PROFILE_MASK; \
(flags_) |= ((profile_) & ENCODING_PROFILE_MASK); \
} while (0)
/*
*----------------------------------------------------------------------
* Common functions for calculating overallocation. Trivial but allows for
* experimenting with growth factors without having to change code in
* multiple places. See TclAttemptAllocElemsEx and similar for usage
* examples. Best to use those functions. Direct use of TclUpsizeAlloc /
* TclResizeAlloc is needed in special cases such as when total size of
* memory block is limited to less than TCL_SIZE_MAX.
*
*----------------------------------------------------------------------
*/
static inline Tcl_Size
TclUpsizeAlloc(
TCL_UNUSED(Tcl_Size), /* oldSize. For future experiments with
* some growth algorithms that use this
* information. */
Tcl_Size needed,
Tcl_Size limit)
{
/* assert (oldCapacity < needed <= limit) */
if (needed < (limit - needed/2)) {
return needed + needed / 2;
} else {
return limit;
}
}
static inline Tcl_Size
TclUpsizeRetry(
Tcl_Size needed,
Tcl_Size lastAttempt)
{
/* assert (needed < lastAttempt) */
if (needed < lastAttempt - 1) {
/* (needed+lastAttempt)/2 but that formula may overflow Tcl_Size */
return needed + (lastAttempt - needed) / 2;
} else {
return needed;
}
}
MODULE_SCOPE void * TclAllocElemsEx(Tcl_Size elemCount, Tcl_Size elemSize,
Tcl_Size leadSize, Tcl_Size *capacityPtr);
MODULE_SCOPE void * TclReallocElemsEx(void *oldPtr, Tcl_Size elemCount,
Tcl_Size elemSize, Tcl_Size leadSize,
Tcl_Size *capacityPtr);
MODULE_SCOPE void * TclAttemptReallocElemsEx(void *oldPtr,
Tcl_Size elemCount, Tcl_Size elemSize,
Tcl_Size leadSize, Tcl_Size *capacityPtr);
/* Alloc elemCount elements of size elemSize with leadSize header
* returning actual capacity (in elements) in *capacityPtr. */
static inline void *
TclAttemptAllocElemsEx(
Tcl_Size elemCount,
Tcl_Size elemSize,
Tcl_Size leadSize,
Tcl_Size *capacityPtr)
{
return TclAttemptReallocElemsEx(
NULL, elemCount, elemSize, leadSize, capacityPtr);
}
/* Alloc numByte bytes, returning actual capacity in *capacityPtr. */
static inline void *
TclAllocEx(
Tcl_Size numBytes,
Tcl_Size *capacityPtr)
{
return TclAllocElemsEx(numBytes, 1, 0, capacityPtr);
}
/* Alloc numByte bytes, returning actual capacity in *capacityPtr. */
static inline void *
TclAttemptAllocEx(
Tcl_Size numBytes,
Tcl_Size *capacityPtr)
{
return TclAttemptAllocElemsEx(numBytes, 1, 0, capacityPtr);
}
/* Realloc numByte bytes, returning actual capacity in *capacityPtr. */
static inline void *
TclReallocEx(
void *oldPtr,
Tcl_Size numBytes,
Tcl_Size *capacityPtr)
{
return TclReallocElemsEx(oldPtr, numBytes, 1, 0, capacityPtr);
}
/* Realloc numByte bytes, returning actual capacity in *capacityPtr. */
static inline void *
TclAttemptReallocEx(
void *oldPtr,
Tcl_Size numBytes,
Tcl_Size *capacityPtr)
{
return TclAttemptReallocElemsEx(oldPtr, numBytes, 1, 0, capacityPtr);
}
/*
*----------------------------------------------------------------
* Variables shared among Tcl modules but not used by the outside world.
*----------------------------------------------------------------
*/
MODULE_SCOPE char *tclNativeExecutableName;
MODULE_SCOPE int tclFindExecutableSearchDone;
MODULE_SCOPE char *tclMemDumpFileName;
MODULE_SCOPE TclPlatformType tclPlatform;
/*
* Declarations related to internal encoding functions.
*/
MODULE_SCOPE Tcl_Encoding tclIdentityEncoding;
MODULE_SCOPE Tcl_Encoding tclUtf8Encoding;
MODULE_SCOPE int TclEncodingProfileNameToId(Tcl_Interp *interp,
const char *profileName,
int *profilePtr);
MODULE_SCOPE const char *TclEncodingProfileIdToName(
Tcl_Interp *interp, int profileId);
MODULE_SCOPE void TclGetEncodingProfiles(Tcl_Interp *interp);
/*
* TIP #233 (Virtualized Time)
* Data for the time hooks, if any.
*/
MODULE_SCOPE Tcl_GetTimeProc *tclGetTimeProcPtr;
|
| ︙ | ︙ | |||
3152 3153 3154 3155 3156 3157 3158 | MODULE_SCOPE Tcl_ObjCmdProc TclNRCoroutineObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclNRYieldObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclNRYieldmObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclNRYieldToObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclNRInvoke; MODULE_SCOPE Tcl_NRPostProc TclNRReleaseValues; | | | | | | | | < < | | < < | | | 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 |
MODULE_SCOPE Tcl_ObjCmdProc TclNRCoroutineObjCmd;
MODULE_SCOPE Tcl_ObjCmdProc TclNRYieldObjCmd;
MODULE_SCOPE Tcl_ObjCmdProc TclNRYieldmObjCmd;
MODULE_SCOPE Tcl_ObjCmdProc TclNRYieldToObjCmd;
MODULE_SCOPE Tcl_ObjCmdProc TclNRInvoke;
MODULE_SCOPE Tcl_NRPostProc TclNRReleaseValues;
MODULE_SCOPE void TclSetTailcall(Tcl_Interp *interp, Tcl_Obj *tailcallPtr);
MODULE_SCOPE void TclPushTailcallPoint(Tcl_Interp *interp);
/* These two can be considered for the public api */
MODULE_SCOPE void TclMarkTailcall(Tcl_Interp *interp);
MODULE_SCOPE void TclSkipTailcall(Tcl_Interp *interp);
/*
* This structure holds the data for the various iteration callbacks used to
* NRE the 'for' and 'while' commands. We need a separate structure because we
* have more than the 4 client data entries we can provide directly thorugh
* the callback API. It is the 'word' information which puts us over the
* limit. It is needed because the loop body is argument 4 of 'for' and
* argument 2 of 'while'. Not providing the correct index confuses the #280
* code. We TclSmallAlloc/Free this.
*/
typedef struct ForIterData {
Tcl_Obj *cond; /* Loop condition expression. */
Tcl_Obj *body; /* Loop body. */
Tcl_Obj *next; /* Loop step script, NULL for 'while'. */
const char *msg; /* Error message part. */
Tcl_Size word; /* Index of the body script in the command */
} ForIterData;
/* TIP #357 - Structure doing the bookkeeping of handles for Tcl_LoadFile
* and Tcl_FindSymbol. This structure corresponds to an opaque
* typedef in tcl.h */
typedef void* TclFindSymbolProc(Tcl_Interp* interp, Tcl_LoadHandle loadHandle,
const char* symbol);
struct Tcl_LoadHandle_ {
void *clientData; /* Client data is the load handle in the
* native filesystem if a module was loaded
* there, or an opaque pointer to a structure
* for further bookkeeping on load-from-VFS
* and load-from-memory */
TclFindSymbolProc* findSymbolProcPtr;
/* Procedure that resolves symbols in a
* loaded module */
Tcl_FSUnloadFileProc* unloadFileProcPtr;
/* Procedure that unloads a loaded module */
};
/* Flags for conversion of doubles to digit strings */
#define TCL_DD_E_FORMAT 0x2 /* Use a fixed-length string of digits,
* suitable for E format*/
#define TCL_DD_F_FORMAT 0x3 /* Use a fixed number of digits after the
* decimal point, suitable for F format */
#define TCL_DD_SHORTEST 0x4 /* Use the shortest possible string */
#define TCL_DD_NO_QUICK 0x8 /* Debug flag: forbid quick FP conversion */
#define TCL_DD_CONVERSION_TYPE_MASK 0x3
/* Mask to isolate the conversion type */
/*
*----------------------------------------------------------------
* Procedures shared among Tcl modules but not used by the outside world:
*----------------------------------------------------------------
*/
|
| ︙ | ︙ | |||
3445 3446 3447 3448 3449 3450 3451 | const char *expected, const char *bytes, Tcl_Size numBytes, const char **endPtrPtr, int flags); MODULE_SCOPE void TclParseInit(Tcl_Interp *interp, const char *string, Tcl_Size numBytes, Tcl_Parse *parsePtr); MODULE_SCOPE Tcl_Size TclParseAllWhiteSpace(const char *src, Tcl_Size numBytes); MODULE_SCOPE int TclProcessReturn(Tcl_Interp *interp, int code, int level, Tcl_Obj *returnOpts); | | | 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 |
const char *expected, const char *bytes,
Tcl_Size numBytes, const char **endPtrPtr, int flags);
MODULE_SCOPE void TclParseInit(Tcl_Interp *interp, const char *string,
Tcl_Size numBytes, Tcl_Parse *parsePtr);
MODULE_SCOPE Tcl_Size TclParseAllWhiteSpace(const char *src, Tcl_Size numBytes);
MODULE_SCOPE int TclProcessReturn(Tcl_Interp *interp,
int code, int level, Tcl_Obj *returnOpts);
MODULE_SCOPE void TclUndoRefCount(Tcl_Obj *objPtr);
MODULE_SCOPE int TclpObjLstat(Tcl_Obj *pathPtr, Tcl_StatBuf *buf);
MODULE_SCOPE Tcl_Obj * TclpTempFileName(void);
MODULE_SCOPE Tcl_Obj * TclpTempFileNameForLibrary(Tcl_Interp *interp,
Tcl_Obj* pathPtr);
MODULE_SCOPE int TclNewArithSeriesObj(Tcl_Interp *interp, Tcl_Obj **arithSeriesPtr,
int useDoubles, Tcl_Obj *startObj, Tcl_Obj *endObj,
Tcl_Obj *stepObj, Tcl_Obj *lenObj);
|
| ︙ | ︙ | |||
3485 3486 3487 3488 3489 3490 3491 | MODULE_SCOPE int TclpThreadCreate(Tcl_ThreadId *idPtr, Tcl_ThreadCreateProc *proc, void *clientData, TCL_HASH_TYPE stackSize, int flags); MODULE_SCOPE Tcl_Size TclpFindVariable(const char *name, Tcl_Size *lengthPtr); MODULE_SCOPE void TclpInitLibraryPath(char **valuePtr, TCL_HASH_TYPE *lengthPtr, Tcl_Encoding *encodingPtr); MODULE_SCOPE void TclpInitLock(void); | | | 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 | MODULE_SCOPE int TclpThreadCreate(Tcl_ThreadId *idPtr, Tcl_ThreadCreateProc *proc, void *clientData, TCL_HASH_TYPE stackSize, int flags); MODULE_SCOPE Tcl_Size TclpFindVariable(const char *name, Tcl_Size *lengthPtr); MODULE_SCOPE void TclpInitLibraryPath(char **valuePtr, TCL_HASH_TYPE *lengthPtr, Tcl_Encoding *encodingPtr); MODULE_SCOPE void TclpInitLock(void); MODULE_SCOPE void * TclpInitNotifier(void); MODULE_SCOPE void TclpInitPlatform(void); MODULE_SCOPE void TclpInitUnlock(void); MODULE_SCOPE Tcl_Obj * TclpObjListVolumes(void); MODULE_SCOPE void TclpGlobalLock(void); MODULE_SCOPE void TclpGlobalUnlock(void); MODULE_SCOPE int TclpObjNormalizePath(Tcl_Interp *interp, Tcl_Obj *pathPtr, int nextCheckpoint); |
| ︙ | ︙ | |||
3573 3574 3575 3576 3577 3578 3579 | MODULE_SCOPE Tcl_Size TclTrim(const char *bytes, Tcl_Size numBytes, const char *trim, Tcl_Size numTrim, Tcl_Size *trimRight); MODULE_SCOPE Tcl_Size TclTrimLeft(const char *bytes, Tcl_Size numBytes, const char *trim, Tcl_Size numTrim); MODULE_SCOPE Tcl_Size TclTrimRight(const char *bytes, Tcl_Size numBytes, const char *trim, Tcl_Size numTrim); MODULE_SCOPE const char*TclGetCommandTypeName(Tcl_Command command); | | | 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 | MODULE_SCOPE Tcl_Size TclTrim(const char *bytes, Tcl_Size numBytes, const char *trim, Tcl_Size numTrim, Tcl_Size *trimRight); MODULE_SCOPE Tcl_Size TclTrimLeft(const char *bytes, Tcl_Size numBytes, const char *trim, Tcl_Size numTrim); MODULE_SCOPE Tcl_Size TclTrimRight(const char *bytes, Tcl_Size numBytes, const char *trim, Tcl_Size numTrim); MODULE_SCOPE const char*TclGetCommandTypeName(Tcl_Command command); MODULE_SCOPE int TclObjInterpProc(void *clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); MODULE_SCOPE void TclRegisterCommandTypeName( Tcl_ObjCmdProc *implementationProc, const char *nameStr); MODULE_SCOPE int TclUtfCmp(const char *cs, const char *ct); MODULE_SCOPE int TclUtfCasecmp(const char *cs, const char *ct); |
| ︙ | ︙ | |||
3599 3600 3601 3602 3603 3604 3605 | Tcl_FSUnloadFileProc **unloadProcPtr, int flags); #endif MODULE_SCOPE void TclInitThreadStorage(void); MODULE_SCOPE void TclFinalizeThreadDataThread(void); MODULE_SCOPE void TclFinalizeThreadStorage(void); #ifdef TCL_WIDE_CLICKS | | | | 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 | Tcl_FSUnloadFileProc **unloadProcPtr, int flags); #endif MODULE_SCOPE void TclInitThreadStorage(void); MODULE_SCOPE void TclFinalizeThreadDataThread(void); MODULE_SCOPE void TclFinalizeThreadStorage(void); #ifdef TCL_WIDE_CLICKS MODULE_SCOPE long long TclpGetWideClicks(void); MODULE_SCOPE double TclpWideClicksToNanoseconds(long long clicks); MODULE_SCOPE double TclpWideClickInMicrosec(void); #else # ifdef _WIN32 # define TCL_WIDE_CLICKS 1 MODULE_SCOPE long long TclpGetWideClicks(void); MODULE_SCOPE double TclpWideClickInMicrosec(void); # define TclpWideClicksToNanoseconds(clicks) \ ((double)(clicks) * TclpWideClickInMicrosec() * 1000) # endif #endif MODULE_SCOPE long long TclpGetMicroseconds(void); |
| ︙ | ︙ | |||
4002 4003 4004 4005 4006 4007 4008 | MODULE_SCOPE int TclFullFinalizationRequested(void); /* * TIP #542 */ | | | | | | | | | 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 | MODULE_SCOPE int TclFullFinalizationRequested(void); /* * TIP #542 */ MODULE_SCOPE size_t TclUniCharLen(const Tcl_UniChar *uniStr); MODULE_SCOPE int TclUniCharNcmp(const Tcl_UniChar *ucs, const Tcl_UniChar *uct, size_t numChars); MODULE_SCOPE int TclUniCharNcasecmp(const Tcl_UniChar *ucs, const Tcl_UniChar *uct, size_t numChars); MODULE_SCOPE int TclUniCharCaseMatch(const Tcl_UniChar *uniStr, const Tcl_UniChar *uniPattern, int nocase); /* * Just for the purposes of command-type registration. */ MODULE_SCOPE Tcl_ObjCmdProc TclEnsembleImplementationCmd; |
| ︙ | ︙ | |||
4047 4048 4049 4050 4051 4052 4053 | } TclProcessWaitStatus; MODULE_SCOPE Tcl_Command TclInitProcessCmd(Tcl_Interp *interp); MODULE_SCOPE void TclProcessCreated(Tcl_Pid pid); MODULE_SCOPE TclProcessWaitStatus TclProcessWait(Tcl_Pid pid, int options, int *codePtr, Tcl_Obj **msgObjPtr, Tcl_Obj **errorObjPtr); | | | 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 | } TclProcessWaitStatus; MODULE_SCOPE Tcl_Command TclInitProcessCmd(Tcl_Interp *interp); MODULE_SCOPE void TclProcessCreated(Tcl_Pid pid); MODULE_SCOPE TclProcessWaitStatus TclProcessWait(Tcl_Pid pid, int options, int *codePtr, Tcl_Obj **msgObjPtr, Tcl_Obj **errorObjPtr); MODULE_SCOPE int TclClose(Tcl_Interp *, Tcl_Channel chan); /* * TIP #508: [array default] */ MODULE_SCOPE void TclInitArrayVar(Var *arrayPtr); MODULE_SCOPE Tcl_Obj * TclGetArrayDefault(Var *arrayPtr); |
| ︙ | ︙ | |||
4153 4154 4155 4156 4157 4158 4159 |
# define TclIncrObjsFreed() \
tclObjsFreed++
#else
# define TclIncrObjsAllocated()
# define TclIncrObjsFreed()
#endif /* TCL_COMPILE_STATS */
| | | | | | | | | | | | | | | | | | | | | | | 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 |
# define TclIncrObjsFreed() \
tclObjsFreed++
#else
# define TclIncrObjsAllocated()
# define TclIncrObjsFreed()
#endif /* TCL_COMPILE_STATS */
# define TclAllocObjStorage(objPtr) \
TclAllocObjStorageEx(NULL, (objPtr))
# define TclFreeObjStorage(objPtr) \
TclFreeObjStorageEx(NULL, (objPtr))
#ifndef TCL_MEM_DEBUG
# define TclNewObj(objPtr) \
TclIncrObjsAllocated(); \
TclAllocObjStorage(objPtr); \
(objPtr)->refCount = 0; \
(objPtr)->bytes = &tclEmptyString; \
(objPtr)->length = 0; \
(objPtr)->typePtr = NULL; \
TCL_DTRACE_OBJ_CREATE(objPtr)
/*
* Invalidate the string rep first so we can use the bytes value for our
* pointer chain, and signal an obj deletion (as opposed to shimmering) with
* 'length == TCL_INDEX_NONE'.
* Use empty 'if ; else' to handle use in unbraced outer if/else conditions.
*/
# define TclDecrRefCount(objPtr) \
if ((objPtr)->refCount-- > 1) ; else { \
if (!(objPtr)->typePtr || !(objPtr)->typePtr->freeIntRepProc) { \
TCL_DTRACE_OBJ_FREE(objPtr); \
if ((objPtr)->bytes \
&& ((objPtr)->bytes != &tclEmptyString)) { \
Tcl_Free((objPtr)->bytes); \
} \
(objPtr)->length = TCL_INDEX_NONE; \
TclFreeObjStorage(objPtr); \
TclIncrObjsFreed(); \
} else { \
TclFreeObj(objPtr); \
} \
}
#if TCL_THREADS && !defined(USE_THREAD_ALLOC)
# define USE_THREAD_ALLOC 1
#endif
#if defined(PURIFY)
|
| ︙ | ︙ | |||
4353 4354 4355 4356 4357 4358 4359 | * *---------------------------------------------------------------- */ #define TclInitEmptyStringRep(objPtr) \ ((objPtr)->length = (((objPtr)->bytes = &tclEmptyString), 0)) | < | | | | | | | | | | | | | 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 |
*
*----------------------------------------------------------------
*/
#define TclInitEmptyStringRep(objPtr) \
((objPtr)->length = (((objPtr)->bytes = &tclEmptyString), 0))
#define TclInitStringRep(objPtr, bytePtr, len) \
if ((len) == 0) { \
TclInitEmptyStringRep(objPtr); \
} else { \
(objPtr)->bytes = (char *) Tcl_Alloc((len) + 1U); \
memcpy((objPtr)->bytes, (bytePtr) ? (bytePtr) : &tclEmptyString, (len)); \
(objPtr)->bytes[len] = '\0'; \
(objPtr)->length = (len); \
}
#define TclAttemptInitStringRep(objPtr, bytePtr, len) \
((((len) == 0) ? ( \
TclInitEmptyStringRep(objPtr) \
) : ( \
(objPtr)->bytes = (char *)Tcl_AttemptAlloc((len) + 1U), \
(objPtr)->length = ((objPtr)->bytes) ? \
(memcpy((objPtr)->bytes, (bytePtr) ? (bytePtr) : &tclEmptyString, (len)), \
(objPtr)->bytes[len] = '\0', (len)) : (-1) \
)), (objPtr)->bytes)
/*
*----------------------------------------------------------------
* Macro used by the Tcl core to get the string representation's byte array
* pointer from a Tcl_Obj. This is an inline version of Tcl_GetString(). The
* macro's expression result is the string rep's byte pointer which might be
|
| ︙ | ︙ | |||
4400 4401 4402 4403 4404 4405 4406 | * "prototype" for this macro is: * * MODULE_SCOPE void TclFreeInternalRep(Tcl_Obj *objPtr); *---------------------------------------------------------------- */ #define TclFreeInternalRep(objPtr) \ | | | | | | | | | | | | | | | 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 |
* "prototype" for this macro is:
*
* MODULE_SCOPE void TclFreeInternalRep(Tcl_Obj *objPtr);
*----------------------------------------------------------------
*/
#define TclFreeInternalRep(objPtr) \
if ((objPtr)->typePtr != NULL) { \
if ((objPtr)->typePtr->freeIntRepProc != NULL) { \
(objPtr)->typePtr->freeIntRepProc(objPtr); \
} \
(objPtr)->typePtr = NULL; \
}
/*
*----------------------------------------------------------------
* Macro used by the Tcl core to clean out an object's string representation.
* The ANSI C "prototype" for this macro is:
*
* MODULE_SCOPE void TclInvalidateStringRep(Tcl_Obj *objPtr);
*----------------------------------------------------------------
*/
#define TclInvalidateStringRep(objPtr) \
do { \
Tcl_Obj *_isobjPtr = (Tcl_Obj *)(objPtr); \
if (_isobjPtr->bytes != NULL) { \
if (_isobjPtr->bytes != &tclEmptyString) { \
Tcl_Free((char *)_isobjPtr->bytes); \
} \
_isobjPtr->bytes = NULL; \
} \
} while (0)
/*
* These form part of the native filesystem support. They are needed here
* because we have a few native filesystem functions (which are the same for
* win/unix) in this file.
*/
|
| ︙ | ︙ | |||
4467 4468 4469 4470 4471 4472 4473 |
*
* MODULE_SCOPE void TclUnpackBignum(Tcl_Obj *objPtr, mp_int bignum);
*----------------------------------------------------------------
*/
#define TclUnpackBignum(objPtr, bignum) \
do { \
| | | | 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 |
*
* MODULE_SCOPE void TclUnpackBignum(Tcl_Obj *objPtr, mp_int bignum);
*----------------------------------------------------------------
*/
#define TclUnpackBignum(objPtr, bignum) \
do { \
Tcl_Obj *bignumObj = (objPtr); \
int bignumPayload = \
PTR2INT(bignumObj->internalRep.twoPtrValue.ptr2); \
if (bignumPayload == -1) { \
(bignum) = *((mp_int *) bignumObj->internalRep.twoPtrValue.ptr1); \
} else { \
(bignum).dp = (mp_digit *)bignumObj->internalRep.twoPtrValue.ptr1; \
(bignum).sign = bignumPayload >> 30; \
(bignum).alloc = (bignumPayload >> 15) & 0x7FFF; \
|
| ︙ | ︙ | |||
4521 4522 4523 4524 4525 4526 4527 |
Tcl_Size allocated = 2 * _needed; \
Tcl_Token *oldPtr = (tokenPtr); \
Tcl_Token *newPtr; \
if (oldPtr == (staticPtr)) { \
oldPtr = NULL; \
} \
newPtr = (Tcl_Token *)Tcl_AttemptRealloc((char *) oldPtr, \
| | | | | | | | | | | | | | | | | | | 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 |
Tcl_Size allocated = 2 * _needed; \
Tcl_Token *oldPtr = (tokenPtr); \
Tcl_Token *newPtr; \
if (oldPtr == (staticPtr)) { \
oldPtr = NULL; \
} \
newPtr = (Tcl_Token *)Tcl_AttemptRealloc((char *) oldPtr, \
allocated * sizeof(Tcl_Token)); \
if (newPtr == NULL) { \
allocated = _needed + (append) + TCL_MIN_TOKEN_GROWTH; \
newPtr = (Tcl_Token *)Tcl_Realloc((char *) oldPtr, \
allocated * sizeof(Tcl_Token)); \
} \
(available) = allocated; \
if (oldPtr == NULL) { \
memcpy(newPtr, staticPtr, \
(used) * sizeof(Tcl_Token)); \
} \
(tokenPtr) = newPtr; \
} \
} while (0)
#define TclGrowParseTokenArray(parsePtr, append) \
TclGrowTokenArray((parsePtr)->tokenPtr, (parsePtr)->numTokens, \
(parsePtr)->tokensAvailable, (append), \
(parsePtr)->staticTokens)
/*
*----------------------------------------------------------------
* Macro used by the Tcl core get a unicode char from a utf string. It checks
* to see if we have a one-byte utf char before calling the real
* Tcl_UtfToUniChar, as this will save a lot of time for primarily ASCII
* string handling. The macro's expression result is 1 for the 1-byte case or
* the result of Tcl_UtfToUniChar. The ANSI C "prototype" for this macro is:
*
* MODULE_SCOPE int TclUtfToUniChar(const char *string, Tcl_UniChar *ch);
*----------------------------------------------------------------
*/
#if TCL_UTF_MAX > 3
#define TclUtfToUniChar(str, chPtr) \
(((UCHAR(*(str))) < 0x80) ? \
((*(chPtr) = UCHAR(*(str))), 1) \
: Tcl_UtfToUniChar(str, chPtr))
#else
#define TclUtfToUniChar(str, chPtr) \
(((UCHAR(*(str))) < 0x80) ? \
((*(chPtr) = UCHAR(*(str))), 1) \
: Tcl_UtfToChar16(str, chPtr))
#endif
/*
*----------------------------------------------------------------
* Macro counterpart of the Tcl_NumUtfChars() function. To be used in speed-
* -sensitive points where it pays to avoid a function call in the common case
* of counting along a string of all one-byte characters. The ANSI C
* "prototype" for this macro is:
*
* MODULE_SCOPE void TclNumUtfCharsM(Tcl_Size numChars, const char *bytes,
* Tcl_Size numBytes);
* numBytes must be >= 0
*----------------------------------------------------------------
*/
#define TclNumUtfCharsM(numChars, bytes, numBytes) \
do { \
Tcl_Size _count = 0, _i = (numBytes); \
unsigned char *_str = (unsigned char *) (bytes); \
while (_i > 0 && (*_str < 0xC0)) { _i--; _str++; } \
_count = (numBytes) - _i; \
if (_i) { \
_count += Tcl_NumUtfChars((bytes) + _count, _i); \
} \
(numChars) = _count; \
} while (0);
/*
*----------------------------------------------------------------
* Macro that encapsulates the logic that determines when it is safe to
* interpret a string as a byte array directly. In summary, the object must be
* a byte array and must not have a string representation (as the operations
|
| ︙ | ︙ | |||
4613 4614 4615 4616 4617 4618 4619 | #define TclIsPureDict(objPtr) \ (((objPtr)->bytes==NULL) && ((objPtr)->typePtr==&tclDictType)) #define TclHasInternalRep(objPtr, type) \ ((objPtr)->typePtr == (type)) #define TclFetchInternalRep(objPtr, type) \ (TclHasInternalRep((objPtr), (type)) ? &((objPtr)->internalRep) : NULL) | < | | | | | | 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 |
#define TclIsPureDict(objPtr) \
(((objPtr)->bytes==NULL) && ((objPtr)->typePtr==&tclDictType))
#define TclHasInternalRep(objPtr, type) \
((objPtr)->typePtr == (type))
#define TclFetchInternalRep(objPtr, type) \
(TclHasInternalRep((objPtr), (type)) ? &((objPtr)->internalRep) : NULL)
/*
*----------------------------------------------------------------
* Macro used by the Tcl core to increment a namespace's export epoch
* counter. The ANSI C "prototype" for this macro is:
*
* MODULE_SCOPE void TclInvalidateNsCmdLookup(Namespace *nsPtr);
*----------------------------------------------------------------
*/
#define TclInvalidateNsCmdLookup(nsPtr) \
if ((nsPtr)->numExportPatterns) { \
(nsPtr)->exportLookupEpoch++; \
} \
if ((nsPtr)->commandPathLength) { \
(nsPtr)->cmdRefEpoch++; \
}
/*
*----------------------------------------------------------------------
*
* Core procedure added to libtommath for bignum manipulation.
*
|
| ︙ | ︙ | |||
4658 4659 4660 4661 4662 4663 4664 | MODULE_SCOPE Tcl_LibraryInitProc TclplatformtestInit; MODULE_SCOPE Tcl_LibraryInitProc TclObjTest_Init; MODULE_SCOPE Tcl_LibraryInitProc TclThread_Init; MODULE_SCOPE Tcl_LibraryInitProc Procbodytest_Init; MODULE_SCOPE Tcl_LibraryInitProc Procbodytest_SafeInit; MODULE_SCOPE Tcl_LibraryInitProc Tcl_ABSListTest_Init; | < | 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 | MODULE_SCOPE Tcl_LibraryInitProc TclplatformtestInit; MODULE_SCOPE Tcl_LibraryInitProc TclObjTest_Init; MODULE_SCOPE Tcl_LibraryInitProc TclThread_Init; MODULE_SCOPE Tcl_LibraryInitProc Procbodytest_Init; MODULE_SCOPE Tcl_LibraryInitProc Procbodytest_SafeInit; MODULE_SCOPE Tcl_LibraryInitProc Tcl_ABSListTest_Init; /* *---------------------------------------------------------------- * Macro used by the Tcl core to check whether a pattern has any characters * special to [string match]. The ANSI C "prototype" for this macro is: * * MODULE_SCOPE int TclMatchIsTrivial(const char *pattern); *---------------------------------------------------------------- |
| ︙ | ︙ | |||
4684 4685 4686 4687 4688 4689 4690 | * * MODULE_SCOPE void TclSetIntObj(Tcl_Obj *objPtr, Tcl_WideInt w); * MODULE_SCOPE void TclSetDoubleObj(Tcl_Obj *objPtr, double d); *---------------------------------------------------------------- */ #define TclSetIntObj(objPtr, i) \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 |
*
* MODULE_SCOPE void TclSetIntObj(Tcl_Obj *objPtr, Tcl_WideInt w);
* MODULE_SCOPE void TclSetDoubleObj(Tcl_Obj *objPtr, double d);
*----------------------------------------------------------------
*/
#define TclSetIntObj(objPtr, i) \
do { \
Tcl_ObjInternalRep ir; \
ir.wideValue = (Tcl_WideInt) i; \
TclInvalidateStringRep(objPtr); \
Tcl_StoreInternalRep(objPtr, &tclIntType, &ir); \
} while (0)
#define TclSetDoubleObj(objPtr, d) \
do { \
Tcl_ObjInternalRep ir; \
ir.doubleValue = (double) d; \
TclInvalidateStringRep(objPtr); \
Tcl_StoreInternalRep(objPtr, &tclDoubleType, &ir); \
} while (0)
/*
*----------------------------------------------------------------
* Macros used by the Tcl core to create and initialise objects of standard
* types, avoiding the corresponding function calls in time critical parts of
* the core. The ANSI C "prototypes" for these macros are:
*
* MODULE_SCOPE void TclNewIntObj(Tcl_Obj *objPtr, Tcl_WideInt w);
* MODULE_SCOPE void TclNewDoubleObj(Tcl_Obj *objPtr, double d);
* MODULE_SCOPE void TclNewStringObj(Tcl_Obj *objPtr, const char *s, Tcl_Size len);
* MODULE_SCOPE void TclNewLiteralStringObj(Tcl_Obj*objPtr, const char *sLiteral);
*
*----------------------------------------------------------------
*/
#ifndef TCL_MEM_DEBUG
#define TclNewIntObj(objPtr, w) \
do { \
TclIncrObjsAllocated(); \
TclAllocObjStorage(objPtr); \
(objPtr)->refCount = 0; \
(objPtr)->bytes = NULL; \
(objPtr)->internalRep.wideValue = (Tcl_WideInt)(w); \
(objPtr)->typePtr = &tclIntType; \
TCL_DTRACE_OBJ_CREATE(objPtr); \
} while (0)
#define TclNewUIntObj(objPtr, uw) \
do { \
TclIncrObjsAllocated(); \
TclAllocObjStorage(objPtr); \
(objPtr)->refCount = 0; \
(objPtr)->bytes = NULL; \
Tcl_WideUInt uw_ = (uw); \
if (uw_ > WIDE_MAX) { \
mp_int bignumValue_; \
if (mp_init_u64(&bignumValue_, uw_) != MP_OKAY) { \
Tcl_Panic("%s: memory overflow", "TclNewUIntObj"); \
} \
TclSetBignumInternalRep((objPtr), &bignumValue_); \
} else { \
(objPtr)->internalRep.wideValue = (Tcl_WideInt)(uw_); \
(objPtr)->typePtr = &tclIntType; \
} \
TCL_DTRACE_OBJ_CREATE(objPtr); \
} while (0)
#define TclNewIndexObj(objPtr, w) \
TclNewIntObj(objPtr, w)
#define TclNewDoubleObj(objPtr, d) \
do { \
TclIncrObjsAllocated(); \
TclAllocObjStorage(objPtr); \
(objPtr)->refCount = 0; \
(objPtr)->bytes = NULL; \
(objPtr)->internalRep.doubleValue = (double)(d); \
(objPtr)->typePtr = &tclDoubleType; \
TCL_DTRACE_OBJ_CREATE(objPtr); \
} while (0)
#define TclNewStringObj(objPtr, s, len) \
do { \
TclIncrObjsAllocated(); \
TclAllocObjStorage(objPtr); \
(objPtr)->refCount = 0; \
TclInitStringRep((objPtr), (s), (len)); \
(objPtr)->typePtr = NULL; \
TCL_DTRACE_OBJ_CREATE(objPtr); \
} while (0)
#else /* TCL_MEM_DEBUG */
#define TclNewIntObj(objPtr, w) \
(objPtr) = Tcl_NewWideIntObj(w)
#define TclNewUIntObj(objPtr, uw) \
do { \
Tcl_WideUInt uw_ = (uw); \
if (uw_ > WIDE_MAX) { \
mp_int bignumValue_; \
if (mp_init_u64(&bignumValue_, uw_) == MP_OKAY) { \
(objPtr) = Tcl_NewBignumObj(&bignumValue_); \
} else { \
(objPtr) = NULL; \
} \
} else { \
(objPtr) = Tcl_NewWideIntObj(uw_); \
} \
} while (0)
#define TclNewIndexObj(objPtr, w) \
TclNewIntObj(objPtr, w)
#define TclNewDoubleObj(objPtr, d) \
(objPtr) = Tcl_NewDoubleObj(d)
|
| ︙ | ︙ | |||
4837 4838 4839 4840 4841 4842 4843 | /* *---------------------------------------------------------------- * Inline version of TclCleanupCommand; still need the function as it is in * the internal stubs, but the core can use the macro instead. */ | | | | | | | > | | | | | | | | | 4869 4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 |
/*
*----------------------------------------------------------------
* Inline version of TclCleanupCommand; still need the function as it is in
* the internal stubs, but the core can use the macro instead.
*/
#define TclCleanupCommandMacro(cmdPtr) \
do { \
if ((cmdPtr)->refCount-- <= 1) { \
Tcl_Free(cmdPtr); \
} \
} while (0)
/*
* Inside this routine increment refCount first incase cmdPtr is replacing
* itself.
*/
#define TclRoutineAssign(location, cmdPtr) \
do { \
(cmdPtr)->refCount++; \
if ((location) != NULL \
&& (location--) <= 1) { \
Tcl_Free(((location))); \
} \
(location) = (cmdPtr); \
} while (0)
#define TclRoutineHasName(cmdPtr) \
((cmdPtr)->hPtr != NULL)
/*
|
| ︙ | ︙ |
Changes to generic/tclInterp.c.
| ︙ | ︙ | |||
182 183 184 185 186 187 188 |
* TIP#143 limit handler internal representation.
*/
struct LimitHandler {
int flags; /* The state of this particular handler. */
Tcl_LimitHandlerProc *handlerProc;
/* The handler callback. */
| | | 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
* TIP#143 limit handler internal representation.
*/
struct LimitHandler {
int flags; /* The state of this particular handler. */
Tcl_LimitHandlerProc *handlerProc;
/* The handler callback. */
void *clientData; /* Opaque argument to the handler callback. */
Tcl_LimitHandlerDeleteProc *deleteProc;
/* How to delete the clientData. */
LimitHandler *prevPtr; /* Previous item in linked list of
* handlers. */
LimitHandler *nextPtr; /* Next item in linked list of handlers. */
};
|
| ︙ | ︙ | |||
1194 1195 1196 1197 1198 1199 1200 |
int
Tcl_CreateAlias(
Tcl_Interp *childInterp, /* Interpreter for source command. */
const char *childCmd, /* Command to install in child. */
Tcl_Interp *targetInterp, /* Interpreter for target command. */
const char *targetCmd, /* Name of target command. */
| | | 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 |
int
Tcl_CreateAlias(
Tcl_Interp *childInterp, /* Interpreter for source command. */
const char *childCmd, /* Command to install in child. */
Tcl_Interp *targetInterp, /* Interpreter for target command. */
const char *targetCmd, /* Name of target command. */
Tcl_Size argc, /* How many additional arguments? */
const char *const *argv) /* These are the additional args. */
{
Tcl_Obj *childObjPtr, *targetObjPtr;
Tcl_Obj **objv;
Tcl_Size i;
int result;
|
| ︙ | ︙ | |||
1249 1250 1251 1252 1253 1254 1255 |
int
Tcl_CreateAliasObj(
Tcl_Interp *childInterp, /* Interpreter for source command. */
const char *childCmd, /* Command to install in child. */
Tcl_Interp *targetInterp, /* Interpreter for target command. */
const char *targetCmd, /* Name of target command. */
| | | 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 |
int
Tcl_CreateAliasObj(
Tcl_Interp *childInterp, /* Interpreter for source command. */
const char *childCmd, /* Command to install in child. */
Tcl_Interp *targetInterp, /* Interpreter for target command. */
const char *targetCmd, /* Name of target command. */
Tcl_Size objc, /* How many additional arguments? */
Tcl_Obj *const objv[]) /* Argument vector. */
{
Tcl_Obj *childObjPtr, *targetObjPtr;
int result;
childObjPtr = Tcl_NewStringObj(childCmd, -1);
Tcl_IncrRefCount(childObjPtr);
|
| ︙ | ︙ | |||
1817 1818 1819 1820 1821 1822 1823 | * forwarded. * *---------------------------------------------------------------------- */ static int AliasNRCmd( | | | 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 |
* forwarded.
*
*----------------------------------------------------------------------
*/
static int
AliasNRCmd(
void *clientData, /* Alias record. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument vector. */
{
Alias *aliasPtr = (Alias *)clientData;
int prefc, cmdc, i;
Tcl_Obj **prefv, **cmdv;
|
| ︙ | ︙ | |||
1870 1871 1872 1873 1874 1875 1876 |
}
TclSkipTailcall(interp);
return Tcl_NREvalObj(interp, listPtr, flags);
}
int
TclAliasObjCmd(
| | | 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 |
}
TclSkipTailcall(interp);
return Tcl_NREvalObj(interp, listPtr, flags);
}
int
TclAliasObjCmd(
void *clientData, /* Alias record. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument vector. */
{
#define ALIAS_CMDV_PREALLOC 10
Alias *aliasPtr = (Alias *)clientData;
Tcl_Interp *targetInterp = aliasPtr->targetInterp;
|
| ︙ | ︙ | |||
1961 1962 1963 1964 1965 1966 1967 |
}
return result;
#undef ALIAS_CMDV_PREALLOC
}
int
TclLocalAliasObjCmd(
| | | 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 |
}
return result;
#undef ALIAS_CMDV_PREALLOC
}
int
TclLocalAliasObjCmd(
void *clientData, /* Alias record. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument vector. */
{
#define ALIAS_CMDV_PREALLOC 10
Alias *aliasPtr = (Alias *)clientData;
int result, prefc, cmdc, i;
|
| ︙ | ︙ | |||
2046 2047 2048 2049 2050 2051 2052 | * interpreter. * *---------------------------------------------------------------------- */ static void AliasObjCmdDeleteProc( | | | 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 |
* interpreter.
*
*----------------------------------------------------------------------
*/
static void
AliasObjCmdDeleteProc(
void *clientData) /* The alias record for this alias. */
{
Alias *aliasPtr = (Alias *)clientData;
Target *targetPtr;
int i;
Tcl_Obj **objv;
Tcl_DecrRefCount(aliasPtr->token);
|
| ︙ | ︙ | |||
2547 2548 2549 2550 2551 2552 2553 | * See user documentation for details. * *---------------------------------------------------------------------- */ int TclChildObjCmd( | | | | 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 |
* See user documentation for details.
*
*----------------------------------------------------------------------
*/
int
TclChildObjCmd(
void *clientData, /* Child interpreter. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
return Tcl_NRCallObjProc(interp, NRChildCmd, clientData, objc, objv);
}
static int
NRChildCmd(
void *clientData, /* Child interpreter. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
Tcl_Interp *childInterp = (Tcl_Interp *)clientData;
static const char *const options[] = {
"alias", "aliases", "bgerror", "debug",
|
| ︙ | ︙ | |||
2761 2762 2763 2764 2765 2766 2767 | * the child interpreter. * *---------------------------------------------------------------------- */ static void ChildObjCmdDeleteProc( | | | 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 |
* the child interpreter.
*
*----------------------------------------------------------------------
*/
static void
ChildObjCmdDeleteProc(
void *clientData) /* The ChildRecord for the command. */
{
Child *childPtr; /* Interim storage for Child record. */
Tcl_Interp *childInterp = (Tcl_Interp *)clientData;
/* And for a child interp. */
childPtr = &((InterpInfo *) ((Interp *) childInterp)->interpInfo)->child;
|
| ︙ | ︙ |
Changes to generic/tclLink.c.
| ︙ | ︙ | |||
32 33 34 35 36 37 38 |
* needed during trace callbacks, since the
* actual variable may be aliased at that time
* via upvar. */
void *addr; /* Location of C variable. */
Tcl_Size bytes; /* Size of C variable array. This is 0 when
* single variables, and >0 used for array
* variables. */
| | | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
* needed during trace callbacks, since the
* actual variable may be aliased at that time
* via upvar. */
void *addr; /* Location of C variable. */
Tcl_Size bytes; /* Size of C variable array. This is 0 when
* single variables, and >0 used for array
* variables. */
Tcl_Size numElems; /* Number of elements in C variable array.
* Zero for single variables. */
int type; /* Type of link (TCL_LINK_INT, etc.). */
union {
char c;
unsigned char uc;
int i;
unsigned int ui;
|
| ︙ | ︙ | |||
676 677 678 679 680 681 682 | * modification. * *---------------------------------------------------------------------- */ static char * LinkTraceProc( | | | 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 |
* modification.
*
*----------------------------------------------------------------------
*/
static char *
LinkTraceProc(
void *clientData, /* Contains information about the link. */
Tcl_Interp *interp, /* Interpreter containing Tcl variable. */
TCL_UNUSED(const char *) /*name1*/,
TCL_UNUSED(const char *) /*name2*/,
/* Links can only be made to global variables,
* so we can find them with need to resolve
* caller-supplied name in caller context. */
int flags) /* Miscellaneous additional information. */
|
| ︙ | ︙ |
Changes to generic/tclListObj.c.
| ︙ | ︙ | |||
42 43 44 45 46 47 48 | #define LIST_ASSERT(cond_) assert(cond_) /* * LIST_INDEX_ASSERT is to catch errors with negative indices and counts * being passed AFTER validation. On Tcl9 length types are unsigned hence * the checks against LIST_MAX. On Tcl8 length types are signed hence the * also checks against 0. */ | | | | | | | | | | 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
#define LIST_ASSERT(cond_) assert(cond_)
/*
* LIST_INDEX_ASSERT is to catch errors with negative indices and counts
* being passed AFTER validation. On Tcl9 length types are unsigned hence
* the checks against LIST_MAX. On Tcl8 length types are signed hence the
* also checks against 0.
*/
#define LIST_INDEX_ASSERT(idxarg_) \
do { \
Tcl_Size idx_ = (idxarg_); /* To guard against ++ etc. */ \
LIST_ASSERT(idx_ >= 0 && idx_ < LIST_MAX); \
} while (0)
/* Ditto for counts except upper limit is different */
#define LIST_COUNT_ASSERT(countarg_) \
do { \
Tcl_Size count_ = (countarg_); /* To guard against ++ etc. */ \
LIST_ASSERT(count_ >= 0 && count_ <= LIST_MAX); \
} while (0)
#else
#define LIST_ASSERT(cond_) ((void) 0)
#define LIST_INDEX_ASSERT(idx_) ((void) 0)
#define LIST_COUNT_ASSERT(count_) ((void) 0)
|
| ︙ | ︙ | |||
107 108 109 110 111 112 113 |
*/
#define LISTREP_PANIC_ON_FAIL 0x00000001
#define LISTREP_SPACE_FAVOR_FRONT 0x00000002
#define LISTREP_SPACE_FAVOR_BACK 0x00000004
#define LISTREP_SPACE_ONLY_BACK 0x00000008
#define LISTREP_SPACE_FAVOR_NONE \
(LISTREP_SPACE_FAVOR_FRONT | LISTREP_SPACE_FAVOR_BACK)
| | | < < | < | < | 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
*/
#define LISTREP_PANIC_ON_FAIL 0x00000001
#define LISTREP_SPACE_FAVOR_FRONT 0x00000002
#define LISTREP_SPACE_FAVOR_BACK 0x00000004
#define LISTREP_SPACE_ONLY_BACK 0x00000008
#define LISTREP_SPACE_FAVOR_NONE \
(LISTREP_SPACE_FAVOR_FRONT | LISTREP_SPACE_FAVOR_BACK)
#define LISTREP_SPACE_FLAGS \
(LISTREP_SPACE_FAVOR_FRONT | LISTREP_SPACE_FAVOR_BACK \
| LISTREP_SPACE_ONLY_BACK)
/*
* Prototypes for non-inline static functions defined later in this file:
*/
static int MemoryAllocationError(Tcl_Interp *, size_t size);
static int ListLimitExceededError(Tcl_Interp *);
static ListStore *ListStoreNew(Tcl_Size objc, Tcl_Obj *const objv[], int flags);
static int ListRepInit(Tcl_Size objc, Tcl_Obj *const objv[], int flags, ListRep *);
static int ListRepInitAttempt(Tcl_Interp *,
Tcl_Size objc, Tcl_Obj *const objv[], ListRep *);
static void ListRepClone(ListRep *fromRepPtr, ListRep *toRepPtr, int flags);
static void ListRepUnsharedFreeUnreferenced(const ListRep *repPtr);
static int TclListObjGetRep(Tcl_Interp *, Tcl_Obj *listPtr, ListRep *repPtr);
static void ListRepRange(ListRep *srcRepPtr,
Tcl_Size rangeStart, Tcl_Size rangeEnd,
int preserveSrcRep, ListRep *rangeRepPtr);
static ListStore *ListStoreReallocate(ListStore *storePtr, Tcl_Size numSlots);
static void ListRepValidate(const ListRep *repPtr, const char *file,
int lineNum);
static void DupListInternalRep(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr);
static void FreeListInternalRep(Tcl_Obj *listPtr);
static int SetListFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
static void UpdateStringOfList(Tcl_Obj *listPtr);
|
| ︙ | ︙ | |||
156 157 158 159 160 161 162 |
DupListInternalRep, /* dupIntRepProc */
UpdateStringOfList, /* updateStringProc */
SetListFromAny, /* setFromAnyProc */
TCL_OBJTYPE_V1(ListLength)
};
/* Macros to manipulate the List internal rep */
| | | | | | > | | 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
DupListInternalRep, /* dupIntRepProc */
UpdateStringOfList, /* updateStringProc */
SetListFromAny, /* setFromAnyProc */
TCL_OBJTYPE_V1(ListLength)
};
/* Macros to manipulate the List internal rep */
#define ListRepIncrRefs(repPtr_) \
do { \
(repPtr_)->storePtr->refCount++; \
if ((repPtr_)->spanPtr) { \
(repPtr_)->spanPtr->refCount++; \
} \
} while (0)
/* Returns number of free unused slots at the back of the ListRep's ListStore */
#define ListRepNumFreeTail(repPtr_) \
((repPtr_)->storePtr->numAllocated \
- ((repPtr_)->storePtr->firstUsed + (repPtr_)->storePtr->numUsed))
/* Returns number of free unused slots at the front of the ListRep's ListStore */
#define ListRepNumFreeHead(repPtr_) ((repPtr_)->storePtr->firstUsed)
/* Returns a pointer to the slot corresponding to list index listIdx_ */
#define ListRepSlotPtr(repPtr_, listIdx_) \
|
| ︙ | ︙ | |||
194 195 196 197 198 199 200 | * the string representation of the Tcl_Obj is not to be modified. * * ListObjReplaceRepAndInvalidate - Like ListObjOverwriteRep but additionally * assumes the Tcl_Obj internal rep is valid (and possibly even same as * passed ListRep) and frees it first. Additionally invalidates the string * representation. Generally used when modifying a Tcl_Obj value. */ | | | | | | | | | | | | | | | | | | | 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 |
* the string representation of the Tcl_Obj is not to be modified.
*
* ListObjReplaceRepAndInvalidate - Like ListObjOverwriteRep but additionally
* assumes the Tcl_Obj internal rep is valid (and possibly even same as
* passed ListRep) and frees it first. Additionally invalidates the string
* representation. Generally used when modifying a Tcl_Obj value.
*/
#define ListObjStompRep(objPtr_, repPtr_) \
do { \
(objPtr_)->internalRep.twoPtrValue.ptr1 = (repPtr_)->storePtr; \
(objPtr_)->internalRep.twoPtrValue.ptr2 = (repPtr_)->spanPtr; \
(objPtr_)->typePtr = &tclListType; \
} while (0)
#define ListObjOverwriteRep(objPtr_, repPtr_) \
do { \
ListRepIncrRefs(repPtr_); \
ListObjStompRep(objPtr_, repPtr_); \
} while (0)
#define ListObjReplaceRepAndInvalidate(objPtr_, repPtr_) \
do { \
/* Note order important, don't use ListObjOverwriteRep! */ \
ListRepIncrRefs(repPtr_); \
TclFreeInternalRep(objPtr_); \
TclInvalidateStringRep(objPtr_); \
ListObjStompRep(objPtr_, repPtr_); \
} while (0)
/*
*------------------------------------------------------------------------
*
* ListSpanNew --
*
* Allocates and initializes memory for a new ListSpan. The reference
* count on the returned struct is 0.
*
* Results:
* Non-NULL pointer to the allocated ListSpan.
*
* Side effects:
* The function will panic on memory allocation failure.
*
*------------------------------------------------------------------------
*/
static inline ListSpan *
ListSpanNew(
Tcl_Size firstSlot, /* Starting slot index of the span */
Tcl_Size numSlots) /* Number of slots covered by the span */
{
ListSpan *spanPtr = (ListSpan *) Tcl_Alloc(sizeof(*spanPtr));
spanPtr->refCount = 0;
spanPtr->spanStart = firstSlot;
spanPtr->spanLength = numSlots;
return spanPtr;
}
|
| ︙ | ︙ | |||
261 262 263 264 265 266 267 | * * Side effects: * The memory may be freed. * *------------------------------------------------------------------------ */ static inline void | | > | 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 |
*
* Side effects:
* The memory may be freed.
*
*------------------------------------------------------------------------
*/
static inline void
ListSpanDecrRefs(
ListSpan *spanPtr)
{
if (spanPtr->refCount <= 1) {
Tcl_Free(spanPtr);
} else {
spanPtr->refCount -= 1;
}
}
|
| ︙ | ︙ | |||
292 293 294 295 296 297 298 | * Side effects: * None. * *------------------------------------------------------------------------ */ static inline int ListSpanMerited( | | | | > | 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 |
* Side effects:
* None.
*
*------------------------------------------------------------------------
*/
static inline int
ListSpanMerited(
Tcl_Size length, /* Length of the proposed span */
Tcl_Size usedStorageLength, /* Number of slots currently in used */
Tcl_Size allocatedStorageLength)
/* Length of the current allocation */
{
/*
* Possible optimizations for future consideration
* - heuristic LIST_SPAN_THRESHOLD
* - currently, information about the sharing (ref count) of existing
* storage is not passed. Perhaps it should be. For example if the
* existing storage has a "large" ref count, then it might make sense
|
| ︙ | ︙ | |||
338 339 340 341 342 343 344 | * * Side effects: * See comments for ListRepUnsharedFreeUnreferenced. * *------------------------------------------------------------------------ */ static inline void | | > | 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 |
*
* Side effects:
* See comments for ListRepUnsharedFreeUnreferenced.
*
*------------------------------------------------------------------------
*/
static inline void
ListRepFreeUnreferenced(
const ListRep *repPtr)
{
if (! ListRepIsShared(repPtr) && repPtr->spanPtr) {
/* T:listrep-1.5.1 */
ListRepUnsharedFreeUnreferenced(repPtr);
}
}
|
| ︙ | ︙ | |||
363 364 365 366 367 368 369 | * Side effects: * As above. * *------------------------------------------------------------------------ */ static inline void ObjArrayIncrRefs( | | | | | 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 |
* Side effects:
* As above.
*
*------------------------------------------------------------------------
*/
static inline void
ObjArrayIncrRefs(
Tcl_Obj * const *objv, /* Pointer to the array */
Tcl_Size startIdx, /* Starting index of subarray within objv */
Tcl_Size count) /* Number of elements in the subarray */
{
Tcl_Obj *const *end;
LIST_INDEX_ASSERT(startIdx);
LIST_COUNT_ASSERT(count);
objv += startIdx;
end = objv + count;
while (objv < end) {
|
| ︙ | ︙ | |||
395 396 397 398 399 400 401 | * Side effects: * As above. * *------------------------------------------------------------------------ */ static inline void ObjArrayDecrRefs( | | | | | 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 |
* Side effects:
* As above.
*
*------------------------------------------------------------------------
*/
static inline void
ObjArrayDecrRefs(
Tcl_Obj * const *objv, /* Pointer to the array */
Tcl_Size startIdx, /* Starting index of subarray within objv */
Tcl_Size count) /* Number of elements in the subarray */
{
Tcl_Obj * const *end;
LIST_INDEX_ASSERT(startIdx);
LIST_COUNT_ASSERT(count);
objv += startIdx;
end = objv + count;
while (objv < end) {
|
| ︙ | ︙ | |||
427 428 429 430 431 432 433 | * Side effects: * Reference counts on copied Tcl_Obj's are incremented. * *------------------------------------------------------------------------ */ static inline void ObjArrayCopy( | | | | | 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 |
* Side effects:
* Reference counts on copied Tcl_Obj's are incremented.
*
*------------------------------------------------------------------------
*/
static inline void
ObjArrayCopy(
Tcl_Obj **to, /* Destination */
Tcl_Size count, /* Number of pointers to copy */
Tcl_Obj *const from[]) /* Source array of Tcl_Obj* */
{
Tcl_Obj **end;
LIST_COUNT_ASSERT(count);
end = to + count;
/* TODO - would memmove followed by separate IncrRef loop be faster? */
while (to < end) {
Tcl_IncrRefCount(*from);
|
| ︙ | ︙ | |||
458 459 460 461 462 463 464 | * Side effects: * Error message and code are stored in the interpreter if not NULL. * *------------------------------------------------------------------------ */ static int MemoryAllocationError( | | | | | | 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 |
* Side effects:
* Error message and code are stored in the interpreter if not NULL.
*
*------------------------------------------------------------------------
*/
static int
MemoryAllocationError(
Tcl_Interp *interp, /* Interpreter for error message. May be NULL */
size_t size) /* Size of attempted allocation that failed */
{
if (interp != NULL) {
Tcl_SetObjResult(
interp,
Tcl_ObjPrintf(
"list construction failed: "
"unable to alloc %" TCL_Z_MODIFIER "u bytes",
size));
Tcl_SetErrorCode(interp, "TCL", "MEMORY", (void *)NULL);
}
return TCL_ERROR;
}
/*
|
| ︙ | ︙ | |||
492 493 494 495 496 497 498 |
*
*------------------------------------------------------------------------
*/
static int
ListLimitExceededError(Tcl_Interp *interp)
{
if (interp != NULL) {
| | < | 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 |
*
*------------------------------------------------------------------------
*/
static int
ListLimitExceededError(Tcl_Interp *interp)
{
if (interp != NULL) {
Tcl_SetObjResult(interp,
Tcl_NewStringObj("max length of a Tcl list exceeded", -1));
Tcl_SetErrorCode(interp, "TCL", "MEMORY", (void *)NULL);
}
return TCL_ERROR;
}
/*
|
| ︙ | ︙ | |||
520 521 522 523 524 525 526 | * Side effects: * The contents of the ListRep's ListStore area are shifted down in the * storage area. The ListRep's ListSpan is updated accordingly. * *------------------------------------------------------------------------ */ static inline void | | > > | 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 |
* Side effects:
* The contents of the ListRep's ListStore area are shifted down in the
* storage area. The ListRep's ListSpan is updated accordingly.
*
*------------------------------------------------------------------------
*/
static inline void
ListRepUnsharedShiftDown(
ListRep *repPtr,
Tcl_Size shiftCount)
{
ListStore *storePtr;
LISTREP_CHECK(repPtr);
LIST_ASSERT(!ListRepIsShared(repPtr));
storePtr = repPtr->storePtr;
|
| ︙ | ︙ | |||
621 622 623 624 625 626 627 | * * Side effects: * Panics if any invariant is not met. * *------------------------------------------------------------------------ */ static void | | > > > | | | | | | | 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 |
*
* Side effects:
* Panics if any invariant is not met.
*
*------------------------------------------------------------------------
*/
static void
ListRepValidate(
const ListRep *repPtr,
const char *file,
int lineNum)
{
ListStore *storePtr = repPtr->storePtr;
const char *condition;
(void)storePtr; /* To stop gcc from whining about unused vars */
#define INVARIANT(cond_) \
do { \
if (!(cond_)) { \
condition = #cond_; \
goto failure; \
} \
} while (0)
/* Separate each condition so line number gives exact reason for failure */
INVARIANT(storePtr != NULL);
INVARIANT(storePtr->numAllocated >= 0);
INVARIANT(storePtr->numAllocated <= LIST_MAX);
INVARIANT(storePtr->firstUsed >= 0);
|
| ︙ | ︙ | |||
664 665 666 667 668 669 670 |
#undef INVARIANT
return;
failure:
Tcl_Panic("List internal failure in %s line %d. Condition: %s",
| < < | | > > | 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 |
#undef INVARIANT
return;
failure:
Tcl_Panic("List internal failure in %s line %d. Condition: %s",
file, lineNum, condition);
}
/*
*------------------------------------------------------------------------
*
* TclListObjValidate --
*
* Wrapper around ListRepValidate. Primarily used from test suite.
*
* Results:
* None.
*
* Side effects:
* Will panic if internal structure is not consistent or if object
* cannot be converted to a list object.
*
*------------------------------------------------------------------------
*/
void
TclListObjValidate(
Tcl_Interp *interp,
Tcl_Obj *listObj)
{
ListRep listRep;
if (TclListObjGetRep(interp, listObj, &listRep) != TCL_OK) {
Tcl_Panic("Object passed to TclListObjValidate cannot be converted to "
"a list object.");
}
ListRepValidate(&listRep, __FILE__, __LINE__);
|
| ︙ | ︙ | |||
753 754 755 756 757 758 759 |
} else {
/* Exact allocation */
capacity = objc;
storePtr = (ListStore *)Tcl_AttemptAlloc(LIST_SIZE(capacity));
}
if (storePtr == NULL) {
if (flags & LISTREP_PANIC_ON_FAIL) {
| | | | 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 |
} else {
/* Exact allocation */
capacity = objc;
storePtr = (ListStore *)Tcl_AttemptAlloc(LIST_SIZE(capacity));
}
if (storePtr == NULL) {
if (flags & LISTREP_PANIC_ON_FAIL) {
Tcl_Panic("list creation failed: "
"unable to alloc %" TCL_SIZE_MODIFIER "d bytes",
LIST_SIZE(objc));
}
return NULL;
}
storePtr->refCount = 0;
storePtr->flags = 0;
|
| ︙ | ︙ | |||
814 815 816 817 818 819 820 | * The memory pointed to by storePtr is freed if it a new block has to * be returned. * * *------------------------------------------------------------------------ */ ListStore * | | > > | < | < < | 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 |
* The memory pointed to by storePtr is freed if it a new block has to
* be returned.
*
*
*------------------------------------------------------------------------
*/
ListStore *
ListStoreReallocate(
ListStore *storePtr,
Tcl_Size needed)
{
Tcl_Size capacity;
if (needed > LIST_MAX) {
return NULL;
}
storePtr = (ListStore *) TclAttemptReallocElemsEx(storePtr, needed,
sizeof(Tcl_Obj *), offsetof(ListStore, slots), &capacity);
/* Only the capacity has changed, fix it in the header */
if (storePtr) {
storePtr->numAllocated = capacity;
}
return storePtr;
}
|
| ︙ | ︙ | |||
869 870 871 872 873 874 875 |
*----------------------------------------------------------------------
*/
static int
ListRepInit(
Tcl_Size objc,
Tcl_Obj *const objv[],
int flags,
| | < | 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 |
*----------------------------------------------------------------------
*/
static int
ListRepInit(
Tcl_Size objc,
Tcl_Obj *const objv[],
int flags,
ListRep *repPtr)
{
ListStore *storePtr;
storePtr = ListStoreNew(objc, objv, flags);
if (storePtr) {
repPtr->storePtr = storePtr;
if (storePtr->firstUsed == 0) {
|
| ︙ | ︙ | |||
960 961 962 963 964 965 966 | * The toRepPtr location is initialized with the ListStore and ListSpan * (if needed) containing a copy of the list elements in fromRepPtr. * The function will panic if memory cannot be allocated. * *------------------------------------------------------------------------ */ static void | | > > > | 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 |
* The toRepPtr location is initialized with the ListStore and ListSpan
* (if needed) containing a copy of the list elements in fromRepPtr.
* The function will panic if memory cannot be allocated.
*
*------------------------------------------------------------------------
*/
static void
ListRepClone(
ListRep *fromRepPtr,
ListRep *toRepPtr,
int flags)
{
Tcl_Obj **fromObjs;
Tcl_Size numFrom;
ListRepElements(fromRepPtr, numFrom, fromObjs);
ListRepInit(numFrom, fromObjs, flags | LISTREP_PANIC_ON_FAIL, toRepPtr);
}
|
| ︙ | ︙ | |||
989 990 991 992 993 994 995 | * * Side effects: * The firstUsed and numUsed fields of the ListStore are updated to * reflect the new "in-use" extent. * *------------------------------------------------------------------------ */ | > | > | 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 |
*
* Side effects:
* The firstUsed and numUsed fields of the ListStore are updated to
* reflect the new "in-use" extent.
*
*------------------------------------------------------------------------
*/
static void
ListRepUnsharedFreeUnreferenced(
const ListRep *repPtr)
{
Tcl_Size count;
ListStore *storePtr;
ListSpan *spanPtr;
LIST_ASSERT(!ListRepIsShared(repPtr));
LISTREP_CHECK(repPtr);
|
| ︙ | ︙ | |||
1385 1386 1387 1388 1389 1390 1391 | * to get wrong. Mostly due to refcount combinations. Perhaps passing * in the source listObj instead of source listRep might simplify. * *------------------------------------------------------------------------ */ static void ListRepRange( | | | | | | | | | 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 |
* to get wrong. Mostly due to refcount combinations. Perhaps passing
* in the source listObj instead of source listRep might simplify.
*
*------------------------------------------------------------------------
*/
static void
ListRepRange(
ListRep *srcRepPtr, /* Contains source of the range */
Tcl_Size rangeStart, /* Index of first element to include */
Tcl_Size rangeEnd, /* Index of last element to include */
int preserveSrcRep, /* If true, srcRepPtr contents must not be
* modified (generally because a shared Tcl_Obj
* references it) */
ListRep *rangeRepPtr) /* Output. Must NOT be == srcRepPtr */
{
Tcl_Obj **srcElems;
Tcl_Size numSrcElems = ListRepLength(srcRepPtr);
Tcl_Size rangeLen;
Tcl_Size numAfterRangeEnd;
LISTREP_CHECK(srcRepPtr);
|
| ︙ | ︙ | |||
1666 1667 1668 1669 1670 1671 1672 |
{
ListRep listRep;
if (TclObjTypeHasProc(objPtr, getElementsProc)) {
return TclObjTypeGetElements(interp, objPtr, objcPtr, objvPtr);
}
if (TclListObjGetRep(interp, objPtr, &listRep) != TCL_OK) {
| | | 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 |
{
ListRep listRep;
if (TclObjTypeHasProc(objPtr, getElementsProc)) {
return TclObjTypeGetElements(interp, objPtr, objcPtr, objvPtr);
}
if (TclListObjGetRep(interp, objPtr, &listRep) != TCL_OK) {
return TCL_ERROR;
}
ListRepElements(&listRep, *objcPtr, *objvPtr);
return TCL_OK;
}
/*
*----------------------------------------------------------------------
|
| ︙ | ︙ | |||
1728 1729 1730 1731 1732 1733 1734 | * * TclListObjAppendElements -- * * Appends multiple elements to a Tcl_Obj list object. If * the passed Tcl_Obj is not a list object, it will be converted to one * and an error raised if the conversion fails. * | | | > | | | 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 |
*
* TclListObjAppendElements --
*
* Appends multiple elements to a Tcl_Obj list object. If
* the passed Tcl_Obj is not a list object, it will be converted to one
* and an error raised if the conversion fails.
*
* The Tcl_Obj must not be shared though the internal representation
* may be.
*
* Results:
* On success, TCL_OK is returned with the specified elements appended.
* On failure, TCL_ERROR is returned with an error message in the
* interpreter if not NULL.
*
* Side effects:
* None.
*
*------------------------------------------------------------------------
*/
int
TclListObjAppendElements (
Tcl_Interp *interp, /* Used to report errors if not NULL. */
Tcl_Obj *toObj, /* List object to append */
Tcl_Size elemCount, /* Number of elements in elemObjs[] */
Tcl_Obj * const elemObjv[]) /* Objects to append to toObj's list. */
{
ListRep listRep;
Tcl_Obj **toObjv;
Tcl_Size toLen;
Tcl_Size finalLen;
|
| ︙ | ︙ | |||
1841 1842 1843 1844 1845 1846 1847 |
/*
* Have to make a new list rep, either shared or no room in old one.
* If the old list did not have a span (all elements at front), do
* not leave space in the front either, assuming all appends and no
* prepends.
*/
| | < | < | < | 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 |
/*
* Have to make a new list rep, either shared or no room in old one.
* If the old list did not have a span (all elements at front), do
* not leave space in the front either, assuming all appends and no
* prepends.
*/
if (ListRepInit(finalLen, NULL,
listRep.spanPtr ? LISTREP_SPACE_FAVOR_BACK : LISTREP_SPACE_ONLY_BACK,
&listRep) != TCL_OK) {
return MemoryAllocationError(interp, finalLen);
}
LIST_ASSERT(listRep.storePtr->numAllocated >= finalLen);
if (toLen) {
/* T:listrep-2.{2,9},4.5 */
ObjArrayCopy(ListRepSlotPtr(&listRep, 0), toLen, toObjv);
|
| ︙ | ︙ | |||
1914 1915 1916 1917 1918 1919 1920 | } /* *---------------------------------------------------------------------- * * Tcl_ListObjIndex -- * | | | | | | | | | | | | | 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 |
}
/*
*----------------------------------------------------------------------
*
* Tcl_ListObjIndex --
*
* Retrieve a pointer to the element of 'listPtr' at 'index'. The index
* of the first element is 0.
*
* Value
*
* TCL_OK
*
* A pointer to the element at 'index' is stored in 'objPtrPtr'. If
* 'index' is out of range, NULL is stored in 'objPtrPtr'. This
* object should be treated as readonly and its 'refCount' is _not_
* incremented. The caller must do that if it holds on to the
* reference.
*
* TCL_ERROR
*
* 'listPtr' is not a valid list. An error message is left in the
* interpreter's result if 'interp' is not NULL.
*
* Effect
*
* If 'listPtr' is not already of type 'tclListType', it is converted.
*
*----------------------------------------------------------------------
*/
int
Tcl_ListObjIndex(
Tcl_Interp *interp, /* Used to report errors if not NULL. */
Tcl_Obj *listObj, /* List object to index into. */
Tcl_Size index, /* Index of element to return. */
Tcl_Obj **objPtrPtr) /* The resulting Tcl_Obj* is stored here. */
{
Tcl_Obj **elemObjs;
Tcl_Size numElems;
/* Empty string => empty list. Avoid unnecessary shimmering */
if (listObj->bytes == &tclEmptyString) {
*objPtrPtr = NULL;
|
| ︙ | ︙ | |||
1997 1998 1999 2000 2001 2002 2003 | * *---------------------------------------------------------------------- */ #undef Tcl_ListObjLength int Tcl_ListObjLength( | | | | | 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 |
*
*----------------------------------------------------------------------
*/
#undef Tcl_ListObjLength
int
Tcl_ListObjLength(
Tcl_Interp *interp, /* Used to report errors if not NULL. */
Tcl_Obj *listObj, /* List object whose #elements to return. */
Tcl_Size *lenPtr) /* The resulting length is stored here. */
{
ListRep listRep;
/* Empty string => empty list. Avoid unnecessary shimmering */
if (listObj->bytes == &tclEmptyString) {
*lenPtr = 0;
return TCL_OK;
|
| ︙ | ︙ | |||
2564 2565 2566 2567 2568 2569 2570 |
*/
Tcl_Obj *
TclLindexList(
Tcl_Interp *interp, /* Tcl interpreter. */
Tcl_Obj *listObj, /* List being unpacked. */
Tcl_Obj *argObj) /* Index or index list. */
{
| | | 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 |
*/
Tcl_Obj *
TclLindexList(
Tcl_Interp *interp, /* Tcl interpreter. */
Tcl_Obj *listObj, /* List being unpacked. */
Tcl_Obj *argObj) /* Index or index list. */
{
Tcl_Size index; /* Index into the list. */
Tcl_Obj *indexListCopy;
Tcl_Obj **indexObjs;
Tcl_Size numIndexObjs;
/*
* Determine whether argPtr designates a list or a single index. We have
* to be careful about the order of the checks to avoid repeated
|
| ︙ | ︙ | |||
2768 2769 2770 2771 2772 2773 2774 |
Tcl_Obj *
TclLsetList(
Tcl_Interp *interp, /* Tcl interpreter. */
Tcl_Obj *listObj, /* Pointer to the list being modified. */
Tcl_Obj *indexArgObj, /* Index or index-list arg to 'lset'. */
Tcl_Obj *valueObj) /* Value arg to 'lset' or NULL to 'lpop'. */
{
| | | | 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 |
Tcl_Obj *
TclLsetList(
Tcl_Interp *interp, /* Tcl interpreter. */
Tcl_Obj *listObj, /* Pointer to the list being modified. */
Tcl_Obj *indexArgObj, /* Index or index-list arg to 'lset'. */
Tcl_Obj *valueObj) /* Value arg to 'lset' or NULL to 'lpop'. */
{
Tcl_Size indexCount = 0; /* Number of indices in the index list. */
Tcl_Obj **indices = NULL; /* Vector of indices in the index list. */
Tcl_Obj *retValueObj; /* Pointer to the list to be returned. */
Tcl_Size index; /* Current index in the list - discarded. */
Tcl_Obj *indexListCopy;
/*
* Determine whether the index arg designates a list or a single index.
* We have to be careful about the order of the checks to avoid repeated
* shimmering; see TIP #22 and #23 for details.
*/
|
| ︙ | ︙ | |||
2870 2871 2872 2873 2874 2875 2876 |
*
*----------------------------------------------------------------------
*/
Tcl_Obj *
TclLsetFlat(
Tcl_Interp *interp, /* Tcl interpreter. */
Tcl_Obj *listObj, /* Pointer to the list being modified. */
| | | < | 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 |
*
*----------------------------------------------------------------------
*/
Tcl_Obj *
TclLsetFlat(
Tcl_Interp *interp, /* Tcl interpreter. */
Tcl_Obj *listObj, /* Pointer to the list being modified. */
Tcl_Size indexCount, /* Number of index args. */
Tcl_Obj *const indexArray[],/* Index args. */
Tcl_Obj *valueObj) /* Value arg to 'lset' or NULL to 'lpop'. */
{
Tcl_Size index, len;
int result;
Tcl_Obj *subListObj, *retValueObj;
Tcl_Obj *pendingInvalidates[10];
Tcl_Obj **pendingInvalidatesPtr = pendingInvalidates;
|
| ︙ | ︙ | |||
2969 2970 2971 2972 2973 2974 2975 |
if ((index == TCL_SIZE_MAX) && (elemCount == 0)) {
index = 0;
}
if (index < 0 || index > elemCount
|| (valueObj == NULL && index >= elemCount)) {
/* ...the index points outside the sublist. */
if (interp != NULL) {
| | | | < < < | | | 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 |
if ((index == TCL_SIZE_MAX) && (elemCount == 0)) {
index = 0;
}
if (index < 0 || index > elemCount
|| (valueObj == NULL && index >= elemCount)) {
/* ...the index points outside the sublist. */
if (interp != NULL) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"index \"%s\" out of range",
Tcl_GetString(indexArray[-1])));
Tcl_SetErrorCode(interp,
"TCL", "VALUE", "INDEX" "OUTOFRANGE",
(void *)NULL);
}
result = TCL_ERROR;
break;
}
/*
* No error conditions. As long as we're not yet on the last index,
|
| ︙ | ︙ | |||
3574 3575 3576 3577 3578 3579 3580 | * * Side effects: * None. * *------------------------------------------------------------------------ */ Tcl_Obj * | | > > > | 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 |
*
* Side effects:
* None.
*
*------------------------------------------------------------------------
*/
Tcl_Obj *
TclListTestObj(
size_t length,
size_t leadingSpace,
size_t endSpace)
{
ListRep listRep;
size_t capacity;
Tcl_Obj *listObj;
TclNewObj(listObj);
|
| ︙ | ︙ |
Changes to generic/tclLiteral.c.
| ︙ | ︙ | |||
172 173 174 175 176 177 178 |
*
*----------------------------------------------------------------------
*/
Tcl_Obj *
TclCreateLiteral(
Interp *iPtr,
| | | | | | 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
*
*----------------------------------------------------------------------
*/
Tcl_Obj *
TclCreateLiteral(
Interp *iPtr,
const char *bytes, /* The start of the string. Note that this is
* not a NUL-terminated string. */
Tcl_Size length, /* Number of bytes in the string. */
size_t hash, /* The string's hash. If the value is
* TCL_INDEX_NONE, it will be computed here. */
int *newPtr,
Namespace *nsPtr,
int flags,
LiteralEntry **globalPtrPtr)
{
LiteralTable *globalTablePtr = &iPtr->literalTable;
LiteralEntry *globalPtr;
|
| ︙ | ︙ | |||
385 386 387 388 389 390 391 | * buffer holding the result of backslash substitutions. * *---------------------------------------------------------------------- */ int /* Do NOT change this type. Should not be wider than TclEmitPush operand*/ TclRegisterLiteral( | | | | | 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 |
* buffer holding the result of backslash substitutions.
*
*----------------------------------------------------------------------
*/
int /* Do NOT change this type. Should not be wider than TclEmitPush operand*/
TclRegisterLiteral(
void *ePtr, /* Points to the CompileEnv in whose object
* array an object is found or created. */
const char *bytes, /* Points to string for which to find or
* create an object in CompileEnv's object
* array. */
Tcl_Size length, /* Number of bytes in the string. If -1, the
* string consists of all bytes up to the
* first null character. */
int flags) /* If LITERAL_ON_HEAP then the caller already
* malloc'd bytes and ownership is passed to
* this function. If LITERAL_CMD_NAME then
* the literal should not be shared across
* namespaces. */
|
| ︙ | ︙ | |||
549 550 551 552 553 554 555 |
*----------------------------------------------------------------------
*/
void
TclHideLiteral(
Tcl_Interp *interp, /* Interpreter for which objPtr was created to
* hold a literal. */
| | | 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 |
*----------------------------------------------------------------------
*/
void
TclHideLiteral(
Tcl_Interp *interp, /* Interpreter for which objPtr was created to
* hold a literal. */
CompileEnv *envPtr, /* Points to CompileEnv whose literal array
* contains the entry being hidden. */
int index) /* The index of the entry in the literal
* array. */
{
LiteralEntry **nextPtrPtr, *entryPtr, *lPtr;
LiteralTable *localTablePtr = &envPtr->localLitTable;
size_t localHash;
|
| ︙ | ︙ | |||
613 614 615 616 617 618 619 | * literal object. * *---------------------------------------------------------------------- */ int TclAddLiteralObj( | | | 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 |
* literal object.
*
*----------------------------------------------------------------------
*/
int
TclAddLiteralObj(
CompileEnv *envPtr, /* Points to CompileEnv in whose literal array
* the object is to be inserted. */
Tcl_Obj *objPtr, /* The object to insert into the array. */
LiteralEntry **litPtrPtr) /* The location where the pointer to the new
* literal entry should be stored. May be
* NULL. */
{
LiteralEntry *lPtr;
|
| ︙ | ︙ | |||
666 667 668 669 670 671 672 | * array of the CompileEnv's literal array if it becomes too large. * *---------------------------------------------------------------------- */ static size_t AddLocalLiteralEntry( | | | 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 |
* array of the CompileEnv's literal array if it becomes too large.
*
*----------------------------------------------------------------------
*/
static size_t
AddLocalLiteralEntry(
CompileEnv *envPtr, /* Points to CompileEnv in whose literal array
* the object is to be inserted. */
Tcl_Obj *objPtr, /* The literal to add to the CompileEnv. */
int localHash) /* Hash value for the literal's string. */
{
LiteralTable *localTablePtr = &envPtr->localLitTable;
LiteralEntry *localPtr;
size_t objIndex;
|
| ︙ | ︙ | |||
744 745 746 747 748 749 750 | * The local literal table is updated to refer to the new entries. * *---------------------------------------------------------------------- */ static void ExpandLocalLiteralArray( | | | 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 |
* The local literal table is updated to refer to the new entries.
*
*----------------------------------------------------------------------
*/
static void
ExpandLocalLiteralArray(
CompileEnv *envPtr) /* Points to the CompileEnv whose object array
* must be enlarged. */
{
/*
* The current allocated local literal entries are stored between elements
* 0 and (envPtr->literalArrayNext - 1) [inclusive].
*/
|
| ︙ | ︙ | |||
826 827 828 829 830 831 832 |
*----------------------------------------------------------------------
*/
void
TclReleaseLiteral(
Tcl_Interp *interp, /* Interpreter for which objPtr was created to
* hold a literal. */
| | | 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 |
*----------------------------------------------------------------------
*/
void
TclReleaseLiteral(
Tcl_Interp *interp, /* Interpreter for which objPtr was created to
* hold a literal. */
Tcl_Obj *objPtr) /* Points to a literal object that was
* previously created by a call to
* TclRegisterLiteral. */
{
Interp *iPtr = (Interp *) interp;
LiteralTable *globalTablePtr;
LiteralEntry *entryPtr, *prevPtr;
const char *bytes;
|
| ︙ | ︙ | |||
906 907 908 909 910 911 912 | * None. * *---------------------------------------------------------------------- */ static size_t HashString( | | | | 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 |
* None.
*
*----------------------------------------------------------------------
*/
static size_t
HashString(
const char *string, /* String for which to compute hash value. */
size_t length) /* Number of bytes in the string. */
{
size_t result = 0;
/*
* I tried a zillion different hash functions and asked many other people
* for advice. Many people had their own favorite functions, all
* different, but no-one had much idea why they were good ones. I chose
|
| ︙ | ︙ | |||
970 971 972 973 974 975 976 | * Memory gets reallocated and entries get rehashed into new buckets. * *---------------------------------------------------------------------- */ static void RebuildLiteralTable( | | < | 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 |
* Memory gets reallocated and entries get rehashed into new buckets.
*
*----------------------------------------------------------------------
*/
static void
RebuildLiteralTable(
LiteralTable *tablePtr) /* Local or global table to enlarge. */
{
LiteralEntry **oldBuckets;
LiteralEntry **oldChainPtr, **newChainPtr;
LiteralEntry *entryPtr;
LiteralEntry **bucketPtr;
const char *bytes;
size_t oldSize, count, index;
|
| ︙ | ︙ |
Changes to generic/tclLoad.c.
| ︙ | ︙ | |||
416 417 418 419 420 421 422 | libraryPtr->fileName = (char *)Tcl_Alloc(len); memcpy(libraryPtr->fileName, fullFileName, len); len = Tcl_DStringLength(&pfx) + 1; libraryPtr->prefix = (char *)Tcl_Alloc(len); memcpy(libraryPtr->prefix, Tcl_DStringValue(&pfx), len); libraryPtr->loadHandle = loadHandle; libraryPtr->initProc = initProc; | | | | | | 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 | libraryPtr->fileName = (char *)Tcl_Alloc(len); memcpy(libraryPtr->fileName, fullFileName, len); len = Tcl_DStringLength(&pfx) + 1; libraryPtr->prefix = (char *)Tcl_Alloc(len); memcpy(libraryPtr->prefix, Tcl_DStringValue(&pfx), len); libraryPtr->loadHandle = loadHandle; libraryPtr->initProc = initProc; libraryPtr->safeInitProc = (Tcl_LibraryInitProc *) Tcl_FindSymbol(interp, loadHandle, Tcl_DStringValue(&safeInitName)); libraryPtr->unloadProc = (Tcl_LibraryUnloadProc *) Tcl_FindSymbol(interp, loadHandle, Tcl_DStringValue(&unloadName)); libraryPtr->safeUnloadProc = (Tcl_LibraryUnloadProc *) Tcl_FindSymbol(interp, loadHandle, Tcl_DStringValue(&safeUnloadName)); libraryPtr->interpRefCount = 0; libraryPtr->safeInterpRefCount = 0; Tcl_MutexLock(&libraryMutex); libraryPtr->nextPtr = firstLibraryPtr; firstLibraryPtr = libraryPtr; Tcl_MutexUnlock(&libraryMutex); /* * The Tcl_FindSymbol calls may have left a spurious error message in * the interpreter result. */ |
| ︙ | ︙ | |||
749 750 751 752 753 754 755 |
Tcl_DStringFree(&tmp);
if (!complain && (code != TCL_OK)) {
code = TCL_OK;
Tcl_ResetResult(interp);
}
return code;
}
| < > | | | | | | < | 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 |
Tcl_DStringFree(&tmp);
if (!complain && (code != TCL_OK)) {
code = TCL_OK;
Tcl_ResetResult(interp);
}
return code;
}
/*
*----------------------------------------------------------------------
*
* UnloadLibrary --
*
* Unloads a library from an interpreter, and also from the process if it
* is unloadable, i.e. if it provides an "unload" function.
*
* Results:
* A standard Tcl result.
*
* Side effects:
* See description.
*
*----------------------------------------------------------------------
*/
static int
UnloadLibrary(
Tcl_Interp *interp,
Tcl_Interp *target,
LoadedLibrary *libraryPtr,
int keepLibrary,
const char *fullFileName,
int interpExiting)
{
int code;
InterpLibrary *ipFirstPtr, *ipPtr;
LoadedLibrary *iterLibraryPtr;
int trustedRefCount = -1, safeRefCount = -1;
Tcl_LibraryUnloadProc *unloadProc = NULL;
|
| ︙ | ︙ | |||
997 998 999 1000 1001 1002 1003 |
void
Tcl_StaticLibrary(
Tcl_Interp *interp, /* If not NULL, it means that the library has
* already been loaded into the given
* interpreter by calling the appropriate init
* proc. */
| | | 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 |
void
Tcl_StaticLibrary(
Tcl_Interp *interp, /* If not NULL, it means that the library has
* already been loaded into the given
* interpreter by calling the appropriate init
* proc. */
const char *prefix, /* Prefix. */
Tcl_LibraryInitProc *initProc,
/* Function to call to incorporate this
* library into a trusted interpreter. */
Tcl_LibraryInitProc *safeInitProc)
/* Function to call to incorporate this
* library into a safe interpreter (one that
* will execute untrusted scripts). NULL means
|
| ︙ | ︙ | |||
1032 1033 1034 1035 1036 1037 1038 |
/*
* If the library is not yet recorded as being loaded statically, add it
* to the list now.
*/
if (libraryPtr == NULL) {
| | | | | | | | | 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 |
/*
* If the library is not yet recorded as being loaded statically, add it
* to the list now.
*/
if (libraryPtr == NULL) {
libraryPtr = (LoadedLibrary *) Tcl_Alloc(sizeof(LoadedLibrary));
libraryPtr->fileName = (char *) Tcl_Alloc(1);
libraryPtr->fileName[0] = 0;
libraryPtr->prefix = (char *)Tcl_Alloc(strlen(prefix) + 1);
strcpy(libraryPtr->prefix, prefix);
libraryPtr->loadHandle = NULL;
libraryPtr->initProc = initProc;
libraryPtr->safeInitProc = safeInitProc;
libraryPtr->unloadProc = NULL;
libraryPtr->safeUnloadProc = NULL;
Tcl_MutexLock(&libraryMutex);
libraryPtr->nextPtr = firstLibraryPtr;
firstLibraryPtr = libraryPtr;
Tcl_MutexUnlock(&libraryMutex);
}
if (interp != NULL) {
/*
* If we're loading the library into an interpreter, determine whether
|
| ︙ | ︙ | |||
1103 1104 1105 1106 1107 1108 1109 |
TclGetLoadedLibraries(
Tcl_Interp *interp, /* Interpreter in which to return information
* or error message. */
const char *targetName, /* Name of target interpreter or NULL. If
* NULL, return info about all interps;
* otherwise, just return info about this
* interpreter. */
| | | < | 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 |
TclGetLoadedLibraries(
Tcl_Interp *interp, /* Interpreter in which to return information
* or error message. */
const char *targetName, /* Name of target interpreter or NULL. If
* NULL, return info about all interps;
* otherwise, just return info about this
* interpreter. */
const char *prefix) /* Prefix or NULL. If NULL, return info
* for all prefixes. */
{
Tcl_Interp *target;
LoadedLibrary *libraryPtr;
InterpLibrary *ipPtr;
Tcl_Obj *resultObj, *pkgDesc[2];
if (targetName == NULL) {
|
| ︙ | ︙ |
Changes to generic/tclMain.c.
| ︙ | ︙ | |||
279 280 281 282 283 284 285 | * interpreted. * *---------------------------------------------------------------------- */ TCL_NORETURN void Tcl_MainEx( | | | 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 |
* interpreted.
*
*----------------------------------------------------------------------
*/
TCL_NORETURN void
Tcl_MainEx(
Tcl_Size argc, /* Number of arguments. */
TCHAR **argv, /* Array of argument strings. */
Tcl_AppInitProc *appInitProc,
/* Application-specific initialization
* function to call after most initialization
* but before starting to execute commands. */
Tcl_Interp *interp)
{
|
| ︙ | ︙ | |||
346 347 348 349 350 351 352 |
path = Tcl_GetStartupScript(&encodingName);
if (path != NULL) {
appName = path;
} else if (argv[0]) {
appName = NewNativeObj(argv[0]);
} else {
| | | 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 |
path = Tcl_GetStartupScript(&encodingName);
if (path != NULL) {
appName = path;
} else if (argv[0]) {
appName = NewNativeObj(argv[0]);
} else {
appName = Tcl_NewStringObj("tclsh", -1);
}
Tcl_SetVar2Ex(interp, "argv0", NULL, appName, TCL_GLOBAL_ONLY);
Tcl_SetVar2Ex(interp, "argc", NULL, Tcl_NewWideIntObj(argc), TCL_GLOBAL_ONLY);
argvPtr = Tcl_NewListObj(0, NULL);
while (argc--) {
|
| ︙ | ︙ | |||
743 744 745 746 747 748 749 | * Could be almost arbitrary, depending on the command that's typed. * *---------------------------------------------------------------------- */ static void StdinProc( | | | 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 |
* Could be almost arbitrary, depending on the command that's typed.
*
*----------------------------------------------------------------------
*/
static void
StdinProc(
void *clientData, /* The state of interactive cmd line */
TCL_UNUSED(int) /*mask*/)
{
int code;
Tcl_Size length;
InteractiveState *isPtr = (InteractiveState *)clientData;
Tcl_Channel chan = isPtr->input;
Tcl_Obj *commandPtr = isPtr->commandPtr;
|
| ︙ | ︙ |
Changes to generic/tclNamesp.c.
| ︙ | ︙ | |||
130 131 132 133 134 135 136 |
FreeNsNameInternalRep, /* freeIntRepProc */
DupNsNameInternalRep, /* dupIntRepProc */
NULL, /* updateStringProc */
SetNsNameFromAny, /* setFromAnyProc */
TCL_OBJTYPE_V0
};
| | | | | | | | 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
FreeNsNameInternalRep, /* freeIntRepProc */
DupNsNameInternalRep, /* dupIntRepProc */
NULL, /* updateStringProc */
SetNsNameFromAny, /* setFromAnyProc */
TCL_OBJTYPE_V0
};
#define NsNameSetInternalRep(objPtr, nnPtr) \
do { \
Tcl_ObjInternalRep ir; \
(nnPtr)->refCount++; \
ir.twoPtrValue.ptr1 = (nnPtr); \
ir.twoPtrValue.ptr2 = NULL; \
Tcl_StoreInternalRep((objPtr), &nsNameType, &ir); \
} while (0)
#define NsNameGetInternalRep(objPtr, nnPtr) \
do { \
const Tcl_ObjInternalRep *irPtr; \
irPtr = TclFetchInternalRep((objPtr), &nsNameType); \
(nnPtr) = irPtr ? (ResolvedNsName *)irPtr->twoPtrValue.ptr1 : NULL; \
} while (0)
/*
* Array of values describing how to implement each standard subcommand of the
* "namespace" command.
*/
|
| ︙ | ︙ | |||
217 218 219 220 221 222 223 | * None. * *---------------------------------------------------------------------- */ Tcl_Namespace * Tcl_GetCurrentNamespace( | | | 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 |
* None.
*
*----------------------------------------------------------------------
*/
Tcl_Namespace *
Tcl_GetCurrentNamespace(
Tcl_Interp *interp) /* Interpreter whose current namespace is
* being queried. */
{
return TclGetCurrentNamespace(interp);
}
/*
*----------------------------------------------------------------------
|
| ︙ | ︙ | |||
241 242 243 244 245 246 247 | * None. * *---------------------------------------------------------------------- */ Tcl_Namespace * Tcl_GetGlobalNamespace( | | | 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 |
* None.
*
*----------------------------------------------------------------------
*/
Tcl_Namespace *
Tcl_GetGlobalNamespace(
Tcl_Interp *interp) /* Interpreter whose global namespace should
* be returned. */
{
return TclGetGlobalNamespace(interp);
}
/*
*----------------------------------------------------------------------
|
| ︙ | ︙ | |||
649 650 651 652 653 654 655 |
Tcl_CreateNamespace(
Tcl_Interp *interp, /* Interpreter in which a new namespace is
* being created. Also used for error
* reporting. */
const char *name, /* Name for the new namespace. May be a
* qualified name with names of ancestor
* namespaces separated by "::"s. */
| | | 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 |
Tcl_CreateNamespace(
Tcl_Interp *interp, /* Interpreter in which a new namespace is
* being created. Also used for error
* reporting. */
const char *name, /* Name for the new namespace. May be a
* qualified name with names of ancestor
* namespaces separated by "::"s. */
void *clientData, /* One-word value to store with namespace. */
Tcl_NamespaceDeleteProc *deleteProc)
/* Function called to delete client data when
* the namespace is deleted. NULL if no
* function should be called. */
{
Interp *iPtr = (Interp *) interp;
Namespace *nsPtr, *ancestorPtr;
|
| ︙ | ︙ | |||
1075 1076 1077 1078 1079 1080 1081 |
Namespace *nsPtr)
{
return (nsPtr->flags & NS_DYING) ? 1 : 0;
}
void
TclDeleteNamespaceChildren(
| | < | 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 |
Namespace *nsPtr)
{
return (nsPtr->flags & NS_DYING) ? 1 : 0;
}
void
TclDeleteNamespaceChildren(
Namespace *nsPtr) /* Namespace whose children to delete. */
{
Interp *iPtr = (Interp *) nsPtr->interp;
Tcl_HashEntry *entryPtr;
size_t i;
int unchecked;
Tcl_HashSearch search;
/*
|
| ︙ | ︙ | |||
1175 1176 1177 1178 1179 1180 1181 | * Deletes all commands, variables and namespaces in this namespace. * *---------------------------------------------------------------------- */ void TclTeardownNamespace( | | | 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 |
* Deletes all commands, variables and namespaces in this namespace.
*
*----------------------------------------------------------------------
*/
void
TclTeardownNamespace(
Namespace *nsPtr) /* Points to the namespace to be dismantled
* and unlinked from its parent. */
{
Interp *iPtr = (Interp *) nsPtr->interp;
Tcl_HashEntry *entryPtr;
Tcl_HashSearch search;
Tcl_Size i;
|
| ︙ | ︙ | |||
1313 1314 1315 1316 1317 1318 1319 | * None. * *---------------------------------------------------------------------- */ static void NamespaceFree( | | | 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 |
* None.
*
*----------------------------------------------------------------------
*/
static void
NamespaceFree(
Namespace *nsPtr) /* Points to the namespace to free. */
{
/*
* Most of the namespace's contents are freed when the namespace is
* deleted by Tcl_DeleteNamespace. All that remains is to free its names
* (for error messages), and the structure itself.
*/
|
| ︙ | ︙ | |||
1612 1613 1614 1615 1616 1617 1618 |
* imported commands in autoloaded libraries and loads them in. That way,
* they will be found when we try to create links below.
*
* Note that we don't just call Tcl_EvalObjv() directly because we do not
* want absence of the command to be a failure case.
*/
| | | 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 |
* imported commands in autoloaded libraries and loads them in. That way,
* they will be found when we try to create links below.
*
* Note that we don't just call Tcl_EvalObjv() directly because we do not
* want absence of the command to be a failure case.
*/
if (Tcl_FindCommand(interp, "auto_import", NULL, TCL_GLOBAL_ONLY) != NULL) {
Tcl_Obj *objv[2];
int result;
TclNewLiteralStringObj(objv[0], "auto_import");
objv[1] = Tcl_NewStringObj(pattern, -1);
Tcl_IncrRefCount(objv[0]);
|
| ︙ | ︙ | |||
2032 2033 2034 2035 2036 2037 2038 | * wrong, the result object is set to an error message. * *---------------------------------------------------------------------- */ static int InvokeImportedNRCmd( | | | | 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 |
* wrong, the result object is set to an error message.
*
*----------------------------------------------------------------------
*/
static int
InvokeImportedNRCmd(
void *clientData, /* Points to the imported command's
* ImportedCmdData structure. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* The argument objects. */
{
ImportedCmdData *dataPtr = (ImportedCmdData *)clientData;
Command *realCmdPtr = dataPtr->realCmdPtr;
TclSkipTailcall(interp);
return TclNREvalObjv(interp, objc, objv, TCL_EVAL_NOERR, realCmdPtr);
}
int
TclInvokeImportedCmd(
void *clientData, /* Points to the imported command's
* ImportedCmdData structure. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* The argument objects. */
{
return Tcl_NRCallObjProc(interp, InvokeImportedNRCmd, clientData,
objc, objv);
|
| ︙ | ︙ | |||
2080 2081 2082 2083 2084 2085 2086 | * Removes the imported command from the real command's import list. * *---------------------------------------------------------------------- */ static void DeleteImportedCmd( | | | 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 |
* Removes the imported command from the real command's import list.
*
*----------------------------------------------------------------------
*/
static void
DeleteImportedCmd(
void *clientData) /* Points to the imported command's
* ImportedCmdData structure. */
{
ImportedCmdData *dataPtr = (ImportedCmdData *)clientData;
Command *realCmdPtr = dataPtr->realCmdPtr;
Command *selfPtr = dataPtr->selfPtr;
ImportRef *refPtr, *prevPtr;
|
| ︙ | ︙ | |||
2507 2508 2509 2510 2511 2512 2513 |
* (current namespace if contextNsPtr is
* NULL), then in global namespace. */
Tcl_Namespace *contextNsPtr,/* Ignored if TCL_GLOBAL_ONLY flag is set or
* if the name starts with "::". Otherwise,
* points to namespace in which to resolve
* name; if NULL, look up name in the current
* namespace. */
| | | 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 |
* (current namespace if contextNsPtr is
* NULL), then in global namespace. */
Tcl_Namespace *contextNsPtr,/* Ignored if TCL_GLOBAL_ONLY flag is set or
* if the name starts with "::". Otherwise,
* points to namespace in which to resolve
* name; if NULL, look up name in the current
* namespace. */
int flags) /* Flags controlling namespace lookup: an OR'd
* combination of TCL_GLOBAL_ONLY and
* TCL_LEAVE_ERR_MSG flags. */
{
Namespace *nsPtr, *dummy1Ptr, *dummy2Ptr;
const char *dummy;
/*
|
| ︙ | ︙ | |||
3354 3355 3356 3357 3358 3359 3360 | * result. * *---------------------------------------------------------------------- */ static int NamespaceEvalCmd( | | | 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 |
* result.
*
*----------------------------------------------------------------------
*/
static int
NamespaceEvalCmd(
void *clientData, /* Arbitrary value passed to cmd. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
return Tcl_NRCallObjProc(interp, NRNamespaceEvalCmd, clientData, objc,
objv);
}
|
| ︙ | ︙ | |||
3803 3804 3805 3806 3807 3808 3809 | * Returns a result in the Tcl interpreter's result object. * *---------------------------------------------------------------------- */ static int NamespaceInscopeCmd( | | | 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 |
* Returns a result in the Tcl interpreter's result object.
*
*----------------------------------------------------------------------
*/
static int
NamespaceInscopeCmd(
void *clientData, /* Arbitrary value passed to cmd. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
return Tcl_NRCallObjProc(interp, NRNamespaceInscopeCmd, clientData, objc,
objv);
}
|
| ︙ | ︙ | |||
3841 3842 3843 3844 3845 3846 3847 |
return TCL_ERROR;
}
/*
* Make the specified namespace the current namespace.
*/
| | | | 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 |
return TCL_ERROR;
}
/*
* Make the specified namespace the current namespace.
*/
framePtrPtr = &framePtr; /* This is needed to satisfy GCC's
* strict aliasing rules. */
(void) TclPushStackFrame(interp, (Tcl_CallFrame **) framePtrPtr,
namespacePtr, /*isProcCallFrame*/ 0);
framePtr->objv = TclFetchEnsembleRoot(interp, objv, objc, &framePtr->objc);
/*
* Execute the command. If there is just one argument, just treat it as a
|
| ︙ | ︙ | |||
4534 4535 4536 4537 4538 4539 4540 |
name = TclGetString(objv[1]);
for (p = name; *p != '\0'; p++) {
/* empty body */
}
while (--p > name) {
if ((*p == ':') && (*(p-1) == ':')) {
| | | 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 |
name = TclGetString(objv[1]);
for (p = name; *p != '\0'; p++) {
/* empty body */
}
while (--p > name) {
if ((*p == ':') && (*(p-1) == ':')) {
p++; /* Just after the last "::" */
break;
}
}
if (p >= name) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(p, -1));
}
|
| ︙ | ︙ | |||
4766 4767 4768 4769 4770 4771 4772 |
*
*----------------------------------------------------------------------
*/
static void
DupNsNameInternalRep(
Tcl_Obj *srcPtr, /* Object with internal rep to copy. */
| | | 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 |
*
*----------------------------------------------------------------------
*/
static void
DupNsNameInternalRep(
Tcl_Obj *srcPtr, /* Object with internal rep to copy. */
Tcl_Obj *copyPtr) /* Object with internal rep to set. */
{
ResolvedNsName *resNamePtr;
NsNameGetInternalRep(srcPtr, resNamePtr);
assert(resNamePtr != NULL);
NsNameSetInternalRep(copyPtr, resNamePtr);
}
|
| ︙ | ︙ | |||
4802 4803 4804 4805 4806 4807 4808 |
*/
static int
SetNsNameFromAny(
Tcl_Interp *interp, /* Points to the namespace in which to resolve
* name. Also used for error reporting if not
* NULL. */
| | | 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 |
*/
static int
SetNsNameFromAny(
Tcl_Interp *interp, /* Points to the namespace in which to resolve
* name. Also used for error reporting if not
* NULL. */
Tcl_Obj *objPtr) /* The object to convert. */
{
const char *dummy;
Namespace *nsPtr, *dummy1Ptr, *dummy2Ptr;
ResolvedNsName *resNamePtr;
const char *name;
if (interp == NULL) {
|
| ︙ | ︙ | |||
4924 4925 4926 4927 4928 4929 4930 |
TclLogCommandInfo(
Tcl_Interp *interp, /* Interpreter in which to log information. */
const char *script, /* First character in script containing
* command (must be <= command). */
const char *command, /* First character in command that generated
* the error. */
Tcl_Size length, /* Number of bytes in command (< 0 means use
| | < | 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 |
TclLogCommandInfo(
Tcl_Interp *interp, /* Interpreter in which to log information. */
const char *script, /* First character in script containing
* command (must be <= command). */
const char *command, /* First character in command that generated
* the error. */
Tcl_Size length, /* Number of bytes in command (< 0 means use
* all bytes up to first null byte). */
const unsigned char *pc, /* Current pc of bytecode execution context */
Tcl_Obj **tosPtr) /* Current stack of bytecode execution
* context */
{
const char *p;
Interp *iPtr = (Interp *) interp;
int overflow, limit = 150;
|
| ︙ | ︙ |
Changes to generic/tclNotify.c.
| ︙ | ︙ | |||
67 68 69 70 71 72 73 |
* elapsed time for the next block. */
int inTraversal; /* 1 if Tcl_SetMaxBlockTime is being called
* during an event source traversal. */
EventSource *firstEventSourcePtr;
/* Pointer to first event source in list of
* event sources for this thread. */
Tcl_ThreadId threadId; /* Thread that owns this notifier instance. */
| | | 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
* elapsed time for the next block. */
int inTraversal; /* 1 if Tcl_SetMaxBlockTime is being called
* during an event source traversal. */
EventSource *firstEventSourcePtr;
/* Pointer to first event source in list of
* event sources for this thread. */
Tcl_ThreadId threadId; /* Thread that owns this notifier instance. */
void *clientData; /* Opaque handle for platform specific
* notifier. */
int initialized; /* 1 if notifier has been initialized. */
struct ThreadSpecificData *nextPtr;
/* Next notifier in global list of notifiers.
* Access is controlled by the listLock global
* mutex. */
} ThreadSpecificData;
|
| ︙ | ︙ | |||
301 302 303 304 305 306 307 |
Tcl_CreateEventSource(
Tcl_EventSetupProc *setupProc,
/* Function to invoke to figure out what to
* wait for. */
Tcl_EventCheckProc *checkProc,
/* Function to call after waiting to see what
* happened. */
| | | 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 |
Tcl_CreateEventSource(
Tcl_EventSetupProc *setupProc,
/* Function to invoke to figure out what to
* wait for. */
Tcl_EventCheckProc *checkProc,
/* Function to call after waiting to see what
* happened. */
void *clientData) /* One-word argument to pass to setupProc and
* checkProc. */
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
EventSource *sourcePtr = (EventSource *)Tcl_Alloc(sizeof(EventSource));
sourcePtr->setupProc = setupProc;
sourcePtr->checkProc = checkProc;
|
| ︙ | ︙ | |||
340 341 342 343 344 345 346 |
Tcl_DeleteEventSource(
Tcl_EventSetupProc *setupProc,
/* Function to invoke to figure out what to
* wait for. */
Tcl_EventCheckProc *checkProc,
/* Function to call after waiting to see what
* happened. */
| | | 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 |
Tcl_DeleteEventSource(
Tcl_EventSetupProc *setupProc,
/* Function to invoke to figure out what to
* wait for. */
Tcl_EventCheckProc *checkProc,
/* Function to call after waiting to see what
* happened. */
void *clientData) /* One-word argument to pass to setupProc and
* checkProc. */
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
EventSource *sourcePtr, *prevPtr;
for (sourcePtr = tsdPtr->firstEventSourcePtr, prevPtr = NULL;
sourcePtr != NULL;
|
| ︙ | ︙ | |||
552 553 554 555 556 557 558 |
*
*----------------------------------------------------------------------
*/
void
Tcl_DeleteEvents(
Tcl_EventDeleteProc *proc, /* The function to call. */
| | | 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 |
*
*----------------------------------------------------------------------
*/
void
Tcl_DeleteEvents(
Tcl_EventDeleteProc *proc, /* The function to call. */
void *clientData) /* The type-specific data. */
{
Tcl_Event *evPtr; /* Pointer to the event being examined */
Tcl_Event *prevPtr; /* Pointer to evPtr's predecessor, or NULL if
* evPtr designates the first event in the
* queue for the thread. */
Tcl_Event *hold;
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
|
| ︙ | ︙ | |||
1249 1250 1251 1252 1253 1254 1255 | * See the platform-specific implementations. * *---------------------------------------------------------------------- */ void Tcl_AlertNotifier( | | | 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 |
* See the platform-specific implementations.
*
*----------------------------------------------------------------------
*/
void
Tcl_AlertNotifier(
void *clientData) /* Pointer to thread data. */
{
if (tclNotifierHooks.alertNotifierProc) {
tclNotifierHooks.alertNotifierProc(clientData);
} else {
TclpAlertNotifier(clientData);
}
}
|
| ︙ | ︙ | |||
1376 1377 1378 1379 1380 1381 1382 |
int fd, /* Handle of stream to watch. */
int mask, /* OR'ed combination of TCL_READABLE,
* TCL_WRITABLE, and TCL_EXCEPTION: indicates
* conditions under which proc should be
* called. */
Tcl_FileProc *proc, /* Function to call for each selected
* event. */
| | | 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 |
int fd, /* Handle of stream to watch. */
int mask, /* OR'ed combination of TCL_READABLE,
* TCL_WRITABLE, and TCL_EXCEPTION: indicates
* conditions under which proc should be
* called. */
Tcl_FileProc *proc, /* Function to call for each selected
* event. */
void *clientData) /* Arbitrary data to pass to proc. */
{
if (tclNotifierHooks.createFileHandlerProc) {
tclNotifierHooks.createFileHandlerProc(fd, mask, proc, clientData);
} else {
TclpCreateFileHandler(fd, mask, proc, clientData);
}
}
|
| ︙ | ︙ |
Changes to generic/tclOO.c.
| ︙ | ︙ | |||
787 788 789 790 791 792 793 | * of those commands when the object itself is deleted. * * ---------------------------------------------------------------------- */ static void MyDeleted( | | | 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 |
* of those commands when the object itself is deleted.
*
* ----------------------------------------------------------------------
*/
static void
MyDeleted(
void *clientData) /* Reference to the object whose [my] has been
* squelched. */
{
Object *oPtr = (Object *)clientData;
oPtr->myCommand = NULL;
}
|
| ︙ | ︙ | |||
818 819 820 821 822 823 824 | * object data structures. * * ---------------------------------------------------------------------- */ static void ObjectRenamedTrace( | | | 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 |
* object data structures.
*
* ----------------------------------------------------------------------
*/
static void
ObjectRenamedTrace(
void *clientData, /* The object being deleted. */
TCL_UNUSED(Tcl_Interp *),
TCL_UNUSED(const char *) /*oldName*/,
TCL_UNUSED(const char *) /*newName*/,
int flags) /* Why was the object deleted? */
{
Object *oPtr = (Object *)clientData;
|
| ︙ | ︙ | |||
1131 1132 1133 1134 1135 1136 1137 | * (interpreter teardown is complex!) * * ---------------------------------------------------------------------- */ static void ObjectNamespaceDeleted( | | | | 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 |
* (interpreter teardown is complex!)
*
* ----------------------------------------------------------------------
*/
static void
ObjectNamespaceDeleted(
void *clientData) /* Pointer to the class whose namespace is
* being deleted. */
{
Object *oPtr = (Object *)clientData;
Foundation *fPtr = oPtr->fPtr;
FOREACH_HASH_DECLS;
Class *mixinPtr;
Method *mPtr;
Tcl_Obj *filterObj, *variableObj, *propertyObj;
PrivateVariableMapping *privateVariable;
Tcl_Interp *interp = oPtr->fPtr->interp;
Tcl_Size i;
if (Destructing(oPtr)) {
/*
* TODO: Can ObjectNamespaceDeleted ever be called twice? If not,
* this guard could be removed.
*/
return;
}
/*
|
| ︙ | ︙ | |||
1711 1712 1713 1714 1715 1716 1717 |
Tcl_Interp *interp, /* Interpreter context. */
Tcl_Class cls, /* Class to create an instance of. */
const char *nameStr, /* Name of object to create, or NULL to ask
* the code to pick its own unique name. */
const char *nsNameStr, /* Name of namespace to create inside object,
* or NULL to ask the code to pick its own
* unique name. */
| | | | 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 |
Tcl_Interp *interp, /* Interpreter context. */
Tcl_Class cls, /* Class to create an instance of. */
const char *nameStr, /* Name of object to create, or NULL to ask
* the code to pick its own unique name. */
const char *nsNameStr, /* Name of namespace to create inside object,
* or NULL to ask the code to pick its own
* unique name. */
Tcl_Size objc, /* Number of arguments. Negative value means
* do not call constructor. */
Tcl_Obj *const *objv, /* Argument list. */
Tcl_Size skip) /* Number of arguments to _not_ pass to the
* constructor. */
{
Class *classPtr = (Class *) cls;
Object *oPtr;
void *clientData[4];
oPtr = TclNewObjectInstanceCommon(interp, classPtr, nameStr, nsNameStr);
|
| ︙ | ︙ |
Changes to generic/tclOOInt.h.
| ︙ | ︙ | |||
43 44 45 46 47 48 49 |
typedef struct Method {
const Tcl_MethodType *typePtr;
/* The type of method. If NULL, this is a
* special flag record which is just used for
* the setting of the flags field. */
Tcl_Size refCount;
| | | 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
typedef struct Method {
const Tcl_MethodType *typePtr;
/* The type of method. If NULL, this is a
* special flag record which is just used for
* the setting of the flags field. */
Tcl_Size refCount;
void *clientData; /* Type-specific data. */
Tcl_Obj *namePtr; /* Name of the method. */
struct Object *declaringObjectPtr;
/* The object that declares this method, or
* NULL if it was declared by a class. */
struct Class *declaringClassPtr;
/* The class that declares this method, or
* NULL if it was declared directly on an
|
| ︙ | ︙ | |||
205 206 207 208 209 210 211 |
* for everything else. It points to the class
* structure. */
Tcl_Size refCount; /* Number of strong references to this object.
* Note that there may be many more weak
* references; this mechanism exists to
* avoid Tcl_Preserve. */
int flags;
| | | | 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 |
* for everything else. It points to the class
* structure. */
Tcl_Size refCount; /* Number of strong references to this object.
* Note that there may be many more weak
* references; this mechanism exists to
* avoid Tcl_Preserve. */
int flags;
Tcl_Size creationEpoch; /* Unique value to make comparisons of objects
* easier. */
Tcl_Size epoch; /* Per-object epoch, incremented when the way
* an object should resolve call chains is
* changed. */
Tcl_HashTable *metadataPtr; /* Mapping from pointers to metadata type to
* the void *values that are the values
* of each piece of attached metadata. This
* field starts out as NULL and is only
* allocated if metadata is attached. */
|
| ︙ | ︙ | |||
514 515 516 517 518 519 520 | */ MODULE_SCOPE void TclOOAddToInstances(Object *oPtr, Class *clsPtr); MODULE_SCOPE void TclOOAddToMixinSubs(Class *subPtr, Class *mixinPtr); MODULE_SCOPE void TclOOAddToSubclasses(Class *subPtr, Class *superPtr); MODULE_SCOPE Class * TclOOAllocClass(Tcl_Interp *interp, Object *useThisObj); | | | | | | | | | | | 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 |
*/
MODULE_SCOPE void TclOOAddToInstances(Object *oPtr, Class *clsPtr);
MODULE_SCOPE void TclOOAddToMixinSubs(Class *subPtr, Class *mixinPtr);
MODULE_SCOPE void TclOOAddToSubclasses(Class *subPtr, Class *superPtr);
MODULE_SCOPE Class * TclOOAllocClass(Tcl_Interp *interp,
Object *useThisObj);
MODULE_SCOPE int TclMethodIsType(Tcl_Method method,
const Tcl_MethodType *typePtr,
void **clientDataPtr);
MODULE_SCOPE Tcl_Method TclNewInstanceMethod(Tcl_Interp *interp,
Tcl_Object object, Tcl_Obj *nameObj,
int flags, const Tcl_MethodType *typePtr,
void *clientData);
MODULE_SCOPE Tcl_Method TclNewMethod(Tcl_Interp *interp, Tcl_Class cls,
Tcl_Obj *nameObj, int flags,
const Tcl_MethodType *typePtr,
void *clientData);
MODULE_SCOPE int TclNRNewObjectInstance(Tcl_Interp *interp,
Tcl_Class cls, const char *nameStr,
const char *nsNameStr, Tcl_Size objc,
Tcl_Obj *const *objv, Tcl_Size skip,
Tcl_Object *objectPtr);
MODULE_SCOPE Object * TclNewObjectInstanceCommon(Tcl_Interp *interp,
Class *classPtr,
|
| ︙ | ︙ | |||
608 609 610 611 612 613 614 | /* * A convenience macro for iterating through the lists used in the internal * memory management of objects. * REQUIRES DECLARATION: Tcl_Size i; */ #define FOREACH(var,ary) \ | | | | | | | | | | | | | | | | 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 |
/*
* A convenience macro for iterating through the lists used in the internal
* memory management of objects.
* REQUIRES DECLARATION: Tcl_Size i;
*/
#define FOREACH(var,ary) \
for(i=0 ; i<(ary).num; i++) if ((ary).list[i] == NULL) { \
continue; \
} else if ((var) = (ary).list[i], 1)
/*
* A variation where the array is an array of structs. There's no issue with
* possible NULLs; every element of the array will be iterated over and the
* variable set to a pointer to each of those elements in turn.
* REQUIRES DECLARATION: Tcl_Size i; See [96551aca55] for more FOREACH_STRUCT details.
*/
#define FOREACH_STRUCT(var, ary) \
if (i=0, (ary).num>0) for(; var=&((ary).list[i]), i<(ary).num; i++)
/*
* Convenience macros for iterating through hash tables. FOREACH_HASH_DECLS
* sets up the declarations needed for the main macro, FOREACH_HASH, which
* does the actual iteration. FOREACH_HASH_VALUE is a restricted version that
* only iterates over values.
* REQUIRES DECLARATION: FOREACH_HASH_DECLS;
*/
#define FOREACH_HASH_DECLS \
Tcl_HashEntry *hPtr;Tcl_HashSearch search
#define FOREACH_HASH(key, val, tablePtr) \
for(hPtr=Tcl_FirstHashEntry((tablePtr),&search); hPtr!=NULL ? \
(*(void **)&(key)=Tcl_GetHashKey((tablePtr),hPtr), \
*(void **)&(val)=Tcl_GetHashValue(hPtr),1):0; hPtr=Tcl_NextHashEntry(&search))
#define FOREACH_HASH_VALUE(val,tablePtr) \
for(hPtr=Tcl_FirstHashEntry((tablePtr),&search); hPtr!=NULL ? \
(*(void **)&(val)=Tcl_GetHashValue(hPtr),1):0;hPtr=Tcl_NextHashEntry(&search))
/*
* Convenience macro for duplicating a list. Needs no external declaration,
* but all arguments are used multiple times and so must have no side effects.
*/
#undef DUPLICATE /* prevent possible conflict with definition in WINAPI nb30.h */
#define DUPLICATE(target, source, type) \
do { \
size_t len = sizeof(type) * ((target).num=(source).num); \
if (len != 0) { \
memcpy(((target).list=(type*)Tcl_Alloc(len)), (source).list, len); \
} else { \
(target).list = NULL; \
} \
} while(0)
#endif /* TCL_OO_INTERNAL_H */
/*
* Local Variables:
* mode: c
* c-basic-offset: 4
* fill-column: 78
* End:
*/
|
Changes to generic/tclObj.c.
| ︙ | ︙ | |||
1658 1659 1660 1661 1662 1663 1664 | * *---------------------------------------------------------------------- */ #if !defined(TCL_NO_DEPRECATED) char * TclGetStringFromObj( | | | | 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 |
*
*----------------------------------------------------------------------
*/
#if !defined(TCL_NO_DEPRECATED)
char *
TclGetStringFromObj(
Tcl_Obj *objPtr, /* Object whose string rep byte pointer should
* be returned. */
void *lengthPtr) /* If non-NULL, the location where the string
* rep's byte array length should * be stored.
* If NULL, no length is stored. */
{
if (objPtr->bytes == NULL) {
/*
* Note we do not check for objPtr->typePtr == NULL. An invariant
* of a properly maintained Tcl_Obj is that at least one of
|
| ︙ | ︙ | |||
1703 1704 1705 1706 1707 1708 1709 |
return objPtr->bytes;
}
#endif /* !defined(TCL_NO_DEPRECATED) */
#undef Tcl_GetStringFromObj
char *
Tcl_GetStringFromObj(
| | | 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 |
return objPtr->bytes;
}
#endif /* !defined(TCL_NO_DEPRECATED) */
#undef Tcl_GetStringFromObj
char *
Tcl_GetStringFromObj(
Tcl_Obj *objPtr, /* Object whose string rep byte pointer should
* be returned. */
Tcl_Size *lengthPtr) /* If non-NULL, the location where the string
* rep's byte array length should * be stored.
* If NULL, no length is stored. */
{
if (objPtr->bytes == NULL) {
/*
|
| ︙ | ︙ | |||
2143 2144 2145 2146 2147 2148 2149 |
Tcl_SetErrorCode(interp, "TCL", "VALUE", "BOOLEAN", (void *)NULL);
}
return TCL_ERROR;
}
static int
ParseBoolean(
| | | 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 |
Tcl_SetErrorCode(interp, "TCL", "VALUE", "BOOLEAN", (void *)NULL);
}
return TCL_ERROR;
}
static int
ParseBoolean(
Tcl_Obj *objPtr) /* The object to parse/convert. */
{
int newBool;
char lowerCase[6];
Tcl_Size i, length;
const char *str = Tcl_GetStringFromObj(objPtr, &length);
if ((length <= 0) || (length > 5)) {
|
| ︙ | ︙ | |||
3139 3140 3141 3142 3143 3144 3145 | * Side effects: * The function may free up any existing internal representation. * *---------------------------------------------------------------------- */ int Tcl_GetSizeIntFromObj( | | | | | 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 |
* Side effects:
* The function may free up any existing internal representation.
*
*----------------------------------------------------------------------
*/
int
Tcl_GetSizeIntFromObj(
Tcl_Interp *interp, /* Used for error reporting if not NULL. */
Tcl_Obj *objPtr, /* The object from which to get a int. */
Tcl_Size *sizePtr) /* Place to store resulting int. */
{
if (sizeof(Tcl_Size) == sizeof(int)) {
return TclGetIntFromObj(interp, objPtr, (int *)sizePtr);
} else {
Tcl_WideInt wide;
if (TclGetWideIntFromObj(interp, objPtr, &wide) != TCL_OK) {
return TCL_ERROR;
|
| ︙ | ︙ | |||
3451 3452 3453 3454 3455 3456 3457 |
*----------------------------------------------------------------------
*/
int
Tcl_GetBignumFromObj(
Tcl_Interp *interp, /* Tcl interpreter for error reporting */
Tcl_Obj *objPtr, /* Object to read */
| | | 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 |
*----------------------------------------------------------------------
*/
int
Tcl_GetBignumFromObj(
Tcl_Interp *interp, /* Tcl interpreter for error reporting */
Tcl_Obj *objPtr, /* Object to read */
void *bignumValue) /* Returned bignum value. */
{
return GetBignumFromObj(interp, objPtr, 1, (mp_int *)bignumValue);
}
/*
*----------------------------------------------------------------------
*
|
| ︙ | ︙ | |||
3486 3487 3488 3489 3490 3491 3492 |
*----------------------------------------------------------------------
*/
int
Tcl_TakeBignumFromObj(
Tcl_Interp *interp, /* Tcl interpreter for error reporting */
Tcl_Obj *objPtr, /* Object to read */
| | | 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 |
*----------------------------------------------------------------------
*/
int
Tcl_TakeBignumFromObj(
Tcl_Interp *interp, /* Tcl interpreter for error reporting */
Tcl_Obj *objPtr, /* Object to read */
void *bignumValue) /* Returned bignum value. */
{
return GetBignumFromObj(interp, objPtr, 0, (mp_int *)bignumValue);
}
/*
*----------------------------------------------------------------------
*
|
| ︙ | ︙ | |||
3511 3512 3513 3514 3515 3516 3517 |
*
*----------------------------------------------------------------------
*/
void
Tcl_SetBignumObj(
Tcl_Obj *objPtr, /* Object to set */
| | | 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 |
*
*----------------------------------------------------------------------
*/
void
Tcl_SetBignumObj(
Tcl_Obj *objPtr, /* Object to set */
void *big) /* Value to store */
{
Tcl_WideUInt value = 0;
size_t numBytes;
Tcl_WideUInt scratch;
unsigned char *bytes = (unsigned char *) &scratch;
mp_int *bignumValue = (mp_int *) big;
|
| ︙ | ︙ |
Changes to generic/tclParse.c.
| ︙ | ︙ | |||
1035 1036 1037 1038 1039 1040 1041 | * None. * *---------------------------------------------------------------------- */ static int ParseTokens( | | | 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 |
* None.
*
*----------------------------------------------------------------------
*/
static int
ParseTokens(
const char *src, /* First character to parse. */
Tcl_Size 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
* mask. */
int flags, /* OR-ed bits indicating what substitutions to
* perform: TCL_SUBST_COMMANDS,
|
| ︙ | ︙ |
Changes to generic/tclPathObj.c.
| ︙ | ︙ | |||
2344 2345 2346 2347 2348 2349 2350 | * Memory may be allocated. * *--------------------------------------------------------------------------- */ static void UpdateStringOfFsPath( | | | 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 |
* Memory may be allocated.
*
*---------------------------------------------------------------------------
*/
static void
UpdateStringOfFsPath(
Tcl_Obj *pathPtr) /* path obj with string rep to update. */
{
FsPath *fsPathPtr = PATHOBJ(pathPtr);
Tcl_Size cwdLen;
Tcl_Obj *copy;
if (PATHFLAGS(pathPtr) == 0 || fsPathPtr->cwdPtr == NULL) {
if (fsPathPtr->translatedPathPtr == NULL) {
|
| ︙ | ︙ | |||
2566 2567 2568 2569 2570 2571 2572 | * Returns NULL if the path begins with a ~ that cannot be resolved * and stores an error message in interp if non-NULL. * *---------------------------------------------------------------------- */ Tcl_Obj * TclResolveTildePath( | | | 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 |
* Returns NULL if the path begins with a ~ that cannot be resolved
* and stores an error message in interp if non-NULL.
*
*----------------------------------------------------------------------
*/
Tcl_Obj *
TclResolveTildePath(
Tcl_Interp *interp, /* May be NULL. Only used for error messages */
Tcl_Obj *pathObj)
{
const char *path;
Tcl_Size len;
Tcl_Size split;
Tcl_DString resolvedPath;
|
| ︙ | ︙ |
Changes to generic/tclPipe.c.
| ︙ | ︙ | |||
1017 1018 1019 1020 1021 1022 1023 |
*----------------------------------------------------------------------
*/
Tcl_Channel
Tcl_OpenCommandChannel(
Tcl_Interp *interp, /* Interpreter for error reporting. Can NOT be
* NULL. */
| | | 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 |
*----------------------------------------------------------------------
*/
Tcl_Channel
Tcl_OpenCommandChannel(
Tcl_Interp *interp, /* Interpreter for error reporting. Can NOT be
* NULL. */
Tcl_Size argc, /* How many arguments. */
const char **argv, /* Array of arguments for command pipe. */
int flags) /* Or'ed combination of TCL_STDIN, TCL_STDOUT,
* TCL_STDERR, and TCL_ENFORCE_MODE. */
{
TclFile *inPipePtr, *outPipePtr, *errFilePtr;
TclFile inPipe, outPipe, errFile;
Tcl_Size numPids;
|
| ︙ | ︙ |
Changes to generic/tclPreserve.c.
| ︙ | ︙ | |||
17 18 19 20 21 22 23 |
/*
* The following data structure is used to keep track of all the Tcl_Preserve
* calls that are still in effect. It grows as needed to accommodate any
* number of calls in effect.
*/
typedef struct {
| | | | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
/*
* The following data structure is used to keep track of all the Tcl_Preserve
* calls that are still in effect. It grows as needed to accommodate any
* number of calls in effect.
*/
typedef struct {
void *clientData; /* Address of preserved block. */
size_t refCount; /* Number of Tcl_Preserve calls in effect for
* block. */
int mustFree; /* Non-zero means Tcl_EventuallyFree was
* called while a Tcl_Preserve call was in
* effect, so the structure must be freed when
* refCount becomes zero. */
Tcl_FreeProc *freeProc; /* Function to call to free. */
} Reference;
/*
* Global data structures used to hold the list of preserved data references.
* These variables are protected by "preserveMutex".
*/
static Reference *refArray = NULL; /* First in array of references. */
static size_t spaceAvl = 0; /* Total number of structures available at
* *firstRefPtr. */
static size_t inUse = 0; /* Count of structures currently in use in
* refArray. */
TCL_DECLARE_MUTEX(preserveMutex)/* To protect the above statics */
#define INITIAL_SIZE 2 /* Initial number of reference slots to make */
/*
* The following data structure is used to keep track of whether an arbitrary
|
| ︙ | ︙ | |||
113 114 115 116 117 118 119 | * until at least the matching call to Tcl_Release. * *---------------------------------------------------------------------- */ void Tcl_Preserve( | | | 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
* until at least the matching call to Tcl_Release.
*
*----------------------------------------------------------------------
*/
void
Tcl_Preserve(
void *clientData) /* Pointer to malloc'ed block of memory. */
{
Reference *refPtr;
size_t i;
/*
* See if there is already a reference for this pointer. If so, just
* increment its reference count.
|
| ︙ | ︙ | |||
176 177 178 179 180 181 182 | * call to Tcl_Preserve is still in effect, the block of memory is freed. * *---------------------------------------------------------------------- */ void Tcl_Release( | | | 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
* call to Tcl_Preserve is still in effect, the block of memory is freed.
*
*----------------------------------------------------------------------
*/
void
Tcl_Release(
void *clientData) /* Pointer to malloc'ed block of memory. */
{
Reference *refPtr;
size_t i;
Tcl_MutexLock(&preserveMutex);
for (i=0, refPtr=refArray ; i<inUse ; i++, refPtr++) {
int mustFree;
|
| ︙ | ︙ | |||
255 256 257 258 259 260 261 | * Ptr may be released by calling free(). * *---------------------------------------------------------------------- */ void Tcl_EventuallyFree( | | | 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 |
* Ptr may be released by calling free().
*
*----------------------------------------------------------------------
*/
void
Tcl_EventuallyFree(
void *clientData, /* Pointer to malloc'ed block of memory. */
Tcl_FreeProc *freeProc) /* Function to actually do free. */
{
Reference *refPtr;
size_t i;
/*
* See if there is a reference for this pointer. If so, set its "mustFree"
|
| ︙ | ︙ |
Changes to generic/tclProc.c.
| ︙ | ︙ | |||
152 153 154 155 156 157 158 |
*/
#undef TclObjInterpProc
int
Tcl_ProcObjCmd(
TCL_UNUSED(void *),
Tcl_Interp *interp, /* Current interpreter. */
| | | 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
*/
#undef TclObjInterpProc
int
Tcl_ProcObjCmd(
TCL_UNUSED(void *),
Tcl_Interp *interp, /* Current interpreter. */
Tcl_Size objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
Interp *iPtr = (Interp *) interp;
Proc *procPtr;
const char *procName;
const char *simpleName, *procArgs, *procBody;
Namespace *nsPtr, *altNsPtr, *cxtNsPtr;
|
| ︙ | ︙ | |||
1336 1337 1338 1339 1340 1341 1342 | * are being referenced at runtime. * *---------------------------------------------------------------------- */ static int InitArgsAndLocals( | | | 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 |
* are being referenced at runtime.
*
*----------------------------------------------------------------------
*/
static int
InitArgsAndLocals(
Tcl_Interp *interp, /* Interpreter in which procedure was
* invoked. */
int skip) /* Number of initial arguments to be skipped,
* i.e., words in the "command name". */
{
CallFrame *framePtr = ((Interp *)interp)->varFramePtr;
Proc *procPtr = framePtr->procPtr;
ByteCode *codePtr;
|
| ︙ | ︙ | |||
1500 1501 1502 1503 1504 1505 1506 | * to be popped by the caller. * *---------------------------------------------------------------------- */ int TclPushProcCallFrame( | | | | 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 |
* to be popped by the caller.
*
*----------------------------------------------------------------------
*/
int
TclPushProcCallFrame(
void *clientData, /* Record describing procedure to be
* interpreted. */
Tcl_Interp *interp, /* Interpreter in which procedure was
* invoked. */
Tcl_Size objc, /* Count of number of arguments to this
* procedure. */
Tcl_Obj *const objv[], /* Argument value objects. */
int isLambda) /* 1 if this is a call by ApplyObjCmd: it
* needs special rules for error msg */
{
|
| ︙ | ︙ | |||
1595 1596 1597 1598 1599 1600 1601 | * Depends on the commands in the procedure. * *---------------------------------------------------------------------- */ int TclObjInterpProc( | | | | | | | | | 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 |
* Depends on the commands in the procedure.
*
*----------------------------------------------------------------------
*/
int
TclObjInterpProc(
void *clientData, /* Record describing procedure to be
* interpreted. */
Tcl_Interp *interp, /* Interpreter in which procedure was
* invoked. */
int objc, /* Count of number of arguments to this
* procedure. */
Tcl_Obj *const objv[]) /* Argument value objects. */
{
/*
* Not used much in the core; external interface for iTcl
*/
return Tcl_NRCallObjProc(interp, NRInterpProc, clientData, objc, objv);
}
int
TclNRInterpProc(
void *clientData, /* Record describing procedure to be
* interpreted. */
Tcl_Interp *interp, /* Interpreter in which procedure was
* invoked. */
Tcl_Size objc, /* Count of number of arguments to this
* procedure. */
Tcl_Obj *const objv[]) /* Argument value objects. */
{
int result = TclPushProcCallFrame(clientData, interp, objc, objv,
/*isLambda*/ 0);
if (result != TCL_OK) {
return TCL_ERROR;
}
return TclNRInterpProcCore(interp, objv[0], 1, &MakeProcError);
}
static int
NRInterpProc(
void *clientData, /* Record describing procedure to be
* interpreted. */
Tcl_Interp *interp, /* Interpreter in which procedure was
* invoked. */
int objc, /* Count of number of arguments to this
* procedure. */
Tcl_Obj *const objv[]) /* Argument value objects. */
{
int result = TclPushProcCallFrame(clientData, interp, objc, objv,
/*isLambda*/ 0);
if (result != TCL_OK) {
|
| ︙ | ︙ | |||
1686 1687 1688 1689 1690 1691 1692 | * Nearly anything; depends on the commands in the procedure body. * *---------------------------------------------------------------------- */ int TclNRInterpProcCore( | | | | 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 |
* Nearly anything; depends on the commands in the procedure body.
*
*----------------------------------------------------------------------
*/
int
TclNRInterpProcCore(
Tcl_Interp *interp, /* Interpreter in which procedure was
* invoked. */
Tcl_Obj *procNameObj, /* Procedure name for error reporting. */
Tcl_Size skip, /* Number of initial arguments to be skipped,
* i.e., words in the "command name". */
ProcErrorProc *errorProc) /* How to convert results from the script into
* results of the overall procedure. */
{
Interp *iPtr = (Interp *) interp;
Proc *procPtr = iPtr->varFramePtr->procPtr;
int result;
|
| ︙ | ︙ | |||
2108 2109 2110 2111 2112 2113 2114 | * procedure completes. * *---------------------------------------------------------------------- */ void TclProcDeleteProc( | | | 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 |
* procedure completes.
*
*----------------------------------------------------------------------
*/
void
TclProcDeleteProc(
void *clientData) /* Procedure to be deleted. */
{
Proc *procPtr = (Proc *)clientData;
if (procPtr->refCount-- <= 1) {
TclProcCleanupProc(procPtr);
}
}
|
| ︙ | ︙ | |||
2401 2402 2403 2404 2405 2406 2407 |
*
*----------------------------------------------------------------------
*/
static void
DupLambdaInternalRep(
Tcl_Obj *srcPtr, /* Object with internal rep to copy. */
| | | | | 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 |
*
*----------------------------------------------------------------------
*/
static void
DupLambdaInternalRep(
Tcl_Obj *srcPtr, /* Object with internal rep to copy. */
Tcl_Obj *copyPtr) /* Object with internal rep to set. */
{
Proc *procPtr;
Tcl_Obj *nsObjPtr;
LambdaGetInternalRep(srcPtr, procPtr, nsObjPtr);
assert(procPtr != NULL);
procPtr->refCount++;
LambdaSetInternalRep(copyPtr, procPtr, nsObjPtr);
}
static void
FreeLambdaInternalRep(
Tcl_Obj *objPtr) /* CmdName object with internal representation
* to free. */
{
Proc *procPtr;
Tcl_Obj *nsObjPtr;
LambdaGetInternalRep(objPtr, procPtr, nsObjPtr);
assert(procPtr != NULL);
if (procPtr->refCount-- <= 1) {
TclProcCleanupProc(procPtr);
}
TclDecrRefCount(nsObjPtr);
}
static int
SetLambdaFromAny(
Tcl_Interp *interp, /* Used for error reporting if not NULL. */
Tcl_Obj *objPtr) /* The object to convert. */
{
Interp *iPtr = (Interp *) interp;
const char *name;
Tcl_Obj *argsPtr, *bodyPtr, *nsObjPtr, **objv;
int isNew, result;
Tcl_Size objc;
CmdFrame *cfPtr = NULL;
|
| ︙ | ︙ |
Changes to generic/tclProcess.c.
| ︙ | ︙ | |||
72 73 74 75 76 77 78 |
*----------------------------------------------------------------------
*/
void
InitProcessInfo(
ProcessInfo *info, /* Structure to initialize. */
Tcl_Pid pid, /* Process id. */
| | | 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
*----------------------------------------------------------------------
*/
void
InitProcessInfo(
ProcessInfo *info, /* Structure to initialize. */
Tcl_Pid pid, /* Process id. */
Tcl_Size resolvedPid) /* Resolved process id. */
{
info->pid = pid;
info->resolvedPid = resolvedPid;
info->purge = 0;
info->status = TCL_PROCESS_UNCHANGED;
info->code = 0;
info->msg = NULL;
|
| ︙ | ︙ | |||
188 189 190 191 192 193 194 |
Tcl_Size resolvedPid, /* Resolved process id. */
int options, /* Options passed to Tcl_WaitPid. */
int *codePtr, /* If non-NULL, will receive either:
* - 0 for normal exit.
* - errno in case of error.
* - non-zero exit code for abormal exit.
* - signal number if killed or suspended.
| | < | 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 |
Tcl_Size resolvedPid, /* Resolved process id. */
int options, /* Options passed to Tcl_WaitPid. */
int *codePtr, /* If non-NULL, will receive either:
* - 0 for normal exit.
* - errno in case of error.
* - non-zero exit code for abormal exit.
* - signal number if killed or suspended.
* - Tcl_WaitPid status in all other cases. */
Tcl_Obj **msgObjPtr, /* If non-NULL, will receive error message. */
Tcl_Obj **errorObjPtr) /* If non-NULL, will receive error code. */
{
int waitStatus;
Tcl_Obj *errorStrings[5];
const char *msg;
|
| ︙ | ︙ |
Changes to generic/tclRegexp.c.
| ︙ | ︙ | |||
363 364 365 366 367 368 369 |
TclRegExpRangeUniChar(
Tcl_RegExp re, /* Compiled regular expression that has been
* passed to Tcl_RegExpExec. */
Tcl_Size index, /* 0 means give the range of the entire match,
* > 0 means give the range of a matching
* subrange, -1 means the range of the
* rm_extend field. */
| | | | 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 |
TclRegExpRangeUniChar(
Tcl_RegExp re, /* Compiled regular expression that has been
* passed to Tcl_RegExpExec. */
Tcl_Size index, /* 0 means give the range of the entire match,
* > 0 means give the range of a matching
* subrange, -1 means the range of the
* rm_extend field. */
Tcl_Size *startPtr, /* Store address of first character in
* (sub-)range here. */
Tcl_Size *endPtr) /* Store address of character just after last
* in (sub-)range here. */
{
TclRegexp *regexpPtr = (TclRegexp *) re;
if ((regexpPtr->flags®_EXPECT) && (index == -1)) {
*startPtr = regexpPtr->details.rm_extend.rm_so;
*endPtr = regexpPtr->details.rm_extend.rm_eo;
|
| ︙ | ︙ | |||
441 442 443 444 445 446 447 |
Tcl_Interp *interp, /* Interpreter to use for error reporting. */
Tcl_RegExp re, /* Compiled regular expression; must have been
* returned by previous call to
* Tcl_GetRegExpFromObj. */
Tcl_Obj *textObj, /* Text against which to match re. */
Tcl_Size offset, /* Character index that marks where matching
* should begin. */
| | | 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 |
Tcl_Interp *interp, /* Interpreter to use for error reporting. */
Tcl_RegExp re, /* Compiled regular expression; must have been
* returned by previous call to
* Tcl_GetRegExpFromObj. */
Tcl_Obj *textObj, /* Text against which to match re. */
Tcl_Size offset, /* Character index that marks where matching
* should begin. */
Tcl_Size nmatches, /* How many subexpression matches (counting
* the whole match as subexpression 0) are of
* interest. -1 means all of them. */
int flags) /* Regular expression execution flags. */
{
TclRegexp *regexpPtr = (TclRegexp *) re;
Tcl_UniChar *udata;
Tcl_Size length;
|
| ︙ | ︙ |
Changes to generic/tclResult.c.
| ︙ | ︙ | |||
756 757 758 759 760 761 762 |
/*
* Reset while keeping the list internalrep as much as possible.
*/
Tcl_ListObjReplace(interp, iPtr->errorStack, 0, len, valueObjc,
valueObjv);
| | | 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 |
/*
* Reset while keeping the list internalrep as much as possible.
*/
Tcl_ListObjReplace(interp, iPtr->errorStack, 0, len, valueObjc,
valueObjv);
}
Tcl_DictObjGet(NULL, iPtr->returnOpts, keys[KEY_ERRORCODE],
&valuePtr);
if (valuePtr != NULL) {
Tcl_SetObjErrorCode(interp, valuePtr);
} else {
Tcl_SetErrorCode(interp, "NONE", (void *)NULL);
}
|
| ︙ | ︙ |
Changes to generic/tclStrToD.c.
| ︙ | ︙ | |||
121 122 123 124 125 126 127 | #define TWO_OVER_3LOG10 0.28952965460216784 #define LOG10_3HALVES_PLUS_FUDGE 0.1760912590558 /* * Definitions of the parts of an IEEE754-format floating point number. */ | | | 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | #define TWO_OVER_3LOG10 0.28952965460216784 #define LOG10_3HALVES_PLUS_FUDGE 0.1760912590558 /* * Definitions of the parts of an IEEE754-format floating point number. */ #define SIGN_BIT 0x80000000 /* Mask for the sign bit in the first word of * a double. */ #define EXP_MASK 0x7FF00000 /* Mask for the exponent field in the first * word of a double. */ #define EXP_SHIFT 20 /* Shift count to make the exponent an * integer. */ |
| ︙ | ︙ | |||
305 306 307 308 309 310 311 | long exponent); #ifdef IEEE_FLOATING_POINT static double MakeNaN(int signum, Tcl_WideUInt tag); #endif static double RefineApproximation(double approx, mp_int *exactSignificand, int exponent); static mp_err MulPow5(mp_int *, unsigned, mp_int *) MP_WUR; | | | 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 | long exponent); #ifdef IEEE_FLOATING_POINT static double MakeNaN(int signum, Tcl_WideUInt tag); #endif static double RefineApproximation(double approx, mp_int *exactSignificand, int exponent); static mp_err MulPow5(mp_int *, unsigned, mp_int *) MP_WUR; static int NormalizeRightward(Tcl_WideUInt *); static int RequiredPrecision(Tcl_WideUInt); static void DoubleToExpAndSig(double, Tcl_WideUInt *, int *, int *); static void TakeAbsoluteValue(Double *, int *); static char * FormatInfAndNaN(Double *, int *, char **); static char * FormatZero(int *, char **); static int ApproximateLog10(Tcl_WideUInt, int, int); |
| ︙ | ︙ | |||
2206 2207 2208 2209 2210 2211 2212 | * Stores base*5**n in result. * *---------------------------------------------------------------------- */ static inline mp_err MulPow5( | | | 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 |
* Stores base*5**n in result.
*
*----------------------------------------------------------------------
*/
static inline mp_err
MulPow5(
mp_int *base, /* Number to multiply. */
unsigned n, /* Power of 5 to multiply by. */
mp_int *result) /* Place to store the result. */
{
mp_int *p = base;
int n13 = n / 13;
int r = n % 13;
mp_err err = MP_OKAY;
|
| ︙ | ︙ | |||
2703 2704 2705 2706 2707 2708 2709 | * "1" and moves the decimal point (*kPtr) one place to the right. * *---------------------------------------------------------------------- */ static inline char * BumpUp( | | | 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 |
* "1" and moves the decimal point (*kPtr) one place to the right.
*
*----------------------------------------------------------------------
*/
static inline char *
BumpUp(
char *s, /* Cursor pointing one past the end of the
* string. */
char *retval, /* Start of the string of digits. */
int *kPtr) /* Position of the decimal point. */
{
while (*--s == '9') {
if (s == retval) {
++(*kPtr);
|
| ︙ | ︙ | |||
4150 4151 4152 4153 4154 4155 4156 |
}
if (mp_init_u64(&b, bw) != MP_OKAY) {
mp_clear(&dig);
return NULL;
}
err = mp_mul_2d(&b, b2, &b);
if (err == MP_OKAY) {
| | | 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 |
}
if (mp_init_u64(&b, bw) != MP_OKAY) {
mp_clear(&dig);
return NULL;
}
err = mp_mul_2d(&b, b2, &b);
if (err == MP_OKAY) {
err = mp_init_set(&S, 1);
}
if (err == MP_OKAY) {
err = MulPow5(&S, s5, &S);
if (err == MP_OKAY) {
err = mp_mul_2d(&S, s2, &S);
}
}
|
| ︙ | ︙ |
Changes to generic/tclStringObj.c.
1 2 3 4 5 6 | /* * tclStringObj.c -- * * This file contains functions that implement string operations on Tcl * objects. Some string operations work with UTF-8 encoding forms. * Functions that require knowledge of the width of each character, | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | /* * tclStringObj.c -- * * This file contains functions that implement string operations on Tcl * objects. Some string operations work with UTF-8 encoding forms. * Functions that require knowledge of the width of each character, * such as indexing, operate on fixed width encoding forms such as UTF-32. * * Conceptually, a string is a sequence of Unicode code points. Internally * it may be stored in an encoding form such as a modified version of * UTF-8 or UTF-32. * * The String object is optimized for the case where each UTF char * in a string is only one byte. In this case, we store the value of * numChars, but we don't store the fixed form encoding (unless * Tcl_GetUnicode is explicitly called). * * The String object type stores one or both formats. The default * behavior is to store UTF-8. Once UTF-16/UTF32 is calculated, it is * stored in the internal rep for future access (without an additional * O(n) cost). * * To allow many appends to be done to an object without constantly |
| ︙ | ︙ | |||
120 121 122 123 124 125 126 |
#ifndef TCL_MIN_UNICHAR_GROWTH
#define TCL_MIN_UNICHAR_GROWTH TCL_MIN_GROWTH/sizeof(Tcl_UniChar)
#endif
static void
GrowStringBuffer(
Tcl_Obj *objPtr,
| | | | 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
#ifndef TCL_MIN_UNICHAR_GROWTH
#define TCL_MIN_UNICHAR_GROWTH TCL_MIN_GROWTH/sizeof(Tcl_UniChar)
#endif
static void
GrowStringBuffer(
Tcl_Obj *objPtr,
Tcl_Size needed, /* Not including terminating nul */
int flag) /* If 0, try to overallocate */
{
/*
* Preconditions:
* objPtr->typePtr == &tclStringType
* needed > stringPtr->allocated
* flag || objPtr->bytes != NULL
*/
|
| ︙ | ︙ | |||
719 720 721 722 723 724 725 |
*
*----------------------------------------------------------------------
*/
Tcl_Obj *
Tcl_GetRange(
Tcl_Obj *objPtr, /* The Tcl object to find the range of. */
| | | | 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 |
*
*----------------------------------------------------------------------
*/
Tcl_Obj *
Tcl_GetRange(
Tcl_Obj *objPtr, /* The Tcl object to find the range of. */
Tcl_Size first, /* First index of the range. */
Tcl_Size last) /* Last index of the range. */
{
Tcl_Obj *newObjPtr; /* The Tcl object to find the range of. */
String *stringPtr;
Tcl_Size length = 0;
if (first < 0) {
first = 0;
|
| ︙ | ︙ | |||
1323 1324 1325 1326 1327 1328 1329 |
void
Tcl_AppendUnicodeToObj(
Tcl_Obj *objPtr, /* Points to the object to append to. */
const Tcl_UniChar *unicode, /* The Unicode string to append to the
* object. */
Tcl_Size length) /* Number of chars in Unicode. Negative
| | | 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 |
void
Tcl_AppendUnicodeToObj(
Tcl_Obj *objPtr, /* Points to the object to append to. */
const Tcl_UniChar *unicode, /* The Unicode string to append to the
* object. */
Tcl_Size length) /* Number of chars in Unicode. Negative
* lengths means nul terminated */
{
String *stringPtr;
if (Tcl_IsShared(objPtr)) {
Tcl_Panic("%s called with shared object", "Tcl_AppendUnicodeToObj");
}
|
| ︙ | ︙ | |||
2151 2152 2153 2154 2155 2156 2157 |
char buf[4] = "";
int code, length;
if (TclGetIntFromObj(interp, segment, &code) != TCL_OK) {
goto error;
}
if ((unsigned)code > 0x10FFFF) {
| | | 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 |
char buf[4] = "";
int code, length;
if (TclGetIntFromObj(interp, segment, &code) != TCL_OK) {
goto error;
}
if ((unsigned)code > 0x10FFFF) {
code = 0xFFFD;
}
length = Tcl_UniCharToUtf(code, buf);
segment = Tcl_NewStringObj(buf, length);
Tcl_IncrRefCount(segment);
allocSegment = 1;
break;
}
|
| ︙ | ︙ | |||
2939 2940 2941 2942 2943 2944 2945 | *--------------------------------------------------------------------------- * * TclStringRepeat -- * * Performs the [string repeat] function. * * Results: | | | | | 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 |
*---------------------------------------------------------------------------
*
* TclStringRepeat --
*
* Performs the [string repeat] function.
*
* Results:
* A (Tcl_Obj *) pointing to the result value, or NULL in case of an
* error.
*
* Side effects:
* On error, when interp is not NULL, error information is left in it.
*
*---------------------------------------------------------------------------
*/
Tcl_Obj *
TclStringRepeat(
Tcl_Interp *interp,
|
| ︙ | ︙ | |||
2968 2969 2970 2971 2972 2973 2974 |
Tcl_Size maxCount;
/* assert (count >= 2) */
/*
* Analyze to determine what representation result should be.
* GOALS: Avoid shimmering & string rep generation.
| | | | 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 |
Tcl_Size maxCount;
/* assert (count >= 2) */
/*
* Analyze to determine what representation result should be.
* GOALS: Avoid shimmering & string rep generation.
* Produce pure bytearray when possible.
* Error on overflow.
*/
if (!binary) {
if (TclHasInternalRep(objPtr, &tclStringType)) {
String *stringPtr = GET_STRING(objPtr);
if (stringPtr->hasUnicode) {
unichar = 1;
|
| ︙ | ︙ | |||
3098 3099 3100 3101 3102 3103 3104 | *--------------------------------------------------------------------------- * * TclStringCat -- * * Performs the [string cat] function. * * Results: | | | | | 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 |
*---------------------------------------------------------------------------
*
* TclStringCat --
*
* Performs the [string cat] function.
*
* Results:
* A (Tcl_Obj *) pointing to the result value, or NULL in case of an
* error.
*
* Side effects:
* On error, when interp is not NULL, error information is left in it.
*
*---------------------------------------------------------------------------
*/
Tcl_Obj *
TclStringCat(
Tcl_Interp *interp,
|
| ︙ | ︙ | |||
3140 3141 3142 3143 3144 3145 3146 |
}
/* assert ( objc >= 2 ) */
/*
* Analyze to determine what representation result should be.
* GOALS: Avoid shimmering & string rep generation.
| | | | | | | | 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 |
}
/* assert ( objc >= 2 ) */
/*
* Analyze to determine what representation result should be.
* GOALS: Avoid shimmering & string rep generation.
* Produce pure bytearray when possible.
* Error on overflow.
*/
ov = objv, oc = objc;
do {
Tcl_Obj *objPtr = *ov++;
if (TclIsPureByteArray(objPtr)) {
allowUniChar = 0;
} else if (objPtr->bytes) {
/* Value has a string rep. */
if (objPtr->length) {
/*
* Non-empty string rep. Not a pure bytearray, so we won't
* create a pure bytearray.
*/
binary = 0;
if (ov > objv+1 && ISCONTINUATION(TclGetString(objPtr))) {
forceUniChar = 1;
} else if ((objPtr->typePtr) && (objPtr->typePtr != &tclStringType)) {
/* Prevent shimmer of non-string types. */
allowUniChar = 0;
}
}
} else {
/* assert (objPtr->typePtr != NULL) -- stork! */
binary = 0;
|
| ︙ | ︙ | |||
3264 3265 3266 3267 3268 3269 3270 |
pendingPtr = objPtr;
} else {
(void)Tcl_GetStringFromObj(objPtr, &length); /* PANIC? */
}
} while (--oc && (length == 0) && (pendingPtr == NULL));
/*
| | | | | | 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 |
pendingPtr = objPtr;
} else {
(void)Tcl_GetStringFromObj(objPtr, &length); /* PANIC? */
}
} while (--oc && (length == 0) && (pendingPtr == NULL));
/*
* Either we found a possibly non-empty value, and we remember
* this index as the first and last such value so far seen,
* or (oc == 0) and all values are known empty,
* so first = last = objc - 1 signals the right quick return.
*/
first = last = objc - oc - 1;
if (oc && (length == 0)) {
Tcl_Size numBytes;
/* assert ( pendingPtr != NULL ) */
|
| ︙ | ︙ | |||
3383 3384 3385 3386 3387 3388 3389 |
/* Ugly interface! Force resize of the unicode array. */
(void)Tcl_GetUnicodeFromObj(objResultPtr, &start);
Tcl_InvalidateStringRep(objResultPtr);
if (0 == Tcl_AttemptSetObjLength(objResultPtr, length)) {
if (interp) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
| | | | 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 |
/* Ugly interface! Force resize of the unicode array. */
(void)Tcl_GetUnicodeFromObj(objResultPtr, &start);
Tcl_InvalidateStringRep(objResultPtr);
if (0 == Tcl_AttemptSetObjLength(objResultPtr, length)) {
if (interp) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"concatenation failed: unable to alloc %"
TCL_Z_MODIFIER "u bytes",
STRING_SIZE(length)));
Tcl_SetErrorCode(interp, "TCL", "MEMORY", (void *)NULL);
}
return NULL;
}
dst = Tcl_GetUnicode(objResultPtr) + start;
} else {
Tcl_UniChar ch = 0;
/* Ugly interface! No scheme to init array size. */
objResultPtr = Tcl_NewUnicodeObj(&ch, 0); /* PANIC? */
if (0 == Tcl_AttemptSetObjLength(objResultPtr, length)) {
Tcl_DecrRefCount(objResultPtr);
if (interp) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"concatenation failed: unable to alloc %"
TCL_Z_MODIFIER "u bytes",
STRING_SIZE(length)));
Tcl_SetErrorCode(interp, "TCL", "MEMORY", (void *)NULL);
}
return NULL;
}
dst = Tcl_GetUnicode(objResultPtr);
|
| ︙ | ︙ | |||
3432 3433 3434 3435 3436 3437 3438 |
objResultPtr = *objv++; objc--;
(void)Tcl_GetStringFromObj(objResultPtr, &start);
if (0 == Tcl_AttemptSetObjLength(objResultPtr, length)) {
if (interp) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
| | | | 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 |
objResultPtr = *objv++; objc--;
(void)Tcl_GetStringFromObj(objResultPtr, &start);
if (0 == Tcl_AttemptSetObjLength(objResultPtr, length)) {
if (interp) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"concatenation failed: unable to alloc %" TCL_SIZE_MODIFIER "d bytes",
length));
Tcl_SetErrorCode(interp, "TCL", "MEMORY", (void *)NULL);
}
return NULL;
}
dst = TclGetString(objResultPtr) + start;
/* assert ( length > start ) */
TclFreeInternalRep(objResultPtr);
} else {
TclNewObj(objResultPtr); /* PANIC? */
if (0 == Tcl_AttemptSetObjLength(objResultPtr, length)) {
Tcl_DecrRefCount(objResultPtr);
if (interp) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"concatenation failed: unable to alloc %" TCL_SIZE_MODIFIER "d bytes",
length));
Tcl_SetErrorCode(interp, "TCL", "MEMORY", (void *)NULL);
}
return NULL;
}
dst = TclGetString(objResultPtr);
}
|
| ︙ | ︙ | |||
3616 3617 3618 3619 3620 3621 3622 |
int
TclStringCmp(
Tcl_Obj *value1Ptr,
Tcl_Obj *value2Ptr,
int checkEq, /* comparison is only for equality */
int nocase, /* comparison is not case sensitive */
Tcl_Size reqlength) /* requested length in characters;
| | | 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 |
int
TclStringCmp(
Tcl_Obj *value1Ptr,
Tcl_Obj *value2Ptr,
int checkEq, /* comparison is only for equality */
int nocase, /* comparison is not case sensitive */
Tcl_Size reqlength) /* requested length in characters;
* TCL_INDEX_NONE to compare whole strings */
{
const char *s1, *s2;
int empty, match;
Tcl_Size length, s1len = 0, s2len = 0;
memCmpFn_t memCmpFn;
if ((reqlength == 0) || (value1Ptr == value2Ptr)) {
|
| ︙ | ︙ | |||
3925 3926 3927 3928 3929 3930 3931 |
Tcl_Size lh = 0, ln = Tcl_GetCharLength(needle);
Tcl_Size value = -1;
Tcl_UniChar *checkStr, *uh, *un;
Tcl_Obj *obj;
if (ln == 0) {
/*
| | | | | 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 |
Tcl_Size lh = 0, ln = Tcl_GetCharLength(needle);
Tcl_Size value = -1;
Tcl_UniChar *checkStr, *uh, *un;
Tcl_Obj *obj;
if (ln == 0) {
/*
* We don't find empty substrings. Bizarre!
*
* TODO: When we one day make this a true substring
* finder, change this to "return last", after limitation.
*/
goto lastEnd;
}
if (TclIsPureByteArray(needle) && TclIsPureByteArray(haystack)) {
unsigned char *check, *bh = Tcl_GetBytesFromObj(NULL, haystack, &lh);
unsigned char *bn = Tcl_GetBytesFromObj(NULL, needle, &ln);
|
| ︙ | ︙ |
Changes to generic/tclTest.c.
| ︙ | ︙ | |||
3789 3790 3791 3792 3793 3794 3795 |
if (arg[1] != 'r') {
goto wrongArgs;
}
readonly = TCL_LINK_READ_ONLY;
i++;
}
if (Tcl_GetIndexFromObj(interp, objv[i++], LinkType, "type", 0,
| | | | 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 |
if (arg[1] != 'r') {
goto wrongArgs;
}
readonly = TCL_LINK_READ_ONLY;
i++;
}
if (Tcl_GetIndexFromObj(interp, objv[i++], LinkType, "type", 0,
&typeIndex) != TCL_OK) {
return TCL_ERROR;
}
if (Tcl_GetIntFromObj(interp, objv[i++], &size) == TCL_ERROR) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong size value", -1));
return TCL_ERROR;
}
name = Tcl_GetString(objv[i++]);
/*
* If no address is given request one in the underlying function
*/
if (i < objc) {
if (Tcl_GetWideIntFromObj(interp, objv[i], &addr) == TCL_ERROR) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"wrong address value", -1));
return TCL_ERROR;
}
} else {
addr = 0;
}
return Tcl_LinkArray(interp, name, INT2PTR(addr),
|
| ︙ | ︙ | |||
8516 8517 8518 8519 8520 8521 8522 |
TCL_UNUSED(Tcl_Interp *),
const char *name,
TCL_UNUSED(Tcl_Size) /* length */,
TCL_UNUSED(Tcl_Namespace *),
Tcl_ResolvedVarInfo **rPtr)
{
if (*name == 'T') {
| | | | | | | | | | 8516 8517 8518 8519 8520 8521 8522 8523 8524 8525 8526 8527 8528 8529 8530 8531 8532 8533 8534 8535 8536 8537 8538 |
TCL_UNUSED(Tcl_Interp *),
const char *name,
TCL_UNUSED(Tcl_Size) /* length */,
TCL_UNUSED(Tcl_Namespace *),
Tcl_ResolvedVarInfo **rPtr)
{
if (*name == 'T') {
MyResolvedVarInfo *resVarInfo = (MyResolvedVarInfo *)Tcl_Alloc(sizeof(MyResolvedVarInfo));
resVarInfo->vInfo.fetchProc = MyCompiledVarFetch;
resVarInfo->vInfo.deleteProc = MyCompiledVarFree;
resVarInfo->var = NULL;
resVarInfo->nameObj = Tcl_NewStringObj(name, -1);
Tcl_IncrRefCount(resVarInfo->nameObj);
*rPtr = &resVarInfo->vInfo;
return TCL_OK;
}
return TCL_CONTINUE;
}
static int
TestInterpResolverCmd(
TCL_UNUSED(void *),
|
| ︙ | ︙ | |||
8642 8643 8644 8645 8646 8647 8648 |
* The bug trigger. Repeating the command but:
* - we are calling apply with a lambda that is a list (as BEFORE),
* BUT
* - The body of the lambda (lambdaObjs[1]) ALREADY has internal
* representation of ByteCode and thus will not be compiled again
*/
evalObjs[1] = lambdaObj; /* lambdaObj already has a ref count so
| | | 8642 8643 8644 8645 8646 8647 8648 8649 8650 8651 8652 8653 8654 8655 8656 |
* The bug trigger. Repeating the command but:
* - we are calling apply with a lambda that is a list (as BEFORE),
* BUT
* - The body of the lambda (lambdaObjs[1]) ALREADY has internal
* representation of ByteCode and thus will not be compiled again
*/
evalObjs[1] = lambdaObj; /* lambdaObj already has a ref count so
no need for IncrRef */
result = Tcl_EvalObjv(interp, 2, evalObjs, TCL_EVAL_GLOBAL);
Tcl_DecrRefCount(evalObjs[0]);
Tcl_DecrRefCount(lambdaObj);
return result;
}
|
| ︙ | ︙ |
Changes to generic/tclTestABSList.c.
| ︙ | ︙ | |||
9 10 11 12 13 14 15 | #include <limits.h> #include "tclInt.h" /* * Forward references */ | | | | | | < | | | | | | < | | > | | | | | | < | < | | | < | | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
#include <limits.h>
#include "tclInt.h"
/*
* Forward references
*/
Tcl_Obj * myNewLStringObj(Tcl_WideInt start,
Tcl_WideInt length);
static void freeRep(Tcl_Obj* alObj);
static Tcl_Obj * my_LStringObjSetElem(Tcl_Interp *interp,
Tcl_Obj *listPtr, Tcl_Size numIndcies,
Tcl_Obj *const indicies[],
Tcl_Obj *valueObj);
static void DupLStringRep(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr);
static Tcl_Size my_LStringObjLength(Tcl_Obj *lstringObjPtr);
static int my_LStringObjIndex(Tcl_Interp *interp,
Tcl_Obj *lstringObj, Tcl_Size index,
Tcl_Obj **charObjPtr);
static int my_LStringObjRange(Tcl_Interp *interp,
Tcl_Obj *lstringObj,
Tcl_Size fromIdx, Tcl_Size toIdx,
Tcl_Obj **newObjPtr);
static int my_LStringObjReverse(Tcl_Interp *interp,
Tcl_Obj *srcObj, Tcl_Obj **newObjPtr);
static int my_LStringReplace(Tcl_Interp *interp,
Tcl_Obj *listObj, Tcl_Size first,
Tcl_Size numToDelete, Tcl_Size numToInsert,
Tcl_Obj *const insertObjs[]);
static int my_LStringGetElements(Tcl_Interp *interp,
Tcl_Obj *listPtr, Tcl_Size *objcptr,
Tcl_Obj ***objvptr);
static void lstringFreeElements(Tcl_Obj* lstringObj);
static void UpdateStringOfLString(Tcl_Obj *objPtr);
/*
* Internal Representation of an lstring type value
*/
typedef struct LString {
char *string; // NULL terminated utf-8 string
|
| ︙ | ︙ | |||
297 298 299 300 301 302 303 | * Side effects: * None. * *---------------------------------------------------------------------- */ static Tcl_Size | | > | > | 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 |
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
static Tcl_Size
my_LStringObjLength(
Tcl_Obj *lstringObjPtr)
{
LString *lstringRepPtr = (LString *)
lstringObjPtr->internalRep.twoPtrValue.ptr1;
return lstringRepPtr->strlen;
}
/*
*----------------------------------------------------------------------
*
|
| ︙ | ︙ | |||
322 323 324 325 326 327 328 | * Side effects: * Modifies the rep of the copyObj. * *---------------------------------------------------------------------- */ static void | | > > | | | | | | | > | | | | < < | 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 |
* Side effects:
* Modifies the rep of the copyObj.
*
*----------------------------------------------------------------------
*/
static void
DupLStringRep(
Tcl_Obj *srcPtr,
Tcl_Obj *copyPtr)
{
LString *srcLString = (LString*)srcPtr->internalRep.twoPtrValue.ptr1;
LString *copyLString = (LString*)Tcl_Alloc(sizeof(LString));
memcpy(copyLString, srcLString, sizeof(LString));
copyLString->string = (char*)Tcl_Alloc(srcLString->allocated);
strncpy(copyLString->string, srcLString->string, srcLString->strlen);
copyLString->string[srcLString->strlen] = '\0';
copyLString->elements = NULL;
Tcl_ObjInternalRep itr;
itr.twoPtrValue.ptr1 = copyLString;
itr.twoPtrValue.ptr2 = NULL;
Tcl_StoreInternalRep(copyPtr, srcPtr->typePtr, &itr);
}
/*
*----------------------------------------------------------------------
*
* my_LStringObjSetElem --
*
|
| ︙ | ︙ | |||
368 369 370 371 372 373 374 |
my_LStringObjSetElem(
Tcl_Interp *interp,
Tcl_Obj *lstringObj,
Tcl_Size numIndicies,
Tcl_Obj *const indicies[],
Tcl_Obj *valueObj)
{
| | > | 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 |
my_LStringObjSetElem(
Tcl_Interp *interp,
Tcl_Obj *lstringObj,
Tcl_Size numIndicies,
Tcl_Obj *const indicies[],
Tcl_Obj *valueObj)
{
LString *lstringRepPtr = (LString*)
lstringObj->internalRep.twoPtrValue.ptr1;
Tcl_Size index;
int status;
Tcl_Obj *returnObj;
if (numIndicies > 1) {
Tcl_SetObjResult(interp,
Tcl_ObjPrintf("Multiple indicies not supported by lstring."));
|
| ︙ | ︙ | |||
390 391 392 393 394 395 396 |
returnObj = Tcl_IsShared(lstringObj) ? Tcl_DuplicateObj(lstringObj) : lstringObj;
lstringRepPtr = (LString*)returnObj->internalRep.twoPtrValue.ptr1;
if (index >= lstringRepPtr->strlen) {
index = lstringRepPtr->strlen;
lstringRepPtr->strlen++;
| > | | 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 |
returnObj = Tcl_IsShared(lstringObj) ? Tcl_DuplicateObj(lstringObj) : lstringObj;
lstringRepPtr = (LString*)returnObj->internalRep.twoPtrValue.ptr1;
if (index >= lstringRepPtr->strlen) {
index = lstringRepPtr->strlen;
lstringRepPtr->strlen++;
lstringRepPtr->string = (char*)
Tcl_Realloc(lstringRepPtr->string, lstringRepPtr->strlen+1);
}
if (valueObj) {
const char newvalue = Tcl_GetString(valueObj)[0];
lstringRepPtr->string[index] = newvalue;
} else if (index < lstringRepPtr->strlen) {
/* Remove the char by sliding the tail of the string down */
|
| ︙ | ︙ | |||
426 427 428 429 430 431 432 | * * Side effects: * A new Obj is created. * *---------------------------------------------------------------------- */ | > | | 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 |
*
* Side effects:
* A new Obj is created.
*
*----------------------------------------------------------------------
*/
static int
my_LStringObjRange(
Tcl_Interp *interp,
Tcl_Obj *lstringObj,
Tcl_Size fromIdx,
Tcl_Size toIdx,
Tcl_Obj **newObjPtr)
{
Tcl_Obj *rangeObj;
|
| ︙ | ︙ | |||
489 490 491 492 493 494 495 | * Side effects: * A new Obj is created. * *---------------------------------------------------------------------- */ static int | | > > > | 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 |
* Side effects:
* A new Obj is created.
*
*----------------------------------------------------------------------
*/
static int
my_LStringObjReverse(
Tcl_Interp *interp,
Tcl_Obj *srcObj,
Tcl_Obj **newObjPtr)
{
LString *srcRep = (LString*)srcObj->internalRep.twoPtrValue.ptr1;
Tcl_Obj *revObj;
LString *revRep = (LString*)Tcl_Alloc(sizeof(LString));
Tcl_ObjInternalRep itr;
Tcl_Size len;
char *srcp, *dstp, *endp;
|
| ︙ | ︙ | |||
634 635 636 637 638 639 640 |
Tcl_InvalidateStringRep(listObj);
lstringFreeElements(listObj);
return TCL_OK;
}
static const Tcl_ObjType *
| | > | 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 |
Tcl_InvalidateStringRep(listObj);
lstringFreeElements(listObj);
return TCL_OK;
}
static const Tcl_ObjType *
my_SetAbstractProc(
int ptype)
{
const Tcl_ObjType *typePtr = &lstringTypes[0]; /* default value */
if (4 <= ptype && ptype <= 11) {
/* Table has no entries for the slots upto setfromany */
typePtr = &lstringTypes[(ptype-3)];
}
return typePtr;
|
| ︙ | ︙ | |||
734 735 736 737 738 739 740 | * freeElements -- * * Free the element array * */ static void | | > | 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 |
* freeElements --
*
* Free the element array
*
*/
static void
lstringFreeElements(
Tcl_Obj* lstringObj)
{
LString *lstringRepPtr = (LString*)lstringObj->internalRep.twoPtrValue.ptr1;
if (lstringRepPtr->elements) {
Tcl_Obj **objptr = lstringRepPtr->elements;
while (objptr < &lstringRepPtr->elements[lstringRepPtr->strlen]) {
Tcl_DecrRefCount(*objptr++);
}
|
| ︙ | ︙ | |||
764 765 766 767 768 769 770 | * Side effects: * Memory free'd. * *---------------------------------------------------------------------- */ static void | > | | 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 |
* Side effects:
* Memory free'd.
*
*----------------------------------------------------------------------
*/
static void
freeRep(
Tcl_Obj* lstringObj)
{
LString *lstringRepPtr = (LString*)lstringObj->internalRep.twoPtrValue.ptr1;
if (lstringRepPtr->string) {
Tcl_Free(lstringRepPtr->string);
}
lstringFreeElements(lstringObj);
Tcl_Free((char*)lstringRepPtr);
|
| ︙ | ︙ | |||
791 792 793 794 795 796 797 | * * Side effects: * A Tcl_Obj is stored for every element of the abstract list * *---------------------------------------------------------------------- */ | > | > | | | | 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 |
*
* Side effects:
* A Tcl_Obj is stored for every element of the abstract list
*
*----------------------------------------------------------------------
*/
static int
my_LStringGetElements(
Tcl_Interp *interp,
Tcl_Obj *lstringObj,
Tcl_Size *objcptr,
Tcl_Obj ***objvptr)
{
LString *lstringRepPtr = (LString*)lstringObj->internalRep.twoPtrValue.ptr1;
Tcl_Obj **objPtr;
char *cptr = lstringRepPtr->string;
(void)interp;
if (lstringRepPtr->strlen == 0) {
*objcptr = 0;
|
| ︙ | ︙ | |||
823 824 825 826 827 828 829 | } /* ** UpdateStringRep */ static void | | > | 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 |
}
/*
** UpdateStringRep
*/
static void
UpdateStringOfLString(
Tcl_Obj *objPtr)
{
# define LOCAL_SIZE 64
int localFlags[LOCAL_SIZE], *flagPtr = NULL;
Tcl_ObjType const *typePtr = objPtr->typePtr;
char *p;
int bytesNeeded = 0;
int llen, i;
|
| ︙ | ︙ | |||
855 856 857 858 859 860 861 862 863 864 865 866 867 868 |
/* We know numElems <= LIST_MAX, so this is safe. */
flagPtr = (int *) Tcl_Alloc(llen*sizeof(int));
}
for (bytesNeeded = 0, i = 0; i < llen; i++) {
Tcl_Obj *elemObj;
const char *elemStr;
Tcl_Size elemLen;
flagPtr[i] = (i ? TCL_DONT_QUOTE_HASH : 0);
typePtr->indexProc(NULL, objPtr, i, &elemObj);
Tcl_IncrRefCount(elemObj);
elemStr = Tcl_GetStringFromObj(elemObj, &elemLen);
/* Note TclScanElement updates flagPtr[i] */
bytesNeeded += Tcl_ScanCountedElement(elemStr, elemLen, &flagPtr[i]);
if (bytesNeeded < 0) {
| > | 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 |
/* We know numElems <= LIST_MAX, so this is safe. */
flagPtr = (int *) Tcl_Alloc(llen*sizeof(int));
}
for (bytesNeeded = 0, i = 0; i < llen; i++) {
Tcl_Obj *elemObj;
const char *elemStr;
Tcl_Size elemLen;
flagPtr[i] = (i ? TCL_DONT_QUOTE_HASH : 0);
typePtr->indexProc(NULL, objPtr, i, &elemObj);
Tcl_IncrRefCount(elemObj);
elemStr = Tcl_GetStringFromObj(elemObj, &elemLen);
/* Note TclScanElement updates flagPtr[i] */
bytesNeeded += Tcl_ScanCountedElement(elemStr, elemLen, &flagPtr[i]);
if (bytesNeeded < 0) {
|
| ︙ | ︙ | |||
880 881 882 883 884 885 886 887 888 889 890 891 892 893 |
*/
objPtr->bytes = (char *) Tcl_Alloc(bytesNeeded);
p = objPtr->bytes;
for (i = 0; i < llen; i++) {
Tcl_Obj *elemObj;
const char *elemStr;
Tcl_Size elemLen;
flagPtr[i] |= (i ? TCL_DONT_QUOTE_HASH : 0);
typePtr->indexProc(NULL, objPtr, i, &elemObj);
Tcl_IncrRefCount(elemObj);
elemStr = Tcl_GetStringFromObj(elemObj, &elemLen);
p += Tcl_ConvertCountedElement(elemStr, elemLen, p, flagPtr[i]);
*p++ = ' ';
Tcl_DecrRefCount(elemObj);
| > | 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 |
*/
objPtr->bytes = (char *) Tcl_Alloc(bytesNeeded);
p = objPtr->bytes;
for (i = 0; i < llen; i++) {
Tcl_Obj *elemObj;
const char *elemStr;
Tcl_Size elemLen;
flagPtr[i] |= (i ? TCL_DONT_QUOTE_HASH : 0);
typePtr->indexProc(NULL, objPtr, i, &elemObj);
Tcl_IncrRefCount(elemObj);
elemStr = Tcl_GetStringFromObj(elemObj, &elemLen);
p += Tcl_ConvertCountedElement(elemStr, elemLen, p, flagPtr[i]);
*p++ = ' ';
Tcl_DecrRefCount(elemObj);
|
| ︙ | ︙ | |||
1038 1039 1040 1041 1042 1043 1044 | } /* ** UpdateStringRep */ static void | | > | 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 |
}
/*
** UpdateStringRep
*/
static void
UpdateStringOfLgen(
Tcl_Obj *objPtr)
{
LgenSeries *lgenSeriesRepPtr;
Tcl_Obj *element;
Tcl_Size i;
size_t bytlen;
Tcl_Obj *tmpstr = Tcl_NewObj();
|
| ︙ | ︙ | |||
1069 1070 1071 1072 1073 1074 1075 |
return;
}
/*
* ObjType Free Internal Rep function
*/
static void
| | > | 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 |
return;
}
/*
* ObjType Free Internal Rep function
*/
static void
FreeLgenInternalRep(
Tcl_Obj *objPtr)
{
LgenSeries *lgenSeries = (LgenSeries*)objPtr->internalRep.twoPtrValue.ptr1;
if (lgenSeries->genFnObj) {
Tcl_DecrRefCount(lgenSeries->genFnObj);
}
lgenSeries->interp = NULL;
Tcl_Free(lgenSeries);
|
| ︙ | ︙ | |||
1206 1207 1208 1209 1210 1211 1212 |
if (Tcl_InitStubs(interp, "8.7", 0) == NULL) {
return TCL_ERROR;
}
Tcl_CreateObjCommand(interp, "lgen", lGenObjCmd, NULL, NULL);
Tcl_PkgProvide(interp, "lgen", "1.0");
return TCL_OK;
}
| < < | 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 |
if (Tcl_InitStubs(interp, "8.7", 0) == NULL) {
return TCL_ERROR;
}
Tcl_CreateObjCommand(interp, "lgen", lGenObjCmd, NULL, NULL);
Tcl_PkgProvide(interp, "lgen", "1.0");
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
* ABSListTest_Init --
*
* Provides Abstract List implemenations via new commands
|
| ︙ | ︙ | |||
1241 1242 1243 1244 1245 1246 1247 | * * Side effects: * New commands defined. * *---------------------------------------------------------------------- */ | > | > > | 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 |
*
* Side effects:
* New commands defined.
*
*----------------------------------------------------------------------
*/
int
Tcl_ABSListTest_Init(
Tcl_Interp *interp)
{
if (Tcl_InitStubs(interp, "8.7-", 0) == NULL) {
return TCL_ERROR;
}
Tcl_CreateObjCommand(interp, "lstring", lLStringObjCmd, NULL, NULL);
Tcl_CreateObjCommand(interp, "lgen", lGenObjCmd, NULL, NULL);
Tcl_PkgProvide(interp, "abstractlisttest", "1.0.0");
return TCL_OK;
}
|
Changes to generic/tclThreadStorage.c.
| ︙ | ︙ | |||
44 45 46 47 48 49 50 |
} tsdGlobal = { NULL, 0, NULL };
/*
* The type of the data held per thread in a system TSD.
*/
typedef struct {
| | | 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
} tsdGlobal = { NULL, 0, NULL };
/*
* The type of the data held per thread in a system TSD.
*/
typedef struct {
void **tablePtr; /* The table of Tcl TSDs. */
sig_atomic_t allocated; /* The size of the table in the current
* thread. */
} TSDTable;
/*
* The actual type of Tcl_ThreadDataKey.
*/
|
| ︙ | ︙ |
Changes to generic/tclThreadTest.c.
| ︙ | ︙ | |||
981 982 983 984 985 986 987 |
* Since Tcl_CancelEval can be safely called from any thread,
* we do it now.
*/
Tcl_MutexUnlock(&threadMutex);
Tcl_ResetResult(interp);
return Tcl_CancelEval(tsdPtr->interp,
| | | 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 |
* Since Tcl_CancelEval can be safely called from any thread,
* we do it now.
*/
Tcl_MutexUnlock(&threadMutex);
Tcl_ResetResult(interp);
return Tcl_CancelEval(tsdPtr->interp,
(result != NULL) ? Tcl_NewStringObj(result, -1) : NULL, 0, flags);
}
/*
*------------------------------------------------------------------------
*
* ThreadEventProc --
*
|
| ︙ | ︙ |
Changes to generic/tclTimer.c.
| ︙ | ︙ | |||
17 18 19 20 21 22 23 |
* type. The normal handlers (created by Tcl_CreateTimerHandler) are chained
* together in a list sorted by time (earliest event first).
*/
typedef struct TimerHandler {
Tcl_Time time; /* When timer is to fire. */
Tcl_TimerProc *proc; /* Function to call. */
| | | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
* type. The normal handlers (created by Tcl_CreateTimerHandler) are chained
* together in a list sorted by time (earliest event first).
*/
typedef struct TimerHandler {
Tcl_Time time; /* When timer is to fire. */
Tcl_TimerProc *proc; /* Function to call. */
void *clientData; /* Argument to pass to proc. */
Tcl_TimerToken token; /* Identifies handler so it can be deleted. */
struct TimerHandler *nextPtr;
/* Next event in queue, or NULL for end of
* queue. */
} TimerHandler;
/*
|
| ︙ | ︙ | |||
69 70 71 72 73 74 75 |
* There is one of the following structures for each of the handlers declared
* in a call to Tcl_DoWhenIdle. All of the currently-active handlers are
* linked together into a list.
*/
typedef struct IdleHandler {
Tcl_IdleProc *proc; /* Function to call. */
| | | 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
* There is one of the following structures for each of the handlers declared
* in a call to Tcl_DoWhenIdle. All of the currently-active handlers are
* linked together into a list.
*/
typedef struct IdleHandler {
Tcl_IdleProc *proc; /* Function to call. */
void *clientData; /* Value to pass to proc. */
int generation; /* Used to distinguish older handlers from
* recently-created ones. */
struct IdleHandler *nextPtr;/* Next in list of active handlers. */
} IdleHandler;
/*
* The timer and idle queues are per-thread because they are associated with
|
| ︙ | ︙ | |||
247 248 249 250 251 252 253 |
*/
Tcl_TimerToken
Tcl_CreateTimerHandler(
int milliseconds, /* How many milliseconds to wait before
* invoking proc. */
Tcl_TimerProc *proc, /* Function to invoke. */
| | | 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 |
*/
Tcl_TimerToken
Tcl_CreateTimerHandler(
int milliseconds, /* How many milliseconds to wait before
* invoking proc. */
Tcl_TimerProc *proc, /* Function to invoke. */
void *clientData) /* Arbitrary data to pass to proc. */
{
Tcl_Time time;
/*
* Compute when the event should fire.
*/
|
| ︙ | ︙ | |||
615 616 617 618 619 620 621 |
*
*--------------------------------------------------------------
*/
void
Tcl_DoWhenIdle(
Tcl_IdleProc *proc, /* Function to invoke. */
| | | 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 |
*
*--------------------------------------------------------------
*/
void
Tcl_DoWhenIdle(
Tcl_IdleProc *proc, /* Function to invoke. */
void *clientData) /* Arbitrary value to pass to proc. */
{
IdleHandler *idlePtr;
Tcl_Time blockTime;
ThreadSpecificData *tsdPtr = InitTimer();
idlePtr = (IdleHandler *)Tcl_Alloc(sizeof(IdleHandler));
idlePtr->proc = proc;
|
| ︙ | ︙ | |||
659 660 661 662 663 664 665 |
*
*----------------------------------------------------------------------
*/
void
Tcl_CancelIdleCall(
Tcl_IdleProc *proc, /* Function that was previously registered. */
| | | 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 |
*
*----------------------------------------------------------------------
*/
void
Tcl_CancelIdleCall(
Tcl_IdleProc *proc, /* Function that was previously registered. */
void *clientData) /* Arbitrary value to pass to proc. */
{
IdleHandler *idlePtr, *prevPtr;
IdleHandler *nextPtr;
ThreadSpecificData *tsdPtr = InitTimer();
for (prevPtr = NULL, idlePtr = tsdPtr->idleList; idlePtr != NULL;
prevPtr = idlePtr, idlePtr = idlePtr->nextPtr) {
|
| ︙ | ︙ | |||
1145 1146 1147 1148 1149 1150 1151 | * bgerror fails then information about the error is output on stderr. * *---------------------------------------------------------------------- */ static void AfterProc( | | | 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 |
* bgerror fails then information about the error is output on stderr.
*
*----------------------------------------------------------------------
*/
static void
AfterProc(
void *clientData) /* Describes command to execute. */
{
AfterInfo *afterPtr = (AfterInfo *)clientData;
AfterAssocData *assocPtr = afterPtr->assocPtr;
AfterInfo *prevPtr;
int result;
Tcl_Interp *interp;
|
| ︙ | ︙ | |||
1247 1248 1249 1250 1251 1252 1253 | * After commands are removed. * *---------------------------------------------------------------------- */ static void AfterCleanupProc( | | | 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 |
* After commands are removed.
*
*----------------------------------------------------------------------
*/
static void
AfterCleanupProc(
void *clientData, /* Points to AfterAssocData for the
* interpreter. */
TCL_UNUSED(Tcl_Interp *))
{
AfterAssocData *assocPtr = (AfterAssocData *)clientData;
AfterInfo *afterPtr;
while (assocPtr->firstAfterPtr != NULL) {
|
| ︙ | ︙ |
Changes to generic/tclTrace.c.
| ︙ | ︙ | |||
18 19 20 21 22 23 24 |
* Structures used to hold information about variable traces:
*/
typedef struct {
int flags; /* Operations for which Tcl command is to be
* invoked. */
Tcl_Size length; /* Number of non-NUL chars. in command. */
| | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
* Structures used to hold information about variable traces:
*/
typedef struct {
int flags; /* Operations for which Tcl command is to be
* invoked. */
Tcl_Size length; /* Number of non-NUL chars. in command. */
char command[TCLFLEXARRAY]; /* Space for Tcl command to invoke. Actual
* size will be as large as necessary to hold
* command. This field must be the last in the
* structure, so that it can be larger than 1
* byte. */
} TraceVarInfo;
typedef struct {
|
| ︙ | ︙ | |||
40 41 42 43 44 45 46 |
typedef struct {
int flags; /* Operations for which Tcl command is to be
* invoked. */
Tcl_Size length; /* Number of non-NUL chars. in command. */
Tcl_Trace stepTrace; /* Used for execution traces, when tracing
* inside the given command */
| | | | 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
typedef struct {
int flags; /* Operations for which Tcl command is to be
* invoked. */
Tcl_Size length; /* Number of non-NUL chars. in command. */
Tcl_Trace stepTrace; /* Used for execution traces, when tracing
* inside the given command */
Tcl_Size startLevel; /* Used for bookkeeping with step execution
* traces, store the level at which the step
* trace was invoked */
char *startCmd; /* Used for bookkeeping with step execution
* traces, store the command name which
* invoked step trace */
int curFlags; /* Trace flags for the current command */
int curCode; /* Return code for the current command */
size_t refCount; /* Used to ensure this structure is not
* deleted too early. Keeps track of how many
* pieces of code have a pointer to this
* structure. */
char command[TCLFLEXARRAY]; /* Space for Tcl command to invoke. Actual
* size will be as large as necessary to hold
* command. This field must be the last in the
* structure, so that it can be larger than 1
* byte. */
} TraceCommandInfo;
/*
|
| ︙ | ︙ | |||
142 143 144 145 146 147 148 |
/*
* The following structure holds the client data for string-based
* trace procs
*/
typedef struct {
| | | | | | | 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
/*
* The following structure holds the client data for string-based
* trace procs
*/
typedef struct {
void *clientData; /* Client data from Tcl_CreateTrace */
Tcl_CmdTraceProc *proc; /* Trace function from Tcl_CreateTrace */
} StringTraceData;
/*
* Convenience macros for iterating over the list of traces. Note that each of
* these *must* be treated as a command, and *must* have a block following it.
*/
#define FOREACH_VAR_TRACE(interp, name, clientData) \
(clientData) = NULL; \
while (((clientData) = Tcl_VarTraceInfo2((interp), (name), NULL, \
0, TraceVarProc, (clientData))) != NULL)
#define FOREACH_COMMAND_TRACE(interp, name, clientData) \
(clientData) = NULL; \
while (((clientData) = Tcl_CommandTraceInfo((interp), (name), 0, \
TraceCommandProc, (clientData))) != NULL)
/*
*----------------------------------------------------------------------
*
* Tcl_TraceObjCmd --
*
|
| ︙ | ︙ | |||
275 276 277 278 279 280 281 |
*
*----------------------------------------------------------------------
*/
static int
TraceExecutionObjCmd(
Tcl_Interp *interp, /* Current interpreter. */
| | > | | 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 |
*
*----------------------------------------------------------------------
*/
static int
TraceExecutionObjCmd(
Tcl_Interp *interp, /* Current interpreter. */
enum traceOptionsEnum optionIndex,
/* Add, info or remove */
Tcl_Size objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
const char *name, *command;
Tcl_Size length;
static const char *const opStrings[] = {
"enter", "leave", "enterstep", "leavestep", NULL
};
|
| ︙ | ︙ | |||
522 523 524 525 526 527 528 |
*
*----------------------------------------------------------------------
*/
static int
TraceCommandObjCmd(
Tcl_Interp *interp, /* Current interpreter. */
| | > | | 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 |
*
*----------------------------------------------------------------------
*/
static int
TraceCommandObjCmd(
Tcl_Interp *interp, /* Current interpreter. */
enum traceOptionsEnum optionIndex,
/* Add, info or remove */
Tcl_Size objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
const char *name, *command;
Tcl_Size length;
static const char *const opStrings[] = { "delete", "rename", NULL };
enum operations { TRACE_CMD_DELETE, TRACE_CMD_RENAME } index;
|
| ︙ | ︙ | |||
716 717 718 719 720 721 722 |
*
*----------------------------------------------------------------------
*/
static int
TraceVariableObjCmd(
Tcl_Interp *interp, /* Current interpreter. */
| | > | | 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 |
*
*----------------------------------------------------------------------
*/
static int
TraceVariableObjCmd(
Tcl_Interp *interp, /* Current interpreter. */
enum traceOptionsEnum optionIndex,
/* Add, info or remove */
Tcl_Size objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
const char *name, *command;
Tcl_Size length;
void *clientData;
static const char *const opStrings[] = {
"array", "read", "unset", "write", NULL
|
| ︙ | ︙ | |||
977 978 979 980 981 982 983 |
* traced. */
const char *cmdName, /* Name of command. */
int flags, /* OR-ed collection of bits, including any of
* TCL_TRACE_RENAME, TCL_TRACE_DELETE, and any
* of the TRACE_*_EXEC flags */
Tcl_CommandTraceProc *proc, /* Function to call when specified ops are
* invoked upon cmdName. */
| | | 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 |
* traced. */
const char *cmdName, /* Name of command. */
int flags, /* OR-ed collection of bits, including any of
* TCL_TRACE_RENAME, TCL_TRACE_DELETE, and any
* of the TRACE_*_EXEC flags */
Tcl_CommandTraceProc *proc, /* Function to call when specified ops are
* invoked upon cmdName. */
void *clientData) /* Arbitrary argument to pass to proc. */
{
Command *cmdPtr;
CommandTrace *tracePtr;
cmdPtr = (Command *) Tcl_FindCommand(interp, cmdName, NULL,
TCL_LEAVE_ERR_MSG);
if (cmdPtr == NULL) {
|
| ︙ | ︙ | |||
1041 1042 1043 1044 1045 1046 1047 |
Tcl_UntraceCommand(
Tcl_Interp *interp, /* Interpreter containing command. */
const char *cmdName, /* Name of command. */
int flags, /* OR-ed collection of bits, including any of
* TCL_TRACE_RENAME, TCL_TRACE_DELETE, and any
* of the TRACE_*_EXEC flags */
Tcl_CommandTraceProc *proc, /* Function assocated with trace. */
| | | 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 |
Tcl_UntraceCommand(
Tcl_Interp *interp, /* Interpreter containing command. */
const char *cmdName, /* Name of command. */
int flags, /* OR-ed collection of bits, including any of
* TCL_TRACE_RENAME, TCL_TRACE_DELETE, and any
* of the TRACE_*_EXEC flags */
Tcl_CommandTraceProc *proc, /* Function assocated with trace. */
void *clientData) /* Arbitrary argument to pass to proc. */
{
CommandTrace *tracePtr;
CommandTrace *prevPtr;
Command *cmdPtr;
Interp *iPtr = (Interp *)interp;
ActiveCommandTrace *activePtr;
int hasExecTraces = 0;
|
| ︙ | ︙ | |||
1146 1147 1148 1149 1150 1151 1152 | * Depends on the command associated with the trace. * *---------------------------------------------------------------------- */ static void TraceCommandProc( | | | 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 |
* Depends on the command associated with the trace.
*
*----------------------------------------------------------------------
*/
static void
TraceCommandProc(
void *clientData, /* Information about the command trace. */
Tcl_Interp *interp, /* Interpreter containing command. */
const char *oldName, /* Name of command being changed. */
const char *newName, /* New name of command. Empty string or NULL
* means command is being deleted (renamed to
* ""). */
int flags) /* OR-ed bits giving operation and other
* information. */
|
| ︙ | ︙ | |||
1291 1292 1293 1294 1295 1296 1297 |
Tcl_Interp *interp, /* The current interpreter. */
const char *command, /* Pointer to beginning of the current command
* string. */
TCL_UNUSED(Tcl_Size) /*numChars*/,
Command *cmdPtr, /* Points to command's Command struct. */
int code, /* The current result code. */
int traceFlags, /* Current tracing situation. */
| | | 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 |
Tcl_Interp *interp, /* The current interpreter. */
const char *command, /* Pointer to beginning of the current command
* string. */
TCL_UNUSED(Tcl_Size) /*numChars*/,
Command *cmdPtr, /* Points to command's Command struct. */
int code, /* The current result code. */
int traceFlags, /* Current tracing situation. */
Tcl_Size objc, /* Number of arguments for the command. */
Tcl_Obj *const objv[]) /* Pointers to Tcl_Obj of each argument. */
{
Interp *iPtr = (Interp *) interp;
CommandTrace *tracePtr, *lastTracePtr;
ActiveCommandTrace active;
Tcl_Size curLevel;
int traceCode = TCL_OK;
|
| ︙ | ︙ | |||
1397 1398 1399 1400 1401 1402 1403 |
const char *command, /* Pointer to beginning of the current command
* string. */
Tcl_Size numChars, /* The number of characters in 'command' which
* are part of the command string. */
Command *cmdPtr, /* Points to command's Command struct. */
int code, /* The current result code. */
int traceFlags, /* Current tracing situation. */
| | | 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 |
const char *command, /* Pointer to beginning of the current command
* string. */
Tcl_Size numChars, /* The number of characters in 'command' which
* are part of the command string. */
Command *cmdPtr, /* Points to command's Command struct. */
int code, /* The current result code. */
int traceFlags, /* Current tracing situation. */
Tcl_Size objc, /* Number of arguments for the command. */
Tcl_Obj *const objv[]) /* Pointers to Tcl_Obj of each argument. */
{
Interp *iPtr = (Interp *) interp;
Trace *tracePtr, *lastTracePtr;
ActiveInterpTrace active;
Tcl_Size curLevel;
int traceCode = TCL_OK;
|
| ︙ | ︙ | |||
1535 1536 1537 1538 1539 1540 1541 |
*
*----------------------------------------------------------------------
*/
static int
CallTraceFunction(
Tcl_Interp *interp, /* The current interpreter. */
| | | 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 |
*
*----------------------------------------------------------------------
*/
static int
CallTraceFunction(
Tcl_Interp *interp, /* The current interpreter. */
Trace *tracePtr, /* Describes the trace function to call. */
Command *cmdPtr, /* Points to command's Command struct. */
const char *command, /* Points to the first character of the
* command's source before substitutions. */
Tcl_Size numChars, /* The number of characters in the command's
* source. */
Tcl_Size objc, /* Number of arguments for the command. */
Tcl_Obj *const objv[]) /* Pointers to Tcl_Obj of each argument. */
|
| ︙ | ︙ | |||
1830 1831 1832 1833 1834 1835 1836 | * Depends on the command associated with the trace. * *---------------------------------------------------------------------- */ static char * TraceVarProc( | | | 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 |
* Depends on the command associated with the trace.
*
*----------------------------------------------------------------------
*/
static char *
TraceVarProc(
void *clientData, /* Information about the variable trace. */
Tcl_Interp *interp, /* Interpreter containing variable. */
const char *name1, /* Name of variable or array. */
const char *name2, /* Name of element within array; NULL means
* scalar variable is being referenced. */
int flags) /* OR-ed bits giving operation and other
* information. */
{
|
| ︙ | ︙ | |||
2010 2011 2012 2013 2014 2015 2016 |
}
Tcl_Free(info);
}
Tcl_Trace
Tcl_CreateObjTrace(
Tcl_Interp *interp, /* Tcl interpreter */
| | | | | | 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 |
}
Tcl_Free(info);
}
Tcl_Trace
Tcl_CreateObjTrace(
Tcl_Interp *interp, /* Tcl interpreter */
Tcl_Size level, /* Maximum nesting level */
int flags, /* Flags, see above */
Tcl_CmdObjTraceProc *proc, /* Trace callback */
void *clientData, /* Client data for the callback */
Tcl_CmdObjTraceDeleteProc *delProc)
/* Function to call when trace is deleted */
{
TraceWrapperInfo *info = (TraceWrapperInfo *)Tcl_Alloc(sizeof(TraceWrapperInfo));
info->proc = proc;
info->delProc = delProc;
info->clientData = clientData;
return Tcl_CreateObjTrace2(interp, level, flags,
(proc ? traceWrapperProc : NULL),
info, traceWrapperDelProc);
}
Tcl_Trace
Tcl_CreateObjTrace2(
Tcl_Interp *interp, /* Tcl interpreter */
Tcl_Size level, /* Maximum nesting level */
int flags, /* Flags, see above */
Tcl_CmdObjTraceProc2 *proc, /* Trace callback */
void *clientData, /* Client data for the callback */
Tcl_CmdObjTraceDeleteProc *delProc)
/* Function to call when trace is deleted */
{
Trace *tracePtr;
Interp *iPtr = (Interp *) interp;
/*
|
| ︙ | ︙ | |||
2118 2119 2120 2121 2122 2123 2124 |
*
*----------------------------------------------------------------------
*/
Tcl_Trace
Tcl_CreateTrace(
Tcl_Interp *interp, /* Interpreter in which to create trace. */
| | | | 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 |
*
*----------------------------------------------------------------------
*/
Tcl_Trace
Tcl_CreateTrace(
Tcl_Interp *interp, /* Interpreter in which to create trace. */
Tcl_Size level, /* Only call proc for commands at nesting
* level<=argument level (1=>top level). */
Tcl_CmdTraceProc *proc, /* Function to call before executing each
* command. */
void *clientData) /* Arbitrary value word to pass to proc. */
{
StringTraceData *data = (StringTraceData *)Tcl_Alloc(sizeof(StringTraceData));
data->clientData = clientData;
data->proc = proc;
return Tcl_CreateObjTrace2(interp, level, 0, StringTraceProc,
data, StringTraceDeleteProc);
|
| ︙ | ︙ | |||
2428 2429 2430 2431 2432 2433 2434 |
*
*----------------------------------------------------------------------
*/
int
TclObjCallVarTraces(
Interp *iPtr, /* Interpreter containing variable. */
| | | 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 |
*
*----------------------------------------------------------------------
*/
int
TclObjCallVarTraces(
Interp *iPtr, /* Interpreter containing variable. */
Var *arrayPtr, /* Pointer to array variable that contains the
* variable, or NULL if the variable isn't an
* element of an array. */
Var *varPtr, /* Variable whose traces are to be invoked. */
Tcl_Obj *part1Ptr,
Tcl_Obj *part2Ptr, /* Variable's two-part name. */
int flags, /* Flags passed to trace functions: indicates
* what's happening to variable, plus maybe
|
| ︙ | ︙ | |||
2462 2463 2464 2465 2466 2467 2468 |
return TclCallVarTraces(iPtr, arrayPtr, varPtr, part1, part2, flags,
leaveErrMsg);
}
int
TclCallVarTraces(
Interp *iPtr, /* Interpreter containing variable. */
| | | 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 |
return TclCallVarTraces(iPtr, arrayPtr, varPtr, part1, part2, flags,
leaveErrMsg);
}
int
TclCallVarTraces(
Interp *iPtr, /* Interpreter containing variable. */
Var *arrayPtr, /* Pointer to array variable that contains the
* variable, or NULL if the variable isn't an
* element of an array. */
Var *varPtr, /* Variable whose traces are to be invoked. */
const char *part1,
const char *part2, /* Variable's two-part name. */
int flags, /* Flags passed to trace functions: indicates
* what's happening to variable, plus maybe
|
| ︙ | ︙ | |||
2770 2771 2772 2773 2774 2775 2776 |
* trace applies to scalar variable or array
* as-a-whole. */
int flags, /* OR-ed collection of bits describing current
* trace, including any of TCL_TRACE_READS,
* TCL_TRACE_WRITES, TCL_TRACE_UNSETS,
* TCL_GLOBAL_ONLY, and TCL_NAMESPACE_ONLY. */
Tcl_VarTraceProc *proc, /* Function associated with trace. */
| | | 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 |
* trace applies to scalar variable or array
* as-a-whole. */
int flags, /* OR-ed collection of bits describing current
* trace, including any of TCL_TRACE_READS,
* TCL_TRACE_WRITES, TCL_TRACE_UNSETS,
* TCL_GLOBAL_ONLY, and TCL_NAMESPACE_ONLY. */
Tcl_VarTraceProc *proc, /* Function associated with trace. */
void *clientData) /* Arbitrary argument to pass to proc. */
{
VarTrace *tracePtr;
VarTrace *prevPtr, *nextPtr;
Var *varPtr, *arrayPtr;
Interp *iPtr = (Interp *) interp;
ActiveVarTrace *activePtr;
int flagMask, allFlags = 0;
|
| ︙ | ︙ | |||
2973 2974 2975 2976 2977 2978 2979 |
* as-a-whole. */
int flags, /* OR-ed collection of bits, including any of
* TCL_TRACE_READS, TCL_TRACE_WRITES,
* TCL_TRACE_UNSETS, TCL_GLOBAL_ONLY, and
* TCL_NAMESPACE_ONLY. */
Tcl_VarTraceProc *proc, /* Function to call when specified ops are
* invoked upon varName. */
| | | 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 |
* as-a-whole. */
int flags, /* OR-ed collection of bits, including any of
* TCL_TRACE_READS, TCL_TRACE_WRITES,
* TCL_TRACE_UNSETS, TCL_GLOBAL_ONLY, and
* TCL_NAMESPACE_ONLY. */
Tcl_VarTraceProc *proc, /* Function to call when specified ops are
* invoked upon varName. */
void *clientData) /* Arbitrary argument to pass to proc. */
{
VarTrace *tracePtr;
int result;
tracePtr = (VarTrace *)Tcl_Alloc(sizeof(VarTrace));
tracePtr->traceProc = proc;
tracePtr->clientData = clientData;
|
| ︙ | ︙ | |||
3020 3021 3022 3023 3024 3025 3026 |
TraceVarEx(
Tcl_Interp *interp, /* Interpreter in which variable is to be
* traced. */
const char *part1, /* Name of scalar variable or array. */
const char *part2, /* Name of element within array; NULL means
* trace applies to scalar variable or array
* as-a-whole. */
| | | 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 |
TraceVarEx(
Tcl_Interp *interp, /* Interpreter in which variable is to be
* traced. */
const char *part1, /* Name of scalar variable or array. */
const char *part2, /* Name of element within array; NULL means
* trace applies to scalar variable or array
* as-a-whole. */
VarTrace *tracePtr) /* Structure containing flags, traceProc and
* clientData fields. Others should be left
* blank. Will be Tcl_Free()d (eventually) if
* this function returns TCL_OK, and up to
* caller to free if this function returns
* TCL_ERROR. */
{
Interp *iPtr = (Interp *) interp;
|
| ︙ | ︙ |
Changes to generic/tclUtf.c.
| ︙ | ︙ | |||
202 203 204 205 206 207 208 | * None. * *--------------------------------------------------------------------------- */ Tcl_Size Tcl_UniCharToUtf( | | | < | | | < | 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 |
* None.
*
*---------------------------------------------------------------------------
*/
Tcl_Size
Tcl_UniCharToUtf(
int ch, /* The Tcl_UniChar to be stored in the buffer.
* Can be or'ed with flag TCL_COMBINE. */
char *buf) /* Buffer in which the UTF-8 representation of
* ch is stored. Must be large enough to hold
* the UTF-8 character (at most 4 bytes). */
{
int flags = ch;
if (ch >= TCL_COMBINE) {
ch &= (TCL_COMBINE - 1);
}
if ((unsigned)(ch - 1) < (UNICODE_SELF - 1)) {
|
| ︙ | ︙ | |||
306 307 308 309 310 311 312 | * None. * *--------------------------------------------------------------------------- */ char * Tcl_UniCharToUtfDString( | | | | 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 |
* None.
*
*---------------------------------------------------------------------------
*/
char *
Tcl_UniCharToUtfDString(
const int *uniStr, /* Unicode string to convert to UTF-8. */
Tcl_Size uniLength, /* Length of Unicode string. Negative for nul
* terminated string */
Tcl_DString *dsPtr) /* UTF-8 representation of string is appended
* to this previously initialized DString. */
{
const int *w, *wEnd;
char *p, *string;
Tcl_Size oldLength;
|
| ︙ | ︙ | |||
437 438 439 440 441 442 443 |
0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x8D, 0x017D, 0x8F,
0x90, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x2DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x9D, 0x017E, 0x0178
};
Tcl_Size
Tcl_UtfToUniChar(
| | | | | 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 |
0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x8D, 0x017D, 0x8F,
0x90, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x2DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x9D, 0x017E, 0x0178
};
Tcl_Size
Tcl_UtfToUniChar(
const char *src, /* The UTF-8 string. */
int *chPtr) /* Filled with the Unicode character
* represented by the UTF-8 string. */
{
int byte;
/*
* Unroll 1 to 4 byte UTF-8 sequences.
*/
|
| ︙ | ︙ | |||
520 521 522 523 524 525 526 |
*chPtr = byte;
return 1;
}
Tcl_Size
Tcl_UtfToChar16(
| | | | > | 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 |
*chPtr = byte;
return 1;
}
Tcl_Size
Tcl_UtfToChar16(
const char *src, /* The UTF-8 string. */
unsigned short *chPtr) /* Filled with the Tcl_UniChar represented by
* the UTF-8 string. This could be a
* surrogate too. */
{
unsigned short byte;
/*
* Unroll 1 to 4 byte UTF-8 sequences.
*/
|
| ︙ | ︙ | |||
798 799 800 801 802 803 804 | * None. * *--------------------------------------------------------------------------- */ Tcl_Size Tcl_NumUtfChars( | | | | | 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 |
* None.
*
*---------------------------------------------------------------------------
*/
Tcl_Size
Tcl_NumUtfChars(
const char *src, /* The UTF-8 string to measure. */
Tcl_Size length) /* The length of the string in bytes, or
* negative value for strlen(src). */
{
Tcl_UniChar ch = 0;
Tcl_Size i = 0;
if (length < 0) {
/* string is NUL-terminated, so TclUtfToUniChar calls are safe. */
while (*src != '\0') {
|
| ︙ | ︙ | |||
850 851 852 853 854 855 856 |
}
}
return i;
}
Tcl_Size
TclNumUtfChars(
| | | | | 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 |
}
}
return i;
}
Tcl_Size
TclNumUtfChars(
const char *src, /* The UTF-8 string to measure. */
Tcl_Size length) /* The length of the string in bytes, or
* negative for strlen(src). */
{
unsigned short ch = 0;
Tcl_Size i = 0;
if (length < 0) {
/* string is NUL-terminated, so TclUtfToUniChar calls are safe. */
while (*src != '\0') {
|
| ︙ | ︙ | |||
1174 1175 1176 1177 1178 1179 1180 | * None. * *--------------------------------------------------------------------------- */ int Tcl_UniCharAtIndex( | | | | 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 |
* None.
*
*---------------------------------------------------------------------------
*/
int
Tcl_UniCharAtIndex(
const char *src, /* The UTF-8 string to dereference. */
Tcl_Size index) /* The position of the desired character. */
{
Tcl_UniChar ch = 0;
int i = 0;
if (index < 0) {
return -1;
}
|
| ︙ | ︙ | |||
1210 1211 1212 1213 1214 1215 1216 | * None. * *--------------------------------------------------------------------------- */ const char * Tcl_UtfAtIndex( | | | | | | 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 |
* None.
*
*---------------------------------------------------------------------------
*/
const char *
Tcl_UtfAtIndex(
const char *src, /* The UTF-8 string. */
Tcl_Size index) /* The position of the desired character. */
{
Tcl_UniChar ch = 0;
while (index-- > 0) {
src += Tcl_UtfToUniChar(src, &ch);
}
return src;
}
const char *
TclUtfAtIndex(
const char *src, /* The UTF-8 string. */
Tcl_Size index) /* The position of the desired character. */
{
unsigned short ch = 0;
Tcl_Size len = 0;
if (index > 0) {
while (index--) {
src += (len = Tcl_UtfToChar16(src, &ch));
|
| ︙ | ︙ | |||
1487 1488 1489 1490 1491 1492 1493 |
*----------------------------------------------------------------------
*/
int
TclpUtfNcmp2(
const void *csPtr, /* UTF string to compare to ct. */
const void *ctPtr, /* UTF string cs is compared to. */
| | | 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 |
*----------------------------------------------------------------------
*/
int
TclpUtfNcmp2(
const void *csPtr, /* UTF string to compare to ct. */
const void *ctPtr, /* UTF string cs is compared to. */
size_t numBytes) /* Number of *bytes* to compare. */
{
const char *cs = (const char *)csPtr;
const char *ct = (const char *)ctPtr;
/*
* We can't simply call 'memcmp(cs, ct, numBytes);' because we need to
* check for Tcl's \xC0\x80 non-utf-8 null encoding. Otherwise utf-8 lexes
* fine in the strcmp manner.
|
| ︙ | ︙ | |||
1536 1537 1538 1539 1540 1541 1542 |
*----------------------------------------------------------------------
*/
int
TclUtfNcmp(
const char *cs, /* UTF string to compare to ct. */
const char *ct, /* UTF string cs is compared to. */
| | | 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 |
*----------------------------------------------------------------------
*/
int
TclUtfNcmp(
const char *cs, /* UTF string to compare to ct. */
const char *ct, /* UTF string cs is compared to. */
size_t numChars) /* Number of UTF-16 chars to compare. */
{
unsigned short ch1 = 0, ch2 = 0;
/*
* Cannot use 'memcmp(cs, ct, n);' as byte representation of \u0000 (the
* pair of bytes 0xC0,0x80) is larger than byte representation of \u0001
* (the byte 0x01.)
|
| ︙ | ︙ | |||
1574 1575 1576 1577 1578 1579 1580 |
return 0;
}
int
Tcl_UtfNcmp(
const char *cs, /* UTF string to compare to ct. */
const char *ct, /* UTF string cs is compared to. */
| | | 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 |
return 0;
}
int
Tcl_UtfNcmp(
const char *cs, /* UTF string to compare to ct. */
const char *ct, /* UTF string cs is compared to. */
size_t numChars) /* Number of chars to compare. */
{
Tcl_UniChar ch1 = 0, ch2 = 0;
/*
* Cannot use 'memcmp(cs, ct, n);' as byte representation of \u0000 (the
* pair of bytes 0xC0,0x80) is larger than byte representation of \u0001
* (the byte 0x01.)
|
| ︙ | ︙ | |||
1622 1623 1624 1625 1626 1627 1628 |
*----------------------------------------------------------------------
*/
int
TclUtfNcasecmp(
const char *cs, /* UTF string to compare to ct. */
const char *ct, /* UTF string cs is compared to. */
| | | 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 |
*----------------------------------------------------------------------
*/
int
TclUtfNcasecmp(
const char *cs, /* UTF string to compare to ct. */
const char *ct, /* UTF string cs is compared to. */
size_t numChars) /* Number of UTF-16 chars to compare. */
{
unsigned short ch1 = 0, ch2 = 0;
while (numChars-- > 0) {
/*
* n must be interpreted as UTF-16 chars, not bytes.
* This should be called only when both strings are of
|
| ︙ | ︙ | |||
1657 1658 1659 1660 1661 1662 1663 |
return 0;
}
int
Tcl_UtfNcasecmp(
const char *cs, /* UTF string to compare to ct. */
const char *ct, /* UTF string cs is compared to. */
| | | 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 |
return 0;
}
int
Tcl_UtfNcasecmp(
const char *cs, /* UTF string to compare to ct. */
const char *ct, /* UTF string cs is compared to. */
size_t numChars) /* Number of chars to compare. */
{
Tcl_UniChar ch1 = 0, ch2 = 0;
while (numChars-- > 0) {
/*
* n must be interpreted as chars, not bytes.
* This should be called only when both strings are of
|
| ︙ | ︙ | |||
1878 1879 1880 1881 1882 1883 1884 | * None. * *---------------------------------------------------------------------- */ Tcl_Size Tcl_Char16Len( | | > | 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 |
* None.
*
*----------------------------------------------------------------------
*/
Tcl_Size
Tcl_Char16Len(
const unsigned short *uniStr)
/* Unicode string to find length of. */
{
Tcl_Size len = 0;
while (*uniStr != '\0') {
len++;
uniStr++;
}
|
| ︙ | ︙ | |||
1908 1909 1910 1911 1912 1913 1914 | * None. * *---------------------------------------------------------------------- */ Tcl_Size Tcl_UniCharLen( | | | 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 |
* None.
*
*----------------------------------------------------------------------
*/
Tcl_Size
Tcl_UniCharLen(
const int *uniStr) /* Unicode string to find length of. */
{
Tcl_Size len = 0;
while (*uniStr != '\0') {
len++;
uniStr++;
}
|
| ︙ | ︙ | |||
1940 1941 1942 1943 1944 1945 1946 |
*----------------------------------------------------------------------
*/
int
TclUniCharNcmp(
const Tcl_UniChar *ucs, /* Unicode string to compare to uct. */
const Tcl_UniChar *uct, /* Unicode string ucs is compared to. */
| | | 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 |
*----------------------------------------------------------------------
*/
int
TclUniCharNcmp(
const Tcl_UniChar *ucs, /* Unicode string to compare to uct. */
const Tcl_UniChar *uct, /* Unicode string ucs is compared to. */
size_t numChars) /* Number of chars to compare. */
{
#if defined(WORDS_BIGENDIAN)
/*
* We are definitely on a big-endian machine; memcmp() is safe
*/
return memcmp(ucs, uct, numChars*sizeof(Tcl_UniChar));
|
| ︙ | ︙ | |||
1985 1986 1987 1988 1989 1990 1991 |
*----------------------------------------------------------------------
*/
int
TclUniCharNcasecmp(
const Tcl_UniChar *ucs, /* Unicode string to compare to uct. */
const Tcl_UniChar *uct, /* Unicode string ucs is compared to. */
| | | 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 |
*----------------------------------------------------------------------
*/
int
TclUniCharNcasecmp(
const Tcl_UniChar *ucs, /* Unicode string to compare to uct. */
const Tcl_UniChar *uct, /* Unicode string ucs is compared to. */
size_t numChars) /* Number of chars to compare. */
{
for ( ; numChars != 0; numChars--, ucs++, uct++) {
if (*ucs != *uct) {
Tcl_UniChar lcs = Tcl_UniCharToLower(*ucs);
Tcl_UniChar lct = Tcl_UniCharToLower(*uct);
if (lcs != lct) {
|
| ︙ | ︙ |
Changes to generic/tclUtil.c.
| ︙ | ︙ | |||
154 155 156 157 158 159 160 | * The ASCII characters which can make up the whitespace between list elements * are: * * \u0009 \t TAB * \u000A \n NEWLINE * \u000B \v VERTICAL TAB * \u000C \f FORM FEED | | | 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | * The ASCII characters which can make up the whitespace between list elements * are: * * \u0009 \t TAB * \u000A \n NEWLINE * \u000B \v VERTICAL TAB * \u000C \f FORM FEED * \u000D \r CARRIAGE RETURN * \u0020 SPACE * * NOTE: differences between this and other places where Tcl defines a role * for "whitespace". * * * Unlike command parsing, here NEWLINE is just another whitespace * character; its role as a command terminator in a script has no |
| ︙ | ︙ | |||
272 273 274 275 276 277 278 | * characters that have special meaning during script evaluation need * special treatment when canonical lists are produced: * * * Whitespace between elements may not include NEWLINE. * * The command terminating character, * \u003b ; SEMICOLON * must be BRACEd, QUOTEd, or escaped so that it does not terminate the | | | 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 | * characters that have special meaning during script evaluation need * special treatment when canonical lists are produced: * * * Whitespace between elements may not include NEWLINE. * * The command terminating character, * \u003b ; SEMICOLON * must be BRACEd, QUOTEd, or escaped so that it does not terminate the * command prematurely. * * Any of the characters that begin substitutions in scripts, * \u0024 $ DOLLAR * \u005b [ OPEN BRACKET * \u005c \ BACKSLASH * need to be BRACEd or escaped. * * In any list where the first character of the first element is * \u0023 # HASH |
| ︙ | ︙ | |||
1032 1033 1034 1035 1036 1037 1038 |
int forbidNone = 0; /* Do not permit CONVERT_NONE mode. Something
* needs protection or escape. */
int requireEscape = 0; /* Force use of CONVERT_ESCAPE mode. For some
* reason bare or brace-quoted form fails. */
Tcl_Size extra = 0; /* Count of number of extra bytes needed for
* formatted element, assuming we use escape
* sequences in formatting. */
| | | 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 |
int forbidNone = 0; /* Do not permit CONVERT_NONE mode. Something
* needs protection or escape. */
int requireEscape = 0; /* Force use of CONVERT_ESCAPE mode. For some
* reason bare or brace-quoted form fails. */
Tcl_Size extra = 0; /* Count of number of extra bytes needed for
* formatted element, assuming we use escape
* sequences in formatting. */
Tcl_Size bytesNeeded; /* Buffer length computed to complete the
* element formatting in the selected mode. */
#if COMPAT
int preferEscape = 0; /* Use preferences to track whether to use */
int preferBrace = 0; /* CONVERT_MASK mode. */
int braceCount = 0; /* Count of all braces '{' '}' seen. */
#endif /* COMPAT */
|
| ︙ | ︙ | |||
1319 1320 1321 1322 1323 1324 1325 | * None. * *---------------------------------------------------------------------- */ Tcl_Size Tcl_ConvertElement( | | | | | 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 |
* None.
*
*----------------------------------------------------------------------
*/
Tcl_Size
Tcl_ConvertElement(
const char *src, /* Source information for list element. */
char *dst, /* Place to put list-ified element. */
int flags) /* Flags produced by Tcl_ScanElement. */
{
return Tcl_ConvertCountedElement(src, TCL_INDEX_NONE, dst, flags);
}
/*
*----------------------------------------------------------------------
*
|
| ︙ | ︙ | |||
1349 1350 1351 1352 1353 1354 1355 | * None. * *---------------------------------------------------------------------- */ Tcl_Size Tcl_ConvertCountedElement( | | | 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 |
* None.
*
*----------------------------------------------------------------------
*/
Tcl_Size
Tcl_ConvertCountedElement(
const char *src, /* Source information for list element. */
Tcl_Size length, /* Number of bytes in src, or TCL_INDEX_NONE. */
char *dst, /* Place to put list-ified element. */
int flags) /* Flags produced by Tcl_ScanElement. */
{
Tcl_Size numBytes = TclConvertElement(src, length, dst, flags);
dst[numBytes] = '\0';
return numBytes;
|
| ︙ | ︙ | |||
1382 1383 1384 1385 1386 1387 1388 | * None. * *---------------------------------------------------------------------- */ Tcl_Size TclConvertElement( | | | 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 |
* None.
*
*----------------------------------------------------------------------
*/
Tcl_Size
TclConvertElement(
const char *src, /* Source information for list element. */
Tcl_Size length, /* Number of bytes in src, or TCL_INDEX_NONE. */
char *dst, /* Place to put list-ified element. */
int flags) /* Flags produced by Tcl_ScanElement. */
{
int conversion = flags & CONVERT_MASK;
char *p = dst;
|
| ︙ | ︙ | |||
1563 1564 1565 1566 1567 1568 1569 | * None. * *---------------------------------------------------------------------- */ char * Tcl_Merge( | | | 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 |
* None.
*
*----------------------------------------------------------------------
*/
char *
Tcl_Merge(
Tcl_Size argc, /* How many strings to merge. */
const char *const *argv) /* Array of string values. */
{
#define LOCAL_SIZE 64
char localFlags[LOCAL_SIZE], *flagPtr = NULL;
Tcl_Size i;
size_t bytesNeeded = 0;
char *result, *dst;
|
| ︙ | ︙ | |||
1640 1641 1642 1643 1644 1645 1646 | * None. * *---------------------------------------------------------------------- */ Tcl_Size TclTrimRight( | | | | | | | | | | | 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 |
* None.
*
*----------------------------------------------------------------------
*/
Tcl_Size
TclTrimRight(
const char *bytes, /* String to be trimmed... */
Tcl_Size numBytes, /* ...and its length in bytes */
/* Calls to TclUtfToUniChar() in this routine
* rely on (bytes[numBytes] == '\0'). */
const char *trim, /* String of trim characters... */
Tcl_Size numTrim) /* ...and its length in bytes */
/* Calls to TclUtfToUniChar() in this routine
* rely on (trim[numTrim] == '\0'). */
{
const char *pp, *p = bytes + numBytes;
int ch1, ch2;
/* Empty strings -> nothing to do */
if ((numBytes == 0) || (numTrim == 0)) {
return 0;
}
/*
* Outer loop: iterate over string to be trimmed.
*/
do {
const char *q = trim;
Tcl_Size pInc = 0, bytesLeft = numTrim;
pp = Tcl_UtfPrev(p, bytes);
do {
pp += pInc;
pInc = Tcl_UtfToUniChar(pp, &ch1);
} while (pp + pInc < p);
/*
* Inner loop: scan trim string for match to current character.
*/
do {
|
| ︙ | ︙ | |||
1719 1720 1721 1722 1723 1724 1725 | * None. * *---------------------------------------------------------------------- */ Tcl_Size TclTrimLeft( | | | | | | | | | | 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 |
* None.
*
*----------------------------------------------------------------------
*/
Tcl_Size
TclTrimLeft(
const char *bytes, /* String to be trimmed... */
Tcl_Size numBytes, /* ...and its length in bytes */
/* Calls to TclUtfToUniChar() in this routine
* rely on (bytes[numBytes] == '\0'). */
const char *trim, /* String of trim characters... */
Tcl_Size numTrim) /* ...and its length in bytes */
/* Calls to TclUtfToUniChar() in this routine
* rely on (trim[numTrim] == '\0'). */
{
const char *p = bytes;
int ch1, ch2;
/* Empty strings -> nothing to do */
if ((numBytes == 0) || (numTrim == 0)) {
return 0;
|
| ︙ | ︙ | |||
1793 1794 1795 1796 1797 1798 1799 | * None. * *---------------------------------------------------------------------- */ Tcl_Size TclTrim( | | | | | | | | | | 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 |
* None.
*
*----------------------------------------------------------------------
*/
Tcl_Size
TclTrim(
const char *bytes, /* String to be trimmed... */
Tcl_Size numBytes, /* ...and its length in bytes */
/* Calls in this routine
* rely on (bytes[numBytes] == '\0'). */
const char *trim, /* String of trim characters... */
Tcl_Size numTrim, /* ...and its length in bytes */
/* Calls in this routine
* rely on (trim[numTrim] == '\0'). */
Tcl_Size *trimRightPtr) /* Offset from the end of the string. */
{
Tcl_Size trimLeft = 0, trimRight = 0;
/* Empty strings -> nothing to do */
if ((numBytes > 0) && (numTrim > 0)) {
|
| ︙ | ︙ | |||
1855 1856 1857 1858 1859 1860 1861 | */ /* The whitespace characters trimmed during [concat] operations */ #define CONCAT_WS_SIZE (sizeof(CONCAT_TRIM_SET "") - 1) char * Tcl_Concat( | | | 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 |
*/
/* The whitespace characters trimmed during [concat] operations */
#define CONCAT_WS_SIZE (sizeof(CONCAT_TRIM_SET "") - 1)
char *
Tcl_Concat(
Tcl_Size argc, /* Number of strings to concatenate. */
const char *const *argv) /* Array of strings to concatenate. */
{
Tcl_Size i, needSpace = 0, bytesNeeded = 0;
char *result, *p;
/*
* Dispose of the empty result corner case first to simplify later code.
|
| ︙ | ︙ | |||
1877 1878 1879 1880 1881 1882 1883 |
/*
* First allocate the result buffer at the size required.
*/
for (i = 0; i < argc; i++) {
bytesNeeded += strlen(argv[i]);
| | | 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 |
/*
* First allocate the result buffer at the size required.
*/
for (i = 0; i < argc; i++) {
bytesNeeded += strlen(argv[i]);
if (bytesNeeded < 0) {
Tcl_Panic("Tcl_Concat: max size of Tcl value exceeded");
}
}
/*
* All element bytes + (argc - 1) spaces + 1 terminating NULL.
*/
|
| ︙ | ︙ | |||
2333 2334 2335 2336 2337 2338 2339 |
*
*----------------------------------------------------------------------
*/
int
TclByteArrayMatch(
const unsigned char *string,/* String. */
| | | | 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 |
*
*----------------------------------------------------------------------
*/
int
TclByteArrayMatch(
const unsigned char *string,/* String. */
Tcl_Size strLen, /* Length of String */
const unsigned char *pattern,
/* Pattern, which may contain special
* characters. */
Tcl_Size ptnLen, /* Length of Pattern */
TCL_UNUSED(int) /*flags*/)
{
const unsigned char *stringEnd, *patternEnd;
unsigned char p;
stringEnd = string + strLen;
patternEnd = pattern + ptnLen;
|
| ︙ | ︙ | |||
2805 2806 2807 2808 2809 2810 2811 |
*
*----------------------------------------------------------------------
*/
void
Tcl_DStringSetLength(
Tcl_DString *dsPtr, /* Structure describing dynamic string. */
| | | 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 |
*
*----------------------------------------------------------------------
*/
void
Tcl_DStringSetLength(
Tcl_DString *dsPtr, /* Structure describing dynamic string. */
Tcl_Size length) /* New length for dynamic string. */
{
Tcl_Size newsize;
if (length < 0) {
length = 0;
}
if (length >= dsPtr->spaceAvl) {
|
| ︙ | ︙ | |||
3294 3295 3296 3297 3298 3299 3300 |
*----------------------------------------------------------------------
*/
Tcl_Size
TclFormatInt(
char *buffer, /* Points to the storage into which the
* formatted characters are written. */
| | | 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 |
*----------------------------------------------------------------------
*/
Tcl_Size
TclFormatInt(
char *buffer, /* Points to the storage into which the
* formatted characters are written. */
Tcl_WideInt n) /* The integer to format. */
{
Tcl_WideUInt intVal;
int i = 0, numFormatted, j;
static const char digits[] = "0123456789";
/*
* Generate the characters of the result backwards in the buffer.
|
| ︙ | ︙ | |||
3409 3410 3411 3412 3413 3414 3415 | * TCL_SIZE_MAX. Negative values are returned as TCL_INDEX_NONE (-1). * * Callers should pass reasonable values for endValue - one in the * valid index range or TCL_INDEX_NONE (-1), for example for an empty * list. * * Results: | | | | | | | | | 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 |
* TCL_SIZE_MAX. Negative values are returned as TCL_INDEX_NONE (-1).
*
* Callers should pass reasonable values for endValue - one in the
* valid index range or TCL_INDEX_NONE (-1), for example for an empty
* list.
*
* Results:
* TCL_OK
*
* The index is stored at the address given by by 'indexPtr'.
*
* TCL_ERROR
*
* The value of 'objPtr' does not have one of the expected formats. If
* 'interp' is non-NULL, an error message is left in the interpreter's
* result object.
*
* Side effects:
*
* The internal representation contained within objPtr may shimmer.
*
*----------------------------------------------------------------------
*/
int
Tcl_GetIntForIndex(
Tcl_Interp *interp, /* Interpreter to use for error reporting. If
|
| ︙ | ︙ | |||
3795 3796 3797 3798 3799 3800 3801 | * to *indexPtr. * *---------------------------------------------------------------------- */ int TclIndexEncode( | | | | | | | 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 |
* to *indexPtr.
*
*----------------------------------------------------------------------
*/
int
TclIndexEncode(
Tcl_Interp *interp, /* For error reporting, may be NULL */
Tcl_Obj *objPtr, /* Index value to parse */
int before, /* Value to return for index before beginning */
int after, /* Value to return for index after end */
int *indexPtr) /* Where to write the encoded answer, not NULL */
{
Tcl_WideInt wide;
int idx;
const Tcl_WideInt ENDVALUE = 2 * (Tcl_WideInt) INT_MAX;
assert(ENDVALUE < WIDE_MAX);
if (TCL_OK != GetWideForIndex(interp, objPtr, ENDVALUE, &wide)) {
|
| ︙ | ︙ | |||
3943 3944 3945 3946 3947 3948 3949 | * The decoded index value. * *---------------------------------------------------------------------- */ Tcl_Size TclIndexDecode( | | | | 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 |
* The decoded index value.
*
*----------------------------------------------------------------------
*/
Tcl_Size
TclIndexDecode(
int encoded, /* Value to decode */
Tcl_Size endValue) /* Meaning of "end" to use, > TCL_INDEX_END */
{
if (encoded > TCL_INDEX_END) {
return encoded;
}
endValue += encoded - TCL_INDEX_END;
if (endValue >= 0) {
return endValue;
|
| ︙ | ︙ | |||
3973 3974 3975 3976 3977 3978 3979 | * Side effects: * If interp is not-NULL, an error message is stored in it. * *------------------------------------------------------------------------ */ int TclCommandWordLimitError ( | | | | < | | < < | < | | | | | | 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 |
* Side effects:
* If interp is not-NULL, an error message is stored in it.
*
*------------------------------------------------------------------------
*/
int
TclCommandWordLimitError (
Tcl_Interp *interp, /* May be NULL */
Tcl_Size count) /* If <= 0, "unknown" */
{
if (interp) {
if (count > 0) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"Number of words (%" TCL_SIZE_MODIFIER
"d) in command exceeds limit %" TCL_SIZE_MODIFIER "d.",
count, (Tcl_Size)INT_MAX));
} else {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"Number of words in command exceeds "
"limit %" TCL_SIZE_MODIFIER "d.",
(Tcl_Size)INT_MAX));
}
}
return TCL_ERROR; /* Always */
}
/*
*----------------------------------------------------------------------
|
| ︙ | ︙ |
Changes to generic/tclVar.c.
| ︙ | ︙ | |||
527 528 529 530 531 532 533 |
*
*----------------------------------------------------------------------
*/
Var *
TclObjLookupVar(
Tcl_Interp *interp, /* Interpreter to use for lookup. */
| | | | | 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 |
*
*----------------------------------------------------------------------
*/
Var *
TclObjLookupVar(
Tcl_Interp *interp, /* Interpreter to use for lookup. */
Tcl_Obj *part1Ptr, /* If part2 isn't NULL, this is the name of an
* array. Otherwise, this is a full variable
* name that could include a parenthesized
* array element. */
const char *part2, /* Name of element within array, or NULL. */
int flags, /* Only TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY,
* and TCL_LEAVE_ERR_MSG bits matter. */
const char *msg, /* Verb to use in error messages, e.g. "read"
* or "set". Only needed if TCL_LEAVE_ERR_MSG
* is set in flags. */
int createPart1, /* If 1, create hash table entry for part 1 of
* name, if it doesn't already exist. If 0,
* return error if it doesn't exist. */
int createPart2, /* If 1, create hash table entry for part 2 of
* name, if it doesn't already exist. If 0,
* return error if it doesn't exist. */
Var **arrayPtrPtr) /* If the name refers to an element of an
* array, *arrayPtrPtr gets filled in with
* address of array variable. Otherwise this
* is set to NULL. */
{
|
| ︙ | ︙ | |||
587 588 589 590 591 592 593 |
* parenthesized array element. */
Tcl_Obj *part2Ptr, /* Name of element within array, or NULL. */
int flags, /* Only TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY,
* and TCL_LEAVE_ERR_MSG bits matter. */
const char *msg, /* Verb to use in error messages, e.g. "read"
* or "set". Only needed if TCL_LEAVE_ERR_MSG
* is set in flags. */
| | | | 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 |
* parenthesized array element. */
Tcl_Obj *part2Ptr, /* Name of element within array, or NULL. */
int flags, /* Only TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY,
* and TCL_LEAVE_ERR_MSG bits matter. */
const char *msg, /* Verb to use in error messages, e.g. "read"
* or "set". Only needed if TCL_LEAVE_ERR_MSG
* is set in flags. */
int createPart1, /* If 1, create hash table entry for part 1 of
* name, if it doesn't already exist. If 0,
* return error if it doesn't exist. */
int createPart2, /* If 1, create hash table entry for part 2 of
* name, if it doesn't already exist. If 0,
* return error if it doesn't exist. */
Var **arrayPtrPtr) /* If the name refers to an element of an
* array, *arrayPtrPtr gets filled in with
* address of array variable. Otherwise this
* is set to NULL. */
{
|
| ︙ | ︙ | |||
823 824 825 826 827 828 829 |
TclLookupSimpleVar(
Tcl_Interp *interp, /* Interpreter to use for lookup. */
Tcl_Obj *varNamePtr, /* This is a simple variable name that could
* represent a scalar or an array. */
int flags, /* Only TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY,
* TCL_AVOID_RESOLVERS and TCL_LEAVE_ERR_MSG
* bits matter. */
| | | 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 |
TclLookupSimpleVar(
Tcl_Interp *interp, /* Interpreter to use for lookup. */
Tcl_Obj *varNamePtr, /* This is a simple variable name that could
* represent a scalar or an array. */
int flags, /* Only TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY,
* TCL_AVOID_RESOLVERS and TCL_LEAVE_ERR_MSG
* bits matter. */
int create, /* If 1, create hash table entry for varname,
* if it doesn't already exist. If 0, return
* error if it doesn't exist. */
const char **errMsgPtr,
int *indexPtr)
{
Interp *iPtr = (Interp *) interp;
CallFrame *varFramePtr = iPtr->varFramePtr;
|
| ︙ | ︙ | |||
1056 1057 1058 1059 1060 1061 1062 |
Var *
TclLookupArrayElement(
Tcl_Interp *interp, /* Interpreter to use for lookup. */
Tcl_Obj *arrayNamePtr, /* This is the name of the array, or NULL if
* index>= 0. */
Tcl_Obj *elNamePtr, /* Name of element within array. */
| | | | | 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 |
Var *
TclLookupArrayElement(
Tcl_Interp *interp, /* Interpreter to use for lookup. */
Tcl_Obj *arrayNamePtr, /* This is the name of the array, or NULL if
* index>= 0. */
Tcl_Obj *elNamePtr, /* Name of element within array. */
int flags, /* Only TCL_LEAVE_ERR_MSG bit matters. */
const char *msg, /* Verb to use in error messages, e.g. "read"
* or "set". Only needed if TCL_LEAVE_ERR_MSG
* is set in flags. */
int createArray, /* If 1, transform arrayName to be an array if
* it isn't one yet and the transformation is
* possible. If 0, return error if it isn't
* already an array. */
int createElem, /* If 1, create hash table entry for the
* element, if it doesn't already exist. If 0,
* return error if it doesn't exist. */
Var *arrayPtr, /* Pointer to the array's Var structure. */
int index) /* If >=0, the index of the local array. */
{
int isNew;
Var *varPtr;
|
| ︙ | ︙ | |||
1273 1274 1275 1276 1277 1278 1279 |
*----------------------------------------------------------------------
*/
Tcl_Obj *
Tcl_ObjGetVar2(
Tcl_Interp *interp, /* Command interpreter in which variable is to
* be looked up. */
| | | | 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 |
*----------------------------------------------------------------------
*/
Tcl_Obj *
Tcl_ObjGetVar2(
Tcl_Interp *interp, /* Command interpreter in which variable is to
* be looked up. */
Tcl_Obj *part1Ptr, /* Points to an object holding the name of an
* array (if part2 is non-NULL) or the name of
* a variable. */
Tcl_Obj *part2Ptr, /* If non-null, points to an object holding
* the name of an element in the array
* part1Ptr. */
int flags) /* OR-ed combination of TCL_GLOBAL_ONLY and
* TCL_LEAVE_ERR_MSG bits. */
{
Var *varPtr, *arrayPtr;
|
| ︙ | ︙ | |||
1332 1333 1334 1335 1336 1337 1338 |
Tcl_Var varPtr, /* The variable to be read.*/
Tcl_Var arrayPtr, /* NULL for scalar variables, pointer to the
* containing array otherwise. */
Tcl_Obj *part1Ptr, /* Name of an array (if part2 is non-NULL) or
* the name of a variable. */
Tcl_Obj *part2Ptr, /* If non-NULL, gives the name of an element
* in the array part1. */
| | | 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 |
Tcl_Var varPtr, /* The variable to be read.*/
Tcl_Var arrayPtr, /* NULL for scalar variables, pointer to the
* containing array otherwise. */
Tcl_Obj *part1Ptr, /* Name of an array (if part2 is non-NULL) or
* the name of a variable. */
Tcl_Obj *part2Ptr, /* If non-NULL, gives the name of an element
* in the array part1. */
int flags) /* OR-ed combination of TCL_GLOBAL_ONLY, and
* TCL_LEAVE_ERR_MSG bits. */
{
if (varPtr == NULL) {
Tcl_Panic("varPtr must not be NULL");
}
if (part1Ptr == NULL) {
Tcl_Panic("part1Ptr must not be NULL");
|
| ︙ | ︙ | |||
1371 1372 1373 1374 1375 1376 1377 |
*----------------------------------------------------------------------
*/
Tcl_Obj *
TclPtrGetVarIdx(
Tcl_Interp *interp, /* Command interpreter in which variable is to
* be looked up. */
| | | | 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 |
*----------------------------------------------------------------------
*/
Tcl_Obj *
TclPtrGetVarIdx(
Tcl_Interp *interp, /* Command interpreter in which variable is to
* be looked up. */
Var *varPtr, /* The variable to be read.*/
Var *arrayPtr, /* NULL for scalar variables, pointer to the
* containing array otherwise. */
Tcl_Obj *part1Ptr, /* Name of an array (if part2 is non-NULL) or
* the name of a variable. */
Tcl_Obj *part2Ptr, /* If non-NULL, gives the name of an element
* in the array part1. */
int flags, /* OR-ed combination of TCL_GLOBAL_ONLY, and
* TCL_LEAVE_ERR_MSG bits. */
int index) /* Index into the local variable table of the
* variable, or -1. Only used when part1Ptr is
* NULL. */
{
Interp *iPtr = (Interp *) interp;
const char *msg;
|
| ︙ | ︙ | |||
1479 1480 1481 1482 1483 1484 1485 |
*
*----------------------------------------------------------------------
*/
int
Tcl_SetObjCmd(
TCL_UNUSED(void *),
| | | 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 |
*
*----------------------------------------------------------------------
*/
int
Tcl_SetObjCmd(
TCL_UNUSED(void *),
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
Tcl_Obj *varValueObj;
if (objc == 2) {
varValueObj = Tcl_ObjGetVar2(interp, objv[1], NULL,TCL_LEAVE_ERR_MSG);
|
| ︙ | ︙ | |||
1656 1657 1658 1659 1660 1661 1662 |
*----------------------------------------------------------------------
*/
Tcl_Obj *
Tcl_ObjSetVar2(
Tcl_Interp *interp, /* Command interpreter in which variable is to
* be found. */
| | | | 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 |
*----------------------------------------------------------------------
*/
Tcl_Obj *
Tcl_ObjSetVar2(
Tcl_Interp *interp, /* Command interpreter in which variable is to
* be found. */
Tcl_Obj *part1Ptr, /* Points to an object holding the name of an
* array (if part2 is non-NULL) or the name of
* a variable. */
Tcl_Obj *part2Ptr, /* If non-NULL, points to an object holding
* the name of an element in the array
* part1Ptr. */
Tcl_Obj *newValuePtr, /* New value for variable. */
int flags) /* Various flags that tell how to set value:
* any of TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY,
* TCL_APPEND_VALUE, TCL_LIST_ELEMENT, or
* TCL_LEAVE_ERR_MSG. */
|
| ︙ | ︙ | |||
1727 1728 1729 1730 1731 1732 1733 |
* variable, or NULL if the variable is a
* scalar. */
Tcl_Obj *part1Ptr, /* Name of an array (if part2 is non-NULL) or
* the name of a variable. */
Tcl_Obj *part2Ptr, /* If non-NULL, gives the name of an element
* in the array part1. */
Tcl_Obj *newValuePtr, /* New value for variable. */
| | | 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 |
* variable, or NULL if the variable is a
* scalar. */
Tcl_Obj *part1Ptr, /* Name of an array (if part2 is non-NULL) or
* the name of a variable. */
Tcl_Obj *part2Ptr, /* If non-NULL, gives the name of an element
* in the array part1. */
Tcl_Obj *newValuePtr, /* New value for variable. */
int flags) /* OR-ed combination of TCL_GLOBAL_ONLY, and
* TCL_LEAVE_ERR_MSG bits. */
{
if (varPtr == NULL) {
Tcl_Panic("varPtr must not be NULL");
}
if (part1Ptr == NULL) {
Tcl_Panic("part1Ptr must not be NULL");
|
| ︙ | ︙ | |||
1896 1897 1898 1899 1900 1901 1902 |
*----------------------------------------------------------------------
*/
Tcl_Obj *
TclPtrSetVarIdx(
Tcl_Interp *interp, /* Command interpreter in which variable is to
* be looked up. */
| | | | 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 |
*----------------------------------------------------------------------
*/
Tcl_Obj *
TclPtrSetVarIdx(
Tcl_Interp *interp, /* Command interpreter in which variable is to
* be looked up. */
Var *varPtr, /* Reference to the variable to set. */
Var *arrayPtr, /* Reference to the array containing the
* variable, or NULL if the variable is a
* scalar. */
Tcl_Obj *part1Ptr, /* Name of an array (if part2 is non-NULL) or
* the name of a variable. NULL if the 'index'
* parameter is >= 0 */
Tcl_Obj *part2Ptr, /* If non-NULL, gives the name of an element
* in the array part1. */
Tcl_Obj *newValuePtr, /* New value for variable. */
int flags, /* OR-ed combination of TCL_GLOBAL_ONLY, and
* TCL_LEAVE_ERR_MSG bits. */
int index) /* Index of local var where part1 is to be
* found. */
{
Interp *iPtr = (Interp *) interp;
Tcl_Obj *oldValuePtr;
Tcl_Obj *resultPtr = NULL;
|
| ︙ | ︙ | |||
2165 2166 2167 2168 2169 2170 2171 |
* array (if part2 is non-NULL) or the name of
* a variable. */
Tcl_Obj *part2Ptr, /* If non-null, points to an object holding
* the name of an element in the array
* part1Ptr. */
Tcl_Obj *incrPtr, /* Increment value. */
/* TODO: Which of these flag values really make sense? */
| | | 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 |
* array (if part2 is non-NULL) or the name of
* a variable. */
Tcl_Obj *part2Ptr, /* If non-null, points to an object holding
* the name of an element in the array
* part1Ptr. */
Tcl_Obj *incrPtr, /* Increment value. */
/* TODO: Which of these flag values really make sense? */
int flags) /* Various flags that tell how to incr value:
* any of TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY,
* TCL_APPEND_VALUE, TCL_LIST_ELEMENT,
* TCL_LEAVE_ERR_MSG. */
{
if (varPtr == NULL) {
Tcl_Panic("varPtr must not be NULL");
}
|
| ︙ | ︙ | |||
2221 2222 2223 2224 2225 2226 2227 |
* array (if part2 is non-NULL) or the name of
* a variable. */
Tcl_Obj *part2Ptr, /* If non-null, points to an object holding
* the name of an element in the array
* part1Ptr. */
Tcl_Obj *incrPtr, /* Increment value. */
/* TODO: Which of these flag values really make sense? */
| | | 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 |
* array (if part2 is non-NULL) or the name of
* a variable. */
Tcl_Obj *part2Ptr, /* If non-null, points to an object holding
* the name of an element in the array
* part1Ptr. */
Tcl_Obj *incrPtr, /* Increment value. */
/* TODO: Which of these flag values really make sense? */
int flags, /* Various flags that tell how to incr value:
* any of TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY,
* TCL_APPEND_VALUE, TCL_LIST_ELEMENT,
* TCL_LEAVE_ERR_MSG. */
int index) /* Index into the local variable table of the
* variable, or -1. Only used when part1Ptr is
* NULL. */
{
|
| ︙ | ︙ | |||
2410 2411 2412 2413 2414 2415 2416 |
Tcl_Var varPtr, /* The variable to be unset. */
Tcl_Var arrayPtr, /* NULL for scalar variables, pointer to the
* containing array otherwise. */
Tcl_Obj *part1Ptr, /* Name of an array (if part2 is non-NULL) or
* the name of a variable. */
Tcl_Obj *part2Ptr, /* If non-NULL, gives the name of an element
* in the array part1. */
| | | 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 |
Tcl_Var varPtr, /* The variable to be unset. */
Tcl_Var arrayPtr, /* NULL for scalar variables, pointer to the
* containing array otherwise. */
Tcl_Obj *part1Ptr, /* Name of an array (if part2 is non-NULL) or
* the name of a variable. */
Tcl_Obj *part2Ptr, /* If non-NULL, gives the name of an element
* in the array part1. */
int flags) /* OR-ed combination of any of
* TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY,
* TCL_LEAVE_ERR_MSG. */
{
if (varPtr == NULL) {
Tcl_Panic("varPtr must not be NULL");
}
if (part1Ptr == NULL) {
|
| ︙ | ︙ | |||
4476 4477 4478 4479 4480 4481 4482 |
ObjMakeUpvar(
Tcl_Interp *interp, /* Interpreter containing variables. Used for
* error messages, too. */
CallFrame *framePtr, /* Call frame containing "other" variable.
* NULL means use global :: context. */
Tcl_Obj *otherP1Ptr,
const char *otherP2, /* Two-part name of variable in framePtr. */
| | | 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 |
ObjMakeUpvar(
Tcl_Interp *interp, /* Interpreter containing variables. Used for
* error messages, too. */
CallFrame *framePtr, /* Call frame containing "other" variable.
* NULL means use global :: context. */
Tcl_Obj *otherP1Ptr,
const char *otherP2, /* Two-part name of variable in framePtr. */
int otherFlags, /* 0, TCL_GLOBAL_ONLY or TCL_NAMESPACE_ONLY:
* indicates scope of "other" variable. */
Tcl_Obj *myNamePtr, /* Name of variable which will refer to
* otherP1/otherP2. Must be a scalar. */
int myFlags, /* 0, TCL_GLOBAL_ONLY or TCL_NAMESPACE_ONLY:
* indicates scope of myName. */
int index) /* If the variable to be linked is an indexed
* scalar, this is its index. Otherwise, -1 */
|
| ︙ | ︙ | |||
5333 5334 5335 5336 5337 5338 5339 |
*
*----------------------------------------------------------------------
*/
static void
DeleteSearches(
Interp *iPtr,
| | | 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 |
*
*----------------------------------------------------------------------
*/
static void
DeleteSearches(
Interp *iPtr,
Var *arrayVarPtr) /* Variable whose searches are to be
* deleted. */
{
ArraySearch *searchPtr, *nextPtr;
Tcl_HashEntry *sPtr;
if (arrayVarPtr->flags & VAR_SEARCH_ACTIVE) {
sPtr = Tcl_FindHashEntry(&iPtr->varSearches, arrayVarPtr);
|
| ︙ | ︙ | |||
6568 6569 6570 6571 6572 6573 6574 |
* Skip nameless (temporary) variables and undefined variables.
*/
if (*varNamePtr && !TclIsVarUndefined(varPtr)
&& (includeLinks || !TclIsVarLink(varPtr))) {
varName = TclGetString(*varNamePtr);
if ((pattern == NULL) || Tcl_StringMatch(varName, pattern)) {
| | | 6568 6569 6570 6571 6572 6573 6574 6575 6576 6577 6578 6579 6580 6581 6582 |
* Skip nameless (temporary) variables and undefined variables.
*/
if (*varNamePtr && !TclIsVarUndefined(varPtr)
&& (includeLinks || !TclIsVarLink(varPtr))) {
varName = TclGetString(*varNamePtr);
if ((pattern == NULL) || Tcl_StringMatch(varName, pattern)) {
if (!justConstants || TclIsVarConstant(varPtr)) {
Tcl_ListObjAppendElement(interp, listPtr, *varNamePtr);
}
if (includeLinks) {
Tcl_CreateHashEntry(&addedTable, *varNamePtr, &added);
}
}
}
|
| ︙ | ︙ | |||
6622 6623 6624 6625 6626 6627 6628 |
varPtr != NULL;
varPtr = VarHashNextVar(&search)) {
if (!TclIsVarUndefined(varPtr)
&& (includeLinks || !TclIsVarLink(varPtr))) {
objNamePtr = VarHashGetKey(varPtr);
varName = TclGetString(objNamePtr);
if ((pattern == NULL) || Tcl_StringMatch(varName, pattern)) {
| | | 6622 6623 6624 6625 6626 6627 6628 6629 6630 6631 6632 6633 6634 6635 6636 |
varPtr != NULL;
varPtr = VarHashNextVar(&search)) {
if (!TclIsVarUndefined(varPtr)
&& (includeLinks || !TclIsVarLink(varPtr))) {
objNamePtr = VarHashGetKey(varPtr);
varName = TclGetString(objNamePtr);
if ((pattern == NULL) || Tcl_StringMatch(varName, pattern)) {
if (!justConstants || TclIsVarConstant(varPtr)) {
Tcl_ListObjAppendElement(interp, listPtr, objNamePtr);
}
if (includeLinks) {
Tcl_CreateHashEntry(&addedTable, objNamePtr, &added);
}
}
}
|
| ︙ | ︙ | |||
6802 6803 6804 6805 6806 6807 6808 |
VarHashRefCount(varPtr)--;
}
Tcl_DecrRefCount(objPtr);
}
static int
CompareVarKeys(
| | | 6802 6803 6804 6805 6806 6807 6808 6809 6810 6811 6812 6813 6814 6815 6816 |
VarHashRefCount(varPtr)--;
}
Tcl_DecrRefCount(objPtr);
}
static int
CompareVarKeys(
void *keyPtr, /* New key to compare. */
Tcl_HashEntry *hPtr) /* Existing key to compare. */
{
Tcl_Obj *objPtr1 = (Tcl_Obj *)keyPtr;
Tcl_Obj *objPtr2 = hPtr->key.objPtr;
const char *p1, *p2;
size_t l1, l2;
|
| ︙ | ︙ | |||
6998 6999 7000 7001 7002 7003 7004 |
* Initialize array variable.
*/
void
TclInitArrayVar(
Var *arrayPtr)
{
| | > | 6998 6999 7000 7001 7002 7003 7004 7005 7006 7007 7008 7009 7010 7011 7012 7013 |
* Initialize array variable.
*/
void
TclInitArrayVar(
Var *arrayPtr)
{
ArrayVarHashTable *tablePtr = (ArrayVarHashTable *)
Tcl_Alloc(sizeof(ArrayVarHashTable));
/*
* Mark the variable as an array.
*/
TclSetVarArray(arrayPtr);
|
| ︙ | ︙ |
Changes to generic/tclZipfs.c.
| ︙ | ︙ | |||
213 214 215 216 217 218 219 |
*/
typedef struct ZipEntry {
char *name; /* The full pathname of the virtual file */
ZipFile *zipFilePtr; /* The ZIP file holding this virtual file */
size_t offset; /* Data offset into memory mapped ZIP file */
int numBytes; /* Uncompressed size of the virtual file.
| | | | 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 |
*/
typedef struct ZipEntry {
char *name; /* The full pathname of the virtual file */
ZipFile *zipFilePtr; /* The ZIP file holding this virtual file */
size_t offset; /* Data offset into memory mapped ZIP file */
int numBytes; /* Uncompressed size of the virtual file.
* -1 for zip64 */
int numCompressedBytes; /* Compressed size of the virtual file.
* -1 for zip64 */
int compressMethod; /* Compress method */
int isDirectory; /* 0 if file, 1 if directory, -1 if root */
int depth; /* Number of slashes in path. */
int crc32; /* CRC-32 as stored in ZIP */
int timestamp; /* Modification time */
int isEncrypted; /* True if data is encrypted */
int flags;
|
| ︙ | ︙ | |||
254 255 256 257 258 259 260 |
ZipFile *zipFilePtr; /* The ZIP file holding this channel */
ZipEntry *zipEntryPtr; /* Pointer back to virtual file */
Tcl_Size maxWrite; /* Maximum size for write */
Tcl_Size numBytes; /* Number of bytes of uncompressed data */
Tcl_Size cursor; /* Seek position for next read or write*/
unsigned char *ubuf; /* Pointer to the uncompressed data */
unsigned char *ubufToFree; /* NULL if ubuf points to memory that does not
| | | | 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 |
ZipFile *zipFilePtr; /* The ZIP file holding this channel */
ZipEntry *zipEntryPtr; /* Pointer back to virtual file */
Tcl_Size maxWrite; /* Maximum size for write */
Tcl_Size numBytes; /* Number of bytes of uncompressed data */
Tcl_Size cursor; /* Seek position for next read or write*/
unsigned char *ubuf; /* Pointer to the uncompressed data */
unsigned char *ubufToFree; /* NULL if ubuf points to memory that does not
* need freeing. Else memory to free (ubuf
* may point *inside* the block) */
Tcl_Size ubufSize; /* Size of allocated ubufToFree */
int iscompr; /* True if data is compressed */
int isDirectory; /* Set to 1 if directory, or -1 if root */
int isEncrypted; /* True if data is encrypted */
int mode; /* O_WRITE, O_APPEND, O_TRUNC etc.*/
unsigned long keys[3]; /* Key for decryption */
} ZipChannel;
|
| ︙ | ︙ | |||
968 969 970 971 972 973 974 | * Results: * TCL_OK on success with normalized mount path in dsPtr * TCL_ERROR on fail with error message in interp if not NULL * *------------------------------------------------------------------------ */ static int | | > | | | 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 |
* Results:
* TCL_OK on success with normalized mount path in dsPtr
* TCL_ERROR on fail with error message in interp if not NULL
*
*------------------------------------------------------------------------
*/
static int
NormalizeMountPoint(
Tcl_Interp *interp,
const char *mountPath,
Tcl_DString *dsPtr) /* Must be initialized by caller! */
{
const char *joiner[2];
char *joinedPath;
Tcl_Obj *unnormalizedObj;
Tcl_Obj *normalizedObj;
const char *normalizedPath;
Tcl_Size normalizedLen;
|
| ︙ | ︙ | |||
1025 1026 1027 1028 1029 1030 1031 |
Tcl_DStringFree(&dsJoin);
Tcl_DStringAppend(dsPtr, normalizedPath, normalizedLen);
Tcl_DecrRefCount(normalizedObj);
return TCL_OK;
invalidMountPath:
if (interp) {
| | | | 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 |
Tcl_DStringFree(&dsJoin);
Tcl_DStringAppend(dsPtr, normalizedPath, normalizedLen);
Tcl_DecrRefCount(normalizedObj);
return TCL_OK;
invalidMountPath:
if (interp) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"Invalid mount path \"%s\"", mountPath));
ZIPFS_ERROR_CODE(interp, "MOUNT_PATH");
}
errorReturn:
Tcl_DStringFree(&dsJoin);
return TCL_ERROR;
}
|
| ︙ | ︙ | |||
1055 1056 1057 1058 1059 1060 1061 | * * Side effects: * Stores mapped path in dsPtr. * *------------------------------------------------------------------------ */ static char * | | > | | | | | 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 |
*
* Side effects:
* Stores mapped path in dsPtr.
*
*------------------------------------------------------------------------
*/
static char *
MapPathToZipfs(
Tcl_Interp *interp,
const char *mountPath, /* Must be fully normalized */
const char *path, /* Archive content path to map */
Tcl_DString *dsPtr) /* Must be initialized and cleared
* by caller. */
{
const char *joiner[2];
char *joinedPath;
Tcl_Obj *unnormalizedObj;
Tcl_Obj *normalizedObj;
const char *normalizedPath;
Tcl_Size normalizedLen;
|
| ︙ | ︙ | |||
1195 1196 1197 1198 1199 1200 1201 | * * Side effects: * None. * *------------------------------------------------------------------------ */ static int | | > > | 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 |
*
* Side effects:
* None.
*
*------------------------------------------------------------------------
*/
static int
ContainsMountPoint(
const char *path,
int pathLen)
{
Tcl_HashEntry *hPtr;
Tcl_HashSearch search;
if (ZipFS.zipHash.numEntries == 0) {
return 0;
}
|
| ︙ | ︙ | |||
2214 2215 2216 2217 2218 2219 2220 | * None. * * Side effects: * Memory associated with the mounted archive is deallocated. *------------------------------------------------------------------------ */ static void | | > | 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 |
* None.
*
* Side effects:
* Memory associated with the mounted archive is deallocated.
*------------------------------------------------------------------------
*/
static void
CleanupMount(
ZipFile *zf) /* Mount point */
{
ZipEntry *z, *znext;
Tcl_HashEntry *hPtr;
for (z = zf->entries; z; z = znext) {
znext = z->next;
hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, z->name);
if (hPtr) {
|
| ︙ | ︙ | |||
3268 3269 3270 3271 3272 3273 3274 |
static inline const char *
ComputeNameInArchive(
Tcl_Obj *pathObj, /* The path to the origin file */
Tcl_Obj *directNameObj, /* User-specified name for use in the ZIP
* archive */
const char *strip, /* A prefix to strip; may be NULL if no
* stripping need be done. */
| | | 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 |
static inline const char *
ComputeNameInArchive(
Tcl_Obj *pathObj, /* The path to the origin file */
Tcl_Obj *directNameObj, /* User-specified name for use in the ZIP
* archive */
const char *strip, /* A prefix to strip; may be NULL if no
* stripping need be done. */
Tcl_Size slen) /* The length of the prefix; must be 0 if no
* stripping need be done. */
{
const char *name;
Tcl_Size len;
if (directNameObj) {
name = TclGetString(directNameObj);
|
| ︙ | ︙ | |||
4742 4743 4744 4745 4746 4747 4748 |
int wr = (mode & (O_WRONLY | O_RDWR)) != 0;
/* Check for unsupported modes. */
if ((ZipFS.wrmax <= 0) && wr) {
Tcl_SetErrno(EACCES);
if (interp) {
| | | | | | | < | | | < | | | 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 |
int wr = (mode & (O_WRONLY | O_RDWR)) != 0;
/* Check for unsupported modes. */
if ((ZipFS.wrmax <= 0) && wr) {
Tcl_SetErrno(EACCES);
if (interp) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"writes not permitted: %s",
Tcl_PosixError(interp)));
}
return NULL;
}
if ((mode & (O_APPEND|O_TRUNC)) && !wr) {
Tcl_SetErrno(EINVAL);
if (interp) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"Invalid flags 0x%x. O_APPEND and "
"O_TRUNC require write access: %s",
mode, Tcl_PosixError(interp)));
}
return NULL;
}
/*
* Is the file there?
*/
WriteLock();
z = ZipFSLookup(filename);
if (!z) {
Tcl_SetErrno(wr ? ENOTSUP : ENOENT);
if (interp) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"file \"%s\" not %s: %s",
filename, wr ? "created" : "found",
Tcl_PosixError(interp)));
}
goto error;
}
if (z->numBytes < 0 || z->numCompressedBytes < 0 ||
z->offset >= z->zipFilePtr->length) {
/* Normally this should only happen for zip64. */
|
| ︙ | ︙ | |||
6507 6508 6509 6510 6511 6512 6513 |
*/
int
TclZipfs_Mount(
Tcl_Interp *interp, /* Current interpreter. */
TCL_UNUSED(const char *), /* Path to ZIP file to mount. */
TCL_UNUSED(const char *), /* Mount point path. */
| | | 6510 6511 6512 6513 6514 6515 6516 6517 6518 6519 6520 6521 6522 6523 6524 |
*/
int
TclZipfs_Mount(
Tcl_Interp *interp, /* Current interpreter. */
TCL_UNUSED(const char *), /* Path to ZIP file to mount. */
TCL_UNUSED(const char *), /* Mount point path. */
TCL_UNUSED(const char *)) /* Password for opening the ZIP, or NULL if
* the ZIP is unprotected. */
{
ZIPFS_ERROR(interp, "no zlib available");
ZIPFS_ERROR_CODE(interp, "NO_ZLIB");
return TCL_ERROR;
}
|
| ︙ | ︙ |
Changes to generic/tclZlib.c.
| ︙ | ︙ | |||
1356 1357 1358 1359 1360 1361 1362 |
*----------------------------------------------------------------------
*/
int
Tcl_ZlibStreamGet(
Tcl_ZlibStream zshandle, /* As obtained from Tcl_ZlibStreamInit */
Tcl_Obj *data, /* A place to append the data. */
| | | 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 |
*----------------------------------------------------------------------
*/
int
Tcl_ZlibStreamGet(
Tcl_ZlibStream zshandle, /* As obtained from Tcl_ZlibStreamInit */
Tcl_Obj *data, /* A place to append the data. */
Tcl_Size count) /* Number of bytes to grab as a maximum, you
* may get less! */
{
ZlibStreamHandle *zshPtr = (ZlibStreamHandle *) zshandle;
int e;
Tcl_Size listLen, i, itemLen = 0, dataPos = 0;
Tcl_Obj *itemObj;
unsigned char *dataPtr, *itemPtr;
|
| ︙ | ︙ | |||
2984 2985 2986 2987 2988 2989 2990 |
*----------------------------------------------------------------------
*/
static int
ZlibTransformClose(
void *instanceData,
Tcl_Interp *interp,
| | | 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 |
*----------------------------------------------------------------------
*/
static int
ZlibTransformClose(
void *instanceData,
Tcl_Interp *interp,
int flags)
{
ZlibChannelData *cd = (ZlibChannelData *)instanceData;
int e, result = TCL_OK;
size_t written;
if ((flags & (TCL_CLOSE_READ | TCL_CLOSE_WRITE)) != 0) {
return EINVAL;
|
| ︙ | ︙ | |||
3105 3106 3107 3108 3109 3110 3111 |
return inProc(Tcl_GetChannelInstanceData(cd->parent), buf, toRead,
errorCodePtr);
}
gotBytes = 0;
readBytes = cd->inStream.avail_in; /* how many bytes in buffer now */
while (!(cd->flags & STREAM_DONE) && toRead > 0) {
| | | 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 |
return inProc(Tcl_GetChannelInstanceData(cd->parent), buf, toRead,
errorCodePtr);
}
gotBytes = 0;
readBytes = cd->inStream.avail_in; /* how many bytes in buffer now */
while (!(cd->flags & STREAM_DONE) && toRead > 0) {
unsigned int n; int decBytes;
/* if starting from scratch or continuation after full decompression */
if (!cd->inStream.avail_in) {
/* buffer to start, we can read to whole available buffer */
cd->inStream.next_in = (Bytef *) cd->inBuffer;
}
/*
|
| ︙ | ︙ |
Changes to macosx/tclMacOSXNotify.c.
| ︙ | ︙ | |||
307 308 309 310 311 312 313 |
int mask; /* Mask of desired events: TCL_READABLE,
* etc. */
int readyMask; /* Mask of events that have been seen since
* the last time file handlers were invoked
* for this file. */
Tcl_FileProc *proc; /* Function to call, in the style of
* Tcl_CreateFileHandler. */
| | | 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 |
int mask; /* Mask of desired events: TCL_READABLE,
* etc. */
int readyMask; /* Mask of events that have been seen since
* the last time file handlers were invoked
* for this file. */
Tcl_FileProc *proc; /* Function to call, in the style of
* Tcl_CreateFileHandler. */
void *clientData; /* Argument to pass to proc. */
struct FileHandler *nextPtr;/* Next in list of all files we care about. */
} FileHandler;
/*
* The following structure is what is added to the Tcl event queue when file
* handlers are ready to fire.
*/
|
| ︙ | ︙ | |||
1110 1111 1112 1113 1114 1115 1116 |
int fd, /* Handle of stream to watch. */
int mask, /* OR'ed combination of TCL_READABLE,
* TCL_WRITABLE, and TCL_EXCEPTION: indicates
* conditions under which proc should be
* called. */
Tcl_FileProc *proc, /* Function to call for each selected
* event. */
| | | 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 |
int fd, /* Handle of stream to watch. */
int mask, /* OR'ed combination of TCL_READABLE,
* TCL_WRITABLE, and TCL_EXCEPTION: indicates
* conditions under which proc should be
* called. */
Tcl_FileProc *proc, /* Function to call for each selected
* event. */
void *clientData) /* Arbitrary data to pass to proc. */
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
FileHandler *filePtr = LookUpFileHandler(tsdPtr, fd, NULL);
if (filePtr == NULL) {
filePtr = (FileHandler *) Tcl_Alloc(sizeof(FileHandler));
filePtr->fd = fd;
|
| ︙ | ︙ |
Changes to unix/dltest/pkgt.c.
| ︙ | ︙ | |||
51 52 53 54 55 56 57 |
*----------------------------------------------------------------------
*/
static int
Pkgt_EqObjCmd2(
void *dummy, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
| | | 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
*----------------------------------------------------------------------
*/
static int
Pkgt_EqObjCmd2(
void *dummy, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
Tcl_Size objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
Tcl_WideInt result;
const char *str1, *str2;
Tcl_Size len1, len2;
(void)dummy;
|
| ︙ | ︙ |
Changes to unix/tclEpollNotfy.c.
| ︙ | ︙ | |||
38 39 40 41 42 43 44 |
int mask; /* Mask of desired events: TCL_READABLE,
* etc. */
int readyMask; /* Mask of events that have been seen since
* the last time file handlers were invoked
* for this file. */
Tcl_FileProc *proc; /* Function to call, in the style of
* Tcl_CreateFileHandler. */
| | | 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
int mask; /* Mask of desired events: TCL_READABLE,
* etc. */
int readyMask; /* Mask of events that have been seen since
* the last time file handlers were invoked
* for this file. */
Tcl_FileProc *proc; /* Function to call, in the style of
* Tcl_CreateFileHandler. */
void *clientData; /* Argument to pass to proc. */
struct FileHandler *nextPtr;/* Next in list of all files we care about. */
LIST_ENTRY(FileHandler) readyNode;
/* Next/previous in list of FileHandlers asso-
* ciated with regular files (S_IFREG) that are
* ready for I/O. */
struct PlatformEventData *pedPtr;
/* Pointer to PlatformEventData associating this
|
| ︙ | ︙ | |||
509 510 511 512 513 514 515 |
int fd, /* Handle of stream to watch. */
int mask, /* OR'ed combination of TCL_READABLE,
* TCL_WRITABLE, and TCL_EXCEPTION: indicates
* conditions under which proc should be
* called. */
Tcl_FileProc *proc, /* Function to call for each selected
* event. */
| | | 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 |
int fd, /* Handle of stream to watch. */
int mask, /* OR'ed combination of TCL_READABLE,
* TCL_WRITABLE, and TCL_EXCEPTION: indicates
* conditions under which proc should be
* called. */
Tcl_FileProc *proc, /* Function to call for each selected
* event. */
void *clientData) /* Arbitrary data to pass to proc. */
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
FileHandler *filePtr = LookUpFileHandler(tsdPtr, fd, NULL);
int isNew = (filePtr == NULL);
if (isNew) {
filePtr = (FileHandler *) Tcl_Alloc(sizeof(FileHandler));
|
| ︙ | ︙ | |||
787 788 789 790 791 792 793 |
*----------------------------------------------------------------------
*/
int
TclAsyncNotifier(
int sigNumber, /* Signal number. */
Tcl_ThreadId threadId, /* Target thread. */
| | | 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 |
*----------------------------------------------------------------------
*/
int
TclAsyncNotifier(
int sigNumber, /* Signal number. */
Tcl_ThreadId threadId, /* Target thread. */
void *clientData, /* Notifier data. */
int *flagPtr, /* Flag to mark. */
int value) /* Value of mark. */
{
#if TCL_THREADS
/*
* WARNING:
* This code most likely runs in a signal handler. Thus,
|
| ︙ | ︙ |
Changes to unix/tclKqueueNotfy.c.
| ︙ | ︙ | |||
36 37 38 39 40 41 42 |
int mask; /* Mask of desired events: TCL_READABLE,
* etc. */
int readyMask; /* Mask of events that have been seen since
* the last time file handlers were invoked
* for this file. */
Tcl_FileProc *proc; /* Function to call, in the style of
* Tcl_CreateFileHandler. */
| | | 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
int mask; /* Mask of desired events: TCL_READABLE,
* etc. */
int readyMask; /* Mask of events that have been seen since
* the last time file handlers were invoked
* for this file. */
Tcl_FileProc *proc; /* Function to call, in the style of
* Tcl_CreateFileHandler. */
void *clientData; /* Argument to pass to proc. */
struct FileHandler *nextPtr;/* Next in list of all files we care about. */
LIST_ENTRY(FileHandler) readyNode;
/* Next/previous in list of FileHandlers asso-
* ciated with regular files (S_IFREG) that are
* ready for I/O. */
struct PlatformEventData *pedPtr;
/* Pointer to PlatformEventData associating this
|
| ︙ | ︙ | |||
514 515 516 517 518 519 520 |
int fd, /* Handle of stream to watch. */
int mask, /* OR'ed combination of TCL_READABLE,
* TCL_WRITABLE, and TCL_EXCEPTION: indicates
* conditions under which proc should be
* called. */
Tcl_FileProc *proc, /* Function to call for each selected
* event. */
| | | 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 |
int fd, /* Handle of stream to watch. */
int mask, /* OR'ed combination of TCL_READABLE,
* TCL_WRITABLE, and TCL_EXCEPTION: indicates
* conditions under which proc should be
* called. */
Tcl_FileProc *proc, /* Function to call for each selected
* event. */
void *clientData) /* Arbitrary data to pass to proc. */
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
FileHandler *filePtr = LookUpFileHandler(tsdPtr, fd, NULL);
int isNew = (filePtr == NULL);
if (isNew) {
filePtr = (FileHandler *) Tcl_Alloc(sizeof(FileHandler));
|
| ︙ | ︙ | |||
783 784 785 786 787 788 789 |
*----------------------------------------------------------------------
*/
int
TclAsyncNotifier(
int sigNumber, /* Signal number. */
Tcl_ThreadId threadId, /* Target thread. */
| | | 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 |
*----------------------------------------------------------------------
*/
int
TclAsyncNotifier(
int sigNumber, /* Signal number. */
Tcl_ThreadId threadId, /* Target thread. */
void *clientData, /* Notifier data. */
int *flagPtr, /* Flag to mark. */
int value) /* Value of mark. */
{
#if TCL_THREADS
/*
* WARNING:
* This code most likely runs in a signal handler. Thus,
|
| ︙ | ︙ |
Changes to unix/tclSelectNotfy.c.
| ︙ | ︙ | |||
28 29 30 31 32 33 34 |
int mask; /* Mask of desired events: TCL_READABLE,
* etc. */
int readyMask; /* Mask of events that have been seen since
* the last time file handlers were invoked
* for this file. */
Tcl_FileProc *proc; /* Function to call, in the style of
* Tcl_CreateFileHandler. */
| | | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
int mask; /* Mask of desired events: TCL_READABLE,
* etc. */
int readyMask; /* Mask of events that have been seen since
* the last time file handlers were invoked
* for this file. */
Tcl_FileProc *proc; /* Function to call, in the style of
* Tcl_CreateFileHandler. */
void *clientData; /* Argument to pass to proc. */
struct FileHandler *nextPtr;/* Next in list of all files we care about. */
} FileHandler;
/*
* The following structure contains a set of select() masks to track readable,
* writable, and exception conditions.
*/
|
| ︙ | ︙ | |||
476 477 478 479 480 481 482 |
int fd, /* Handle of stream to watch. */
int mask, /* OR'ed combination of TCL_READABLE,
* TCL_WRITABLE, and TCL_EXCEPTION: indicates
* conditions under which proc should be
* called. */
Tcl_FileProc *proc, /* Function to call for each selected
* event. */
| | | 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 |
int fd, /* Handle of stream to watch. */
int mask, /* OR'ed combination of TCL_READABLE,
* TCL_WRITABLE, and TCL_EXCEPTION: indicates
* conditions under which proc should be
* called. */
Tcl_FileProc *proc, /* Function to call for each selected
* event. */
void *clientData) /* Arbitrary data to pass to proc. */
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
FileHandler *filePtr = LookUpFileHandler(tsdPtr, fd, NULL);
if (filePtr == NULL) {
filePtr = (FileHandler *) Tcl_Alloc(sizeof(FileHandler));
filePtr->fd = fd;
|
| ︙ | ︙ |
Changes to unix/tclUnixChan.c.
| ︙ | ︙ | |||
221 222 223 224 225 226 227 | * Sets the device into blocking or non-blocking mode. * *---------------------------------------------------------------------- */ static int FileBlockModeProc( | | | 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 |
* Sets the device into blocking or non-blocking mode.
*
*----------------------------------------------------------------------
*/
static int
FileBlockModeProc(
void *instanceData, /* File state. */
int mode) /* The mode to set. Can be TCL_MODE_BLOCKING
* or TCL_MODE_NONBLOCKING. */
{
FileState *fsPtr = (FileState *)instanceData;
if (TclUnixSetBlockingMode(fsPtr->fd, mode) < 0) {
return errno;
|
| ︙ | ︙ | |||
254 255 256 257 258 259 260 | * Reads input from the input device of the channel. * *---------------------------------------------------------------------- */ static int FileInputProc( | | | 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 |
* Reads input from the input device of the channel.
*
*----------------------------------------------------------------------
*/
static int
FileInputProc(
void *instanceData, /* File state. */
char *buf, /* Where to store data read. */
int toRead, /* How much space is available in the
* buffer? */
int *errorCodePtr) /* Where to store error code. */
{
FileState *fsPtr = (FileState *)instanceData;
int bytesRead; /* How many bytes were actually read from the
|
| ︙ | ︙ | |||
304 305 306 307 308 309 310 | * Writes output on the output device of the channel. * *---------------------------------------------------------------------- */ static int FileOutputProc( | | | 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 |
* Writes output on the output device of the channel.
*
*----------------------------------------------------------------------
*/
static int
FileOutputProc(
void *instanceData, /* File state. */
const char *buf, /* The data buffer. */
int toWrite, /* How many bytes to write? */
int *errorCodePtr) /* Where to store error code. */
{
FileState *fsPtr = (FileState *)instanceData;
int written;
|
| ︙ | ︙ | |||
351 352 353 354 355 356 357 | * Closes the device of the channel. * *---------------------------------------------------------------------- */ static int FileCloseProc( | | | 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 |
* Closes the device of the channel.
*
*----------------------------------------------------------------------
*/
static int
FileCloseProc(
void *instanceData, /* File state. */
TCL_UNUSED(Tcl_Interp *),
int flags)
{
FileState *fsPtr = (FileState *)instanceData;
int errorCode = 0;
if ((flags & (TCL_CLOSE_READ | TCL_CLOSE_WRITE)) != 0) {
|
| ︙ | ︙ | |||
383 384 385 386 387 388 389 |
}
#ifdef SUPPORTS_TTY
static int
TtyCloseProc(
void *instanceData,
Tcl_Interp *interp,
| | | 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 |
}
#ifdef SUPPORTS_TTY
static int
TtyCloseProc(
void *instanceData,
Tcl_Interp *interp,
int flags)
{
TtyState *ttyPtr = (TtyState*)instanceData;
if ((flags & (TCL_CLOSE_READ | TCL_CLOSE_WRITE)) != 0) {
return EINVAL;
}
/*
|
| ︙ | ︙ | |||
444 445 446 447 448 449 450 | * operations. * *---------------------------------------------------------------------- */ static long long FileWideSeekProc( | | | 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 |
* operations.
*
*----------------------------------------------------------------------
*/
static long long
FileWideSeekProc(
void *instanceData, /* File state. */
long long offset, /* Offset to seek to. */
int mode, /* Relative to where should we seek? Can be
* one of SEEK_START, SEEK_CUR or SEEK_END. */
int *errorCodePtr) /* To store error code. */
{
FileState *fsPtr = (FileState *)instanceData;
long long newLoc;
|
| ︙ | ︙ | |||
492 493 494 495 496 497 498 |
{
Tcl_Channel channel = (Tcl_Channel)clientData;
Tcl_NotifyChannel(channel, mask);
}
static void
FileWatchProc(
| | | 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 |
{
Tcl_Channel channel = (Tcl_Channel)clientData;
Tcl_NotifyChannel(channel, mask);
}
static void
FileWatchProc(
void *instanceData, /* The file state. */
int mask) /* Events of interest; an OR-ed combination of
* TCL_READABLE, TCL_WRITABLE and
* TCL_EXCEPTION. */
{
FileState *fsPtr = (FileState *)instanceData;
/*
|
| ︙ | ︙ | |||
532 533 534 535 536 537 538 | * None. * *---------------------------------------------------------------------- */ static int FileGetHandleProc( | | | | 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 |
* None.
*
*----------------------------------------------------------------------
*/
static int
FileGetHandleProc(
void *instanceData, /* The file state. */
int direction, /* TCL_READABLE or TCL_WRITABLE */
void **handlePtr) /* Where to store the handle. */
{
FileState *fsPtr = (FileState *)instanceData;
if (direction & fsPtr->validMask) {
*handlePtr = INT2PTR(fsPtr->fd);
return TCL_OK;
}
|
| ︙ | ︙ | |||
769 770 771 772 773 774 775 | * calling Tcl_BadChannelOption). * *---------------------------------------------------------------------- */ static int TtySetOptionProc( | | | 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 |
* calling Tcl_BadChannelOption).
*
*----------------------------------------------------------------------
*/
static int
TtySetOptionProc(
void *instanceData, /* File state. */
Tcl_Interp *interp, /* For error reporting - can be NULL. */
const char *optionName, /* Which option to set? */
const char *value) /* New value for option. */
{
TtyState *fsPtr = (TtyState *)instanceData;
size_t len, vlen;
TtyAttrs tty;
|
| ︙ | ︙ | |||
1109 1110 1111 1112 1113 1114 1115 | * (by calling Tcl_BadChannelOption). * *---------------------------------------------------------------------- */ static int TtyGetOptionProc( | | | 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 |
* (by calling Tcl_BadChannelOption).
*
*----------------------------------------------------------------------
*/
static int
TtyGetOptionProc(
void *instanceData, /* File state. */
Tcl_Interp *interp, /* For error reporting - can be NULL. */
const char *optionName, /* Option to get. */
Tcl_DString *dsPtr) /* Where to store value(s). */
{
TtyState *fsPtr = (TtyState *)instanceData;
size_t len;
char buf[3*TCL_INTEGER_SPACE + 16];
|
| ︙ | ︙ | |||
2065 2066 2067 2068 2069 2070 2071 |
const char *chanID, /* String that identifies file. */
int forWriting, /* 1 means the file is going to be used for
* writing, 0 means for reading. */
TCL_UNUSED(int), /* Obsolete argument.
* Ignored, we always check that
* the channel is open for the requested
* mode. */
| | | 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 |
const char *chanID, /* String that identifies file. */
int forWriting, /* 1 means the file is going to be used for
* writing, 0 means for reading. */
TCL_UNUSED(int), /* Obsolete argument.
* Ignored, we always check that
* the channel is open for the requested
* mode. */
void **filePtr) /* Store pointer to FILE structure here. */
{
Tcl_Channel chan;
int chanMode, fd;
const Tcl_ChannelType *chanTypePtr;
void *data;
FILE *f;
|
| ︙ | ︙ |
Changes to unix/tclUnixPipe.c.
| ︙ | ︙ | |||
1000 1001 1002 1003 1004 1005 1006 | * Sets the device into blocking or non-blocking mode. * *---------------------------------------------------------------------- */ static int PipeBlockModeProc( | | | 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 |
* Sets the device into blocking or non-blocking mode.
*
*----------------------------------------------------------------------
*/
static int
PipeBlockModeProc(
void *instanceData, /* Pipe state. */
int mode) /* The mode to set. Can be one of
* TCL_MODE_BLOCKING or
* TCL_MODE_NONBLOCKING. */
{
PipeState *psPtr = (PipeState *)instanceData;
if (psPtr->inFile
|
| ︙ | ︙ | |||
1040 1041 1042 1043 1044 1045 1046 | * Closes the command pipeline channel. * *---------------------------------------------------------------------- */ static int PipeClose2Proc( | | | 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 |
* Closes the command pipeline channel.
*
*----------------------------------------------------------------------
*/
static int
PipeClose2Proc(
void *instanceData, /* The pipe to close. */
Tcl_Interp *interp, /* For error reporting. */
int flags) /* Flags that indicate which side to close. */
{
PipeState *pipePtr = (PipeState *)instanceData;
Tcl_Channel errChan;
int errorCode, result;
|
| ︙ | ︙ | |||
1137 1138 1139 1140 1141 1142 1143 | * Reads input from the input device of the channel. * *---------------------------------------------------------------------- */ static int PipeInputProc( | | | 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 |
* Reads input from the input device of the channel.
*
*----------------------------------------------------------------------
*/
static int
PipeInputProc(
void *instanceData, /* Pipe state. */
char *buf, /* Where to store data read. */
int toRead, /* How much space is available in the
* buffer? */
int *errorCodePtr) /* Where to store error code. */
{
PipeState *psPtr = (PipeState *)instanceData;
int bytesRead; /* How many bytes were actually read from the
|
| ︙ | ︙ | |||
1188 1189 1190 1191 1192 1193 1194 | * Writes output on the output device of the channel. * *---------------------------------------------------------------------- */ static int PipeOutputProc( | | | 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 |
* Writes output on the output device of the channel.
*
*----------------------------------------------------------------------
*/
static int
PipeOutputProc(
void *instanceData, /* Pipe state. */
const char *buf, /* The data buffer. */
int toWrite, /* How many bytes to write? */
int *errorCodePtr) /* Where to store error code. */
{
PipeState *psPtr = (PipeState *)instanceData;
int written;
|
| ︙ | ︙ | |||
1247 1248 1249 1250 1251 1252 1253 |
{
Tcl_Channel channel = (Tcl_Channel)clientData;
Tcl_NotifyChannel(channel, mask);
}
static void
PipeWatchProc(
| | | 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 |
{
Tcl_Channel channel = (Tcl_Channel)clientData;
Tcl_NotifyChannel(channel, mask);
}
static void
PipeWatchProc(
void *instanceData, /* The pipe state. */
int mask) /* Events of interest; an OR-ed combination of
* TCL_READABLE, TCL_WRITABLE and
* TCL_EXCEPTION. */
{
PipeState *psPtr = (PipeState *)instanceData;
int newmask;
|
| ︙ | ︙ | |||
1295 1296 1297 1298 1299 1300 1301 | * None. * *---------------------------------------------------------------------- */ static int PipeGetHandleProc( | | | | 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 |
* None.
*
*----------------------------------------------------------------------
*/
static int
PipeGetHandleProc(
void *instanceData, /* The pipe state. */
int direction, /* TCL_READABLE or TCL_WRITABLE */
void **handlePtr) /* Where to store the handle. */
{
PipeState *psPtr = (PipeState *)instanceData;
if (direction == TCL_READABLE && psPtr->inFile) {
*handlePtr = INT2PTR(GetFd(psPtr->inFile));
return TCL_OK;
}
|
| ︙ | ︙ |
Changes to unix/tclUnixSock.c.
| ︙ | ︙ | |||
61 62 63 64 65 66 67 |
/*
* Only needed for server sockets
*/
Tcl_TcpAcceptProc *acceptProc;
/* Proc to call on accept. */
| | | 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
/*
* Only needed for server sockets
*/
Tcl_TcpAcceptProc *acceptProc;
/* Proc to call on accept. */
void *acceptProcData; /* The data for the accept proc. */
/*
* Only needed for client sockets
*/
struct addrinfo *addrlist; /* Addresses to connect to. */
struct addrinfo *addr; /* Iterator over addrlist. */
|
| ︙ | ︙ | |||
353 354 355 356 357 358 359 | * Sets the device into blocking or nonblocking mode. * * ---------------------------------------------------------------------- */ static int TcpBlockModeProc( | | | 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 |
* Sets the device into blocking or nonblocking mode.
*
* ----------------------------------------------------------------------
*/
static int
TcpBlockModeProc(
void *instanceData, /* Socket state. */
int mode) /* The mode to set. Can be one of
* TCL_MODE_BLOCKING or
* TCL_MODE_NONBLOCKING. */
{
TcpState *statePtr = (TcpState *)instanceData;
if (mode == TCL_MODE_BLOCKING) {
|
| ︙ | ︙ | |||
498 499 500 501 502 503 504 | * Reads input from the input device of the channel. * *---------------------------------------------------------------------- */ static int TcpInputProc( | | | 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 |
* Reads input from the input device of the channel.
*
*----------------------------------------------------------------------
*/
static int
TcpInputProc(
void *instanceData, /* Socket state. */
char *buf, /* Where to store data read. */
int bufSize, /* How much space is available in the
* buffer? */
int *errorCodePtr) /* Where to store error code. */
{
TcpState *statePtr = (TcpState *)instanceData;
int bytesRead;
|
| ︙ | ︙ | |||
549 550 551 552 553 554 555 | * Writes output on the output device of the channel. * *---------------------------------------------------------------------- */ static int TcpOutputProc( | | | 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 |
* Writes output on the output device of the channel.
*
*----------------------------------------------------------------------
*/
static int
TcpOutputProc(
void *instanceData, /* Socket state. */
const char *buf, /* The data buffer. */
int toWrite, /* How many bytes to write? */
int *errorCodePtr) /* Where to store error code. */
{
TcpState *statePtr = (TcpState *)instanceData;
int written;
|
| ︙ | ︙ | |||
590 591 592 593 594 595 596 | * Closes the socket of the channel. * *---------------------------------------------------------------------- */ static int TcpCloseProc( | | | 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 |
* Closes the socket of the channel.
*
*----------------------------------------------------------------------
*/
static int
TcpCloseProc(
void *instanceData, /* The socket to close. */
TCL_UNUSED(Tcl_Interp *))
{
TcpState *statePtr = (TcpState *)instanceData;
int errorCode = 0;
TcpFdList *fds;
/*
|
| ︙ | ︙ | |||
651 652 653 654 655 656 657 | * Shuts down one side of the socket. * *---------------------------------------------------------------------- */ static int TcpClose2Proc( | | | 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 |
* Shuts down one side of the socket.
*
*----------------------------------------------------------------------
*/
static int
TcpClose2Proc(
void *instanceData, /* The socket to close. */
TCL_UNUSED(Tcl_Interp *),
int flags) /* Flags that indicate which side to close. */
{
TcpState *statePtr = (TcpState *)instanceData;
int readError = 0;
int writeError = 0;
|
| ︙ | ︙ | |||
1165 1166 1167 1168 1169 1170 1171 |
newmask = TCL_WRITABLE;
}
Tcl_NotifyChannel(statePtr->channel, newmask);
}
static void
TcpWatchProc(
| | | 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 |
newmask = TCL_WRITABLE;
}
Tcl_NotifyChannel(statePtr->channel, newmask);
}
static void
TcpWatchProc(
void *instanceData, /* The socket state. */
int mask) /* Events of interest; an OR-ed combination of
* TCL_READABLE, TCL_WRITABLE and
* TCL_EXCEPTION. */
{
TcpState *statePtr = (TcpState *)instanceData;
if (statePtr->acceptProc != NULL) {
|
| ︙ | ︙ | |||
1238 1239 1240 1241 1242 1243 1244 | * None. * * ---------------------------------------------------------------------- */ static int TcpGetHandleProc( | | | | 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 |
* None.
*
* ----------------------------------------------------------------------
*/
static int
TcpGetHandleProc(
void *instanceData, /* The socket state. */
TCL_UNUSED(int) /*direction*/,
void **handlePtr) /* Where to store the handle. */
{
TcpState *statePtr = (TcpState *)instanceData;
*handlePtr = INT2PTR(statePtr->fds.fd);
return TCL_OK;
}
|
| ︙ | ︙ | |||
1262 1263 1264 1265 1266 1267 1268 | * attempt has succeeded or failed. * * ---------------------------------------------------------------------- */ static void TcpAsyncCallback( | | | 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 |
* attempt has succeeded or failed.
*
* ----------------------------------------------------------------------
*/
static void
TcpAsyncCallback(
void *clientData, /* The socket state. */
TCL_UNUSED(int) /*mask*/)
{
TcpConnect(NULL, (TcpState *)clientData);
}
/*
* ----------------------------------------------------------------------
|
| ︙ | ︙ | |||
1571 1572 1573 1574 1575 1576 1577 | * None. * *---------------------------------------------------------------------- */ Tcl_Channel Tcl_MakeTcpClientChannel( | | | 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 |
* None.
*
*----------------------------------------------------------------------
*/
Tcl_Channel
Tcl_MakeTcpClientChannel(
void *sock) /* The socket to wrap up into a channel. */
{
return (Tcl_Channel) TclpMakeTcpClientChannelMode(sock,
TCL_READABLE | TCL_WRITABLE);
}
/*
*----------------------------------------------------------------------
|
| ︙ | ︙ | |||
1596 1597 1598 1599 1600 1601 1602 | * None. * *---------------------------------------------------------------------- */ void * TclpMakeTcpClientChannelMode( | | | 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 |
* None.
*
*----------------------------------------------------------------------
*/
void *
TclpMakeTcpClientChannelMode(
void *sock, /* The socket to wrap up into a channel. */
int mode) /* OR'ed combination of TCL_READABLE and
* TCL_WRITABLE to indicate file mode. */
{
TcpState *statePtr;
char channelName[SOCK_CHAN_LENGTH];
statePtr = (TcpState *)Tcl_Alloc(sizeof(TcpState));
|
| ︙ | ︙ | |||
1897 1898 1899 1900 1901 1902 1903 | * connection acceptance mechanism. * *---------------------------------------------------------------------- */ static void TcpAccept( | | | 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 |
* connection acceptance mechanism.
*
*----------------------------------------------------------------------
*/
static void
TcpAccept(
void *data, /* Callback token. */
TCL_UNUSED(int) /*mask*/)
{
TcpFdList *fds = (TcpFdList *)data; /* Client data of server socket. */
int newsock; /* The new client socket */
TcpState *newSockState; /* State for new socket. */
address addr; /* The remote address */
socklen_t len; /* For accept interface */
|
| ︙ | ︙ |
Changes to unix/tclUnixTest.c.
| ︙ | ︙ | |||
308 309 310 311 312 313 314 |
return TCL_ERROR;
}
return TCL_OK;
}
static void
TestFileHandlerProc(
| | | 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 |
return TCL_ERROR;
}
return TCL_OK;
}
static void
TestFileHandlerProc(
void *clientData, /* Points to a Pipe structure. */
int mask) /* Indicates which events happened:
* TCL_READABLE or TCL_WRITABLE. */
{
Pipe *pipePtr = (Pipe *)clientData;
if (mask & TCL_READABLE) {
pipePtr->readCount++;
|
| ︙ | ︙ |
Changes to unix/tclUnixThrd.c.
| ︙ | ︙ | |||
209 210 211 212 213 214 215 |
*----------------------------------------------------------------------
*/
int
TclpThreadCreate(
Tcl_ThreadId *idPtr, /* Return, the ID of the thread */
Tcl_ThreadCreateProc *proc, /* Main() function of the thread */
| | | | 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 |
*----------------------------------------------------------------------
*/
int
TclpThreadCreate(
Tcl_ThreadId *idPtr, /* Return, the ID of the thread */
Tcl_ThreadCreateProc *proc, /* Main() function of the thread */
void *clientData, /* The one argument to Main() */
size_t stackSize, /* Size of stack for the new thread */
int flags) /* Flags controlling behaviour of the new
* thread. */
{
#if TCL_THREADS
pthread_attr_t attr;
pthread_t theThread;
int result;
|
| ︙ | ︙ |
Changes to unix/tclXtNotify.c.
| ︙ | ︙ | |||
29 30 31 32 33 34 35 |
* time FileHandlerEventProc was called for
* this file. */
XtInputId read; /* Xt read callback handle. */
XtInputId write; /* Xt write callback handle. */
XtInputId except; /* Xt exception callback handle. */
Tcl_FileProc *proc; /* Procedure to call, in the style of
* Tcl_CreateFileHandler. */
| | | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
* time FileHandlerEventProc was called for
* this file. */
XtInputId read; /* Xt read callback handle. */
XtInputId write; /* Xt write callback handle. */
XtInputId except; /* Xt exception callback handle. */
Tcl_FileProc *proc; /* Procedure to call, in the style of
* Tcl_CreateFileHandler. */
void *clientData; /* Argument to pass to proc. */
struct FileHandler *nextPtr;/* Next in list of all files we care about. */
} FileHandler;
/*
* The following structure is what is added to the Tcl event queue when file
* handlers are ready to fire.
*/
|
| ︙ | ︙ | |||
335 336 337 338 339 340 341 |
int fd, /* Handle of stream to watch. */
int mask, /* OR'ed combination of TCL_READABLE,
* TCL_WRITABLE, and TCL_EXCEPTION: indicates
* conditions under which proc should be
* called. */
Tcl_FileProc *proc, /* Procedure to call for each selected
* event. */
| | | 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 |
int fd, /* Handle of stream to watch. */
int mask, /* OR'ed combination of TCL_READABLE,
* TCL_WRITABLE, and TCL_EXCEPTION: indicates
* conditions under which proc should be
* called. */
Tcl_FileProc *proc, /* Procedure to call for each selected
* event. */
void *clientData) /* Arbitrary data to pass to proc. */
{
FileHandler *filePtr;
if (!initialized) {
InitNotifier();
}
|
| ︙ | ︙ |
Changes to win/tclWinChan.c.
| ︙ | ︙ | |||
354 355 356 357 358 359 360 | * Sets the device into blocking or non-blocking mode. * *---------------------------------------------------------------------- */ static int FileBlockProc( | | | 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 |
* Sets the device into blocking or non-blocking mode.
*
*----------------------------------------------------------------------
*/
static int
FileBlockProc(
void *instanceData, /* Instance data for channel. */
int mode) /* TCL_MODE_BLOCKING or
* TCL_MODE_NONBLOCKING. */
{
FileInfo *infoPtr = (FileInfo *)instanceData;
/*
* Files on Windows can not be switched between blocking and nonblocking,
|
| ︙ | ︙ | |||
393 394 395 396 397 398 399 | * Closes the physical channel * *---------------------------------------------------------------------- */ static int FileCloseProc( | | | 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 |
* Closes the physical channel
*
*----------------------------------------------------------------------
*/
static int
FileCloseProc(
void *instanceData, /* Pointer to FileInfo structure. */
TCL_UNUSED(Tcl_Interp *),
int flags)
{
FileInfo *fileInfoPtr = (FileInfo *)instanceData;
FileInfo *infoPtr;
ThreadSpecificData *tsdPtr;
int errorCode = 0;
|
| ︙ | ︙ | |||
471 472 473 474 475 476 477 | * operations. * *---------------------------------------------------------------------- */ static long long FileWideSeekProc( | | | 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 |
* operations.
*
*----------------------------------------------------------------------
*/
static long long
FileWideSeekProc(
void *instanceData, /* File state. */
long long offset, /* Offset to seek to. */
int mode, /* Relative to where should we seek? */
int *errorCodePtr) /* To store error code. */
{
FileInfo *infoPtr = (FileInfo *)instanceData;
DWORD moveMethod;
LONG newPos, newPosHigh;
|
| ︙ | ︙ | |||
523 524 525 526 527 528 529 | * Truncates the file, may move file pointers too. * *---------------------------------------------------------------------- */ static int FileTruncateProc( | | | 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 |
* Truncates the file, may move file pointers too.
*
*----------------------------------------------------------------------
*/
static int
FileTruncateProc(
void *instanceData, /* File state. */
long long length) /* Length to truncate at. */
{
FileInfo *infoPtr = (FileInfo *)instanceData;
LONG newPos, newPosHigh, oldPos, oldPosHigh;
/*
* Save where we were...
|
| ︙ | ︙ | |||
599 600 601 602 603 604 605 | * Reads input from the actual channel. * *---------------------------------------------------------------------- */ static int FileInputProc( | | | 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 |
* Reads input from the actual channel.
*
*----------------------------------------------------------------------
*/
static int
FileInputProc(
void *instanceData, /* File state. */
char *buf, /* Where to store data read. */
int bufSize, /* Num bytes available in buffer. */
int *errorCode) /* Where to store error code. */
{
FileInfo *infoPtr = (FileInfo *)instanceData;
DWORD bytesRead;
|
| ︙ | ︙ | |||
654 655 656 657 658 659 660 | * Writes output on the actual channel. * *---------------------------------------------------------------------- */ static int FileOutputProc( | | | 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 |
* Writes output on the actual channel.
*
*----------------------------------------------------------------------
*/
static int
FileOutputProc(
void *instanceData, /* File state. */
const char *buf, /* The data buffer. */
int toWrite, /* How many bytes to write? */
int *errorCode) /* Where to store error code. */
{
FileInfo *infoPtr = (FileInfo *)instanceData;
DWORD bytesWritten;
|
| ︙ | ︙ | |||
701 702 703 704 705 706 707 | * None. * *---------------------------------------------------------------------- */ static void FileWatchProc( | | | 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 |
* None.
*
*----------------------------------------------------------------------
*/
static void
FileWatchProc(
void *instanceData, /* File state. */
int mask) /* What events to watch for; OR-ed combination
* of TCL_READABLE, TCL_WRITABLE and
* TCL_EXCEPTION. */
{
FileInfo *infoPtr = (FileInfo *)instanceData;
Tcl_Time blockTime = { 0, 0 };
|
| ︙ | ︙ | |||
740 741 742 743 744 745 746 | * None. * *---------------------------------------------------------------------- */ static int FileGetHandleProc( | | | | 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 |
* None.
*
*----------------------------------------------------------------------
*/
static int
FileGetHandleProc(
void *instanceData, /* The file state. */
int direction, /* TCL_READABLE or TCL_WRITABLE */
void **handlePtr) /* Where to store the handle. */
{
FileInfo *infoPtr = (FileInfo *)instanceData;
if (!TEST_FLAG(direction, infoPtr->validMask)) {
return TCL_ERROR;
}
|
| ︙ | ︙ | |||
890 891 892 893 894 895 896 |
#undef STORE_ELEM
return dictObj;
}
static int
FileGetOptionProc(
| | | 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 |
#undef STORE_ELEM
return dictObj;
}
static int
FileGetOptionProc(
void *instanceData, /* The file state. */
Tcl_Interp *interp, /* For error reporting. */
const char *optionName, /* What option to read, or NULL for all. */
Tcl_DString *dsPtr) /* Where to write the value read. */
{
FileInfo *infoPtr = (FileInfo *)instanceData;
int valid = 0; /* Flag if valid option parsed. */
int len;
|
| ︙ | ︙ | |||
1188 1189 1190 1191 1192 1193 1194 | * None. * *---------------------------------------------------------------------- */ Tcl_Channel Tcl_MakeFileChannel( | | | 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 |
* None.
*
*----------------------------------------------------------------------
*/
Tcl_Channel
Tcl_MakeFileChannel(
void *rawHandle, /* OS level handle */
int mode) /* OR'ed combination of TCL_READABLE and
* TCL_WRITABLE to indicate file mode. */
{
#if defined(HAVE_NO_SEH) && !defined(_WIN64) && !defined(__clang__)
TCLEXCEPTION_REGISTRATION registration;
#endif
char channelName[16 + TCL_INTEGER_SPACE];
|
| ︙ | ︙ |
Changes to win/tclWinConsole.c.
| ︙ | ︙ | |||
81 82 83 84 85 86 87 |
#endif
/*
* Ring buffer for storing data. Actual data is from bufPtr[start]:bufPtr[size-1]
* and bufPtr[0]:bufPtr[length - (size-start)].
*/
typedef struct RingBuffer {
| | | | | | 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
#endif
/*
* Ring buffer for storing data. Actual data is from bufPtr[start]:bufPtr[size-1]
* and bufPtr[0]:bufPtr[length - (size-start)].
*/
typedef struct RingBuffer {
char *bufPtr; /* Pointer to buffer storage */
Tcl_Size capacity; /* Size of the buffer in RingBufferChar */
Tcl_Size start; /* Start of the data within the buffer. */
Tcl_Size length; /* Number of RingBufferChar*/
} RingBuffer;
#define RingBufferLength(ringPtr_) ((ringPtr_)->length)
#define RingBufferHasFreeSpace(ringPtr_) ((ringPtr_)->length < (ringPtr_)->capacity)
#define RINGBUFFER_ASSERT(ringPtr_) assert(RingBufferCheck(ringPtr_))
/*
* The Win32 console API does not support non-blocking I/O in any form. Thus
|
| ︙ | ︙ | |||
376 377 378 379 380 381 382 |
* Internal buffer is updated.
*
*------------------------------------------------------------------------
*/
static Tcl_Size
RingBufferIn(
RingBuffer *ringPtr,
| | | | < | 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 |
* Internal buffer is updated.
*
*------------------------------------------------------------------------
*/
static Tcl_Size
RingBufferIn(
RingBuffer *ringPtr,
const char *srcPtr, /* Source to be copied */
Tcl_Size srcLen, /* Length of source */
int partialCopyOk) /* If true, partial copy is permitted */
{
Tcl_Size freeSpace;
RINGBUFFER_ASSERT(ringPtr);
freeSpace = ringPtr->capacity - ringPtr->length;
if (freeSpace < srcLen) {
|
| ︙ | ︙ | |||
437 438 439 440 441 442 443 | * * Side effects: * Internal buffer is updated. * *------------------------------------------------------------------------ */ static Tcl_Size | | > | | | | 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 |
*
* Side effects:
* Internal buffer is updated.
*
*------------------------------------------------------------------------
*/
static Tcl_Size
RingBufferOut(
RingBuffer *ringPtr,
char *dstPtr, /* Buffer for output data. May be NULL */
Tcl_Size dstCapacity, /* Size of buffer */
int partialCopyOk) /* If true, return what's available */
{
Tcl_Size leadLen;
RINGBUFFER_ASSERT(ringPtr);
if (dstCapacity > ringPtr->length) {
if (dstPtr && !partialCopyOk) {
|
| ︙ | ︙ | |||
489 490 491 492 493 494 495 |
RINGBUFFER_ASSERT(ringPtr);
return dstCapacity;
}
#ifndef NDEBUG
static int
| | > | 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 |
RINGBUFFER_ASSERT(ringPtr);
return dstCapacity;
}
#ifndef NDEBUG
static int
RingBufferCheck(
const RingBuffer *ringPtr)
{
return (ringPtr->bufPtr != NULL && ringPtr->capacity == CONSOLE_BUFFER_SIZE
&& ringPtr->start < ringPtr->capacity
&& ringPtr->length <= ringPtr->capacity);
}
#endif
|
| ︙ | ︙ | |||
708 709 710 711 712 713 714 | * Results: * None. * * Side effects: * As above. *------------------------------------------------------------------------ */ | | > | 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 |
* Results:
* None.
*
* Side effects:
* As above.
*------------------------------------------------------------------------
*/
void NudgeWatchers(
HANDLE consoleHandle)
{
ConsoleChannelInfo *chanInfoPtr;
AcquireSRWLockShared(&gConsoleLock); /* Shared-read lock */
for (chanInfoPtr = gWatchingChannelList; chanInfoPtr;
chanInfoPtr = chanInfoPtr->nextWatchingChannelPtr) {
/*
* Notify channels interested in our handle AND that have
|
| ︙ | ︙ | |||
912 913 914 915 916 917 918 | * Sets the device into blocking or non-blocking mode. * *---------------------------------------------------------------------- */ static int ConsoleBlockModeProc( | | | 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 |
* Sets the device into blocking or non-blocking mode.
*
*----------------------------------------------------------------------
*/
static int
ConsoleBlockModeProc(
void *instanceData, /* Instance data for channel. */
int mode) /* TCL_MODE_BLOCKING or
* TCL_MODE_NONBLOCKING. */
{
ConsoleChannelInfo *chanInfoPtr = (ConsoleChannelInfo *)instanceData;
/*
* Consoles on Windows can not be switched between blocking and
|
| ︙ | ︙ | |||
952 953 954 955 956 957 958 | * Closes the physical channel. * *---------------------------------------------------------------------- */ static int ConsoleCloseProc( | | | 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 |
* Closes the physical channel.
*
*----------------------------------------------------------------------
*/
static int
ConsoleCloseProc(
void *instanceData, /* Pointer to ConsoleChannelInfo structure. */
TCL_UNUSED(Tcl_Interp *),
int flags)
{
ConsoleChannelInfo *chanInfoPtr = (ConsoleChannelInfo *)instanceData;
ConsoleHandleInfo *handleInfoPtr;
int errorCode = 0;
ConsoleChannelInfo **nextPtrPtr;
|
| ︙ | ︙ | |||
1071 1072 1073 1074 1075 1076 1077 | * Side effects: * Reads input from the actual channel. * *---------------------------------------------------------------------- */ static int ConsoleInputProc( | | | 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 |
* Side effects:
* Reads input from the actual channel.
*
*----------------------------------------------------------------------
*/
static int
ConsoleInputProc(
void *instanceData, /* Console state. */
char *bufPtr, /* Where to store data read. */
int bufSize, /* How much space is available in the
* buffer? */
int *errorCode) /* Where to store error code. */
{
ConsoleChannelInfo *chanInfoPtr = (ConsoleChannelInfo *)instanceData;
ConsoleHandleInfo *handleInfoPtr;
|
| ︙ | ︙ | |||
1224 1225 1226 1227 1228 1229 1230 | * Side effects: * Writes output on the actual channel. * *---------------------------------------------------------------------- */ static int ConsoleOutputProc( | | | 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 |
* Side effects:
* Writes output on the actual channel.
*
*----------------------------------------------------------------------
*/
static int
ConsoleOutputProc(
void *instanceData, /* Console state. */
const char *buf, /* The data buffer. */
int toWrite, /* How many bytes to write? */
int *errorCode) /* Where to store error code. */
{
ConsoleChannelInfo *chanInfoPtr = (ConsoleChannelInfo *)instanceData;
ConsoleHandleInfo *handleInfoPtr;
Tcl_Size numWritten;
|
| ︙ | ︙ | |||
1464 1465 1466 1467 1468 1469 1470 | * None. * *---------------------------------------------------------------------- */ static void ConsoleWatchProc( | | | < | 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 |
* None.
*
*----------------------------------------------------------------------
*/
static void
ConsoleWatchProc(
void *instanceData, /* Console state. */
int newMask) /* What events to watch for, one of
* of TCL_READABLE, TCL_WRITABLE */
{
ConsoleChannelInfo **nextPtrPtr, *ptr;
ConsoleChannelInfo *chanInfoPtr = (ConsoleChannelInfo *)instanceData;
int oldMask = chanInfoPtr->watchMask;
/*
* Since most of the work is handled by the background threads, we just
|
| ︙ | ︙ | |||
1540 1541 1542 1543 1544 1545 1546 | * None. * *---------------------------------------------------------------------- */ static int ConsoleGetHandleProc( | | | | | 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 |
* None.
*
*----------------------------------------------------------------------
*/
static int
ConsoleGetHandleProc(
void *instanceData, /* The console state. */
TCL_UNUSED(int), /* Direction */
void **handlePtr) /* Where to store the handle. */
{
ConsoleChannelInfo *chanInfoPtr = (ConsoleChannelInfo *)instanceData;
if (chanInfoPtr->handle == INVALID_HANDLE_VALUE) {
return TCL_ERROR;
} else {
*handlePtr = chanInfoPtr->handle;
|
| ︙ | ︙ | |||
1569 1570 1571 1572 1573 1574 1575 1576 | * Returns 1 if the input queue has data, -1 on error else 0 if empty. * * Side effects: * None. * *------------------------------------------------------------------------ */ static int | > | > | 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 |
* Returns 1 if the input queue has data, -1 on error else 0 if empty.
*
* Side effects:
* None.
*
*------------------------------------------------------------------------
*/
static int
ConsoleDataAvailable(
HANDLE consoleHandle)
{
INPUT_RECORD input[10];
DWORD count;
DWORD i;
/*
* Need at least one keyboard event.
|
| ︙ | ︙ | |||
1664 1665 1666 1667 1668 1669 1670 |
if (inputLen > 0) {
/* Private buffer has data. Copy it over. */
Tcl_Size nStored;
assert((inputLen - inputOffset) > 0);
nStored = RingBufferIn(&handleInfoPtr->buffer,
| | < < | 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 |
if (inputLen > 0) {
/* Private buffer has data. Copy it over. */
Tcl_Size nStored;
assert((inputLen - inputOffset) > 0);
nStored = RingBufferIn(&handleInfoPtr->buffer,
inputOffset + inputChars, inputLen - inputOffset, 1);
inputOffset += nStored;
if (inputOffset == inputLen) {
/* Temp buffer now empty */
inputOffset = 0;
inputLen = 0;
}
} else {
|
| ︙ | ︙ | |||
1717 1718 1719 1720 1721 1722 1723 | * Both shared buffer and private buffer are empty. Need to go get * data from console but do not want to read ahead because the * interp thread might change the read mode, e.g. turning off echo * for password input. So only do so if at least one interpreter has * requested data. */ if ((handleInfoPtr->flags & CONSOLE_DATA_AWAITED) | | | < | | 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 |
* Both shared buffer and private buffer are empty. Need to go get
* data from console but do not want to read ahead because the
* interp thread might change the read mode, e.g. turning off echo
* for password input. So only do so if at least one interpreter has
* requested data.
*/
if ((handleInfoPtr->flags & CONSOLE_DATA_AWAITED)
&& ConsoleDataAvailable(handleInfoPtr->console)) {
DWORD error;
/* Do not hold the lock while blocked in console */
ReleaseSRWLockExclusive(&handleInfoPtr->lock);
/*
* Note - the temporary buffer serves two purposes. It
*/
error = ReadConsoleChars(handleInfoPtr->console,
(WCHAR *)inputChars, sizeof(inputChars) / sizeof(WCHAR),
&inputLen);
AcquireSRWLockExclusive(&handleInfoPtr->lock);
if (error == 0) {
inputLen *= sizeof(WCHAR);
} else {
/*
* We only store the last error. It is up to channel
* handlers whether to close or not in case of errors.
|
| ︙ | ︙ | |||
1753 1754 1755 1756 1757 1758 1759 | * poll since ReadConsole does not support async operation. * So sleep for a short while and loop back to retry. */ DWORD sleepTime; sleepTime = handleInfoPtr->flags & CONSOLE_DATA_AWAITED ? 50 : INFINITE; SleepConditionVariableSRW(&handleInfoPtr->consoleThreadCV, | | < < | 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 |
* poll since ReadConsole does not support async operation.
* So sleep for a short while and loop back to retry.
*/
DWORD sleepTime;
sleepTime =
handleInfoPtr->flags & CONSOLE_DATA_AWAITED ? 50 : INFINITE;
SleepConditionVariableSRW(&handleInfoPtr->consoleThreadCV,
&handleInfoPtr->lock, sleepTime, 0);
}
/* Loop again to check for exit or wait for readers to wake us */
}
/*
* Exiting:
|
| ︙ | ︙ | |||
1784 1785 1786 1787 1788 1789 1790 |
}
ReleaseSRWLockExclusive(&gConsoleLock);
/* No need for relocking - no other thread should have access to it now */
RingBufferClear(&handleInfoPtr->buffer);
if (handleInfoPtr->console != INVALID_HANDLE_VALUE
| | | 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 |
}
ReleaseSRWLockExclusive(&gConsoleLock);
/* No need for relocking - no other thread should have access to it now */
RingBufferClear(&handleInfoPtr->buffer);
if (handleInfoPtr->console != INVALID_HANDLE_VALUE
&& handleInfoPtr->lastError != ERROR_INVALID_HANDLE) {
SetConsoleMode(handleInfoPtr->console, handleInfoPtr->initMode);
/*
* NOTE: we do not call CloseHandle(handleInfoPtr->console) here.
* As per the GetStdHandle documentation, it need not be closed.
* Other components may be directly using it. Note however that
* an explicit chan close script command does close the handle
* for all threads.
|
| ︙ | ︙ | |||
1816 1817 1818 1819 1820 1821 1822 1823 | * Always returns 0. * * Side effects: * Signals the main thread when an output operation is completed. * *---------------------------------------------------------------------- */ static DWORD WINAPI | > | > | 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 |
* Always returns 0.
*
* Side effects:
* Signals the main thread when an output operation is completed.
*
*----------------------------------------------------------------------
*/
static DWORD WINAPI
ConsoleWriterThread(
LPVOID arg)
{
ConsoleHandleInfo *handleInfoPtr = (ConsoleHandleInfo *) arg;
ConsoleHandleInfo **iterator;
BOOL success;
Tcl_Size numBytes;
/*
* This buffer size has no relation really with the size of the shared
|
| ︙ | ︙ | |||
1870 1871 1872 1873 1874 1875 1876 | * and no buffered output. */ break; } /* Wake up any threads waiting synchronously. */ WakeConditionVariable(&handleInfoPtr->interpThreadCV); success = SleepConditionVariableSRW(&handleInfoPtr->consoleThreadCV, | | < < | 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 |
* and no buffered output.
*/
break;
}
/* Wake up any threads waiting synchronously. */
WakeConditionVariable(&handleInfoPtr->interpThreadCV);
success = SleepConditionVariableSRW(&handleInfoPtr->consoleThreadCV,
&handleInfoPtr->lock, INFINITE, 0);
/* Note: lock has been acquired again! */
if (!success && GetLastError() != ERROR_TIMEOUT) {
/* TODO - what can be done? Should not happen */
/* For now keep going */
}
continue;
}
|
| ︙ | ︙ | |||
1894 1895 1896 1897 1898 1899 1900 |
consoleHandle = handleInfoPtr->console;
WakeConditionVariable(&handleInfoPtr->interpThreadCV);
ReleaseSRWLockExclusive(&handleInfoPtr->lock);
offset = 0;
while (numBytes > 0) {
Tcl_Size numWChars = numBytes / sizeof(WCHAR);
| < | | | < | 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 |
consoleHandle = handleInfoPtr->console;
WakeConditionVariable(&handleInfoPtr->interpThreadCV);
ReleaseSRWLockExclusive(&handleInfoPtr->lock);
offset = 0;
while (numBytes > 0) {
Tcl_Size numWChars = numBytes / sizeof(WCHAR);
DWORD status = WriteConsoleChars(handleInfoPtr->console,
(WCHAR *)(offset + buffer), numWChars, &numWChars);
if (status != 0) {
/* Only overwrite if no previous error */
if (handleInfoPtr->lastError == 0) {
handleInfoPtr->lastError = status;
}
if (status == ERROR_INVALID_HANDLE) {
handleInfoPtr->console = INVALID_HANDLE_VALUE;
|
| ︙ | ︙ | |||
1989 1990 1991 1992 1993 1994 1995 |
AllocateConsoleHandleInfo(
HANDLE consoleHandle,
int permissions) /* TCL_READABLE or TCL_WRITABLE */
{
ConsoleHandleInfo *handleInfoPtr;
DWORD consoleMode;
| < | | | | | | | | 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 |
AllocateConsoleHandleInfo(
HANDLE consoleHandle,
int permissions) /* TCL_READABLE or TCL_WRITABLE */
{
ConsoleHandleInfo *handleInfoPtr;
DWORD consoleMode;
handleInfoPtr = (ConsoleHandleInfo *) Tcl_Alloc(sizeof(*handleInfoPtr));
memset(handleInfoPtr, 0, sizeof(*handleInfoPtr));
memset(handleInfoPtr, 0, sizeof(*handleInfoPtr));
handleInfoPtr->console = consoleHandle;
InitializeSRWLock(&handleInfoPtr->lock);
InitializeConditionVariable(&handleInfoPtr->consoleThreadCV);
InitializeConditionVariable(&handleInfoPtr->interpThreadCV);
RingBufferInit(&handleInfoPtr->buffer, CONSOLE_BUFFER_SIZE);
handleInfoPtr->lastError = 0;
handleInfoPtr->permissions = permissions;
handleInfoPtr->numRefs = 1; /* See function header */
if (permissions == TCL_READABLE) {
GetConsoleMode(consoleHandle, &handleInfoPtr->initMode);
consoleMode = handleInfoPtr->initMode;
consoleMode &= ~(ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT);
consoleMode |= ENABLE_LINE_INPUT;
SetConsoleMode(consoleHandle, consoleMode);
}
handleInfoPtr->consoleThread = CreateThread(
NULL, /* default security descriptor */
2*CONSOLE_BUFFER_SIZE, /* Stack size - gets rounded up to granularity */
permissions == TCL_READABLE ? ConsoleReaderThread : ConsoleWriterThread,
handleInfoPtr, /* Pass to thread */
0, /* Flags - no special cases */
NULL); /* Don't care about thread id */
if (handleInfoPtr->consoleThread == NULL) {
/* Note - SRWLock and condition variables do not need finalization */
RingBufferClear(&handleInfoPtr->buffer);
Tcl_Free(handleInfoPtr);
return NULL;
}
|
| ︙ | ︙ | |||
2053 2054 2055 2056 2057 2058 2059 | * * Side effects: * None. * *------------------------------------------------------------------------ */ static ConsoleHandleInfo * | > | | > | 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 |
*
* Side effects:
* None.
*
*------------------------------------------------------------------------
*/
static ConsoleHandleInfo *
FindConsoleInfo(
const ConsoleChannelInfo *chanInfoPtr)
{
ConsoleHandleInfo *handleInfoPtr;
for (handleInfoPtr = gConsoleHandleInfoList; handleInfoPtr;
handleInfoPtr = handleInfoPtr->nextPtr) {
if (handleInfoPtr->console == chanInfoPtr->handle) {
return handleInfoPtr;
}
}
return NULL;
}
|
| ︙ | ︙ | |||
2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 |
* Returns the new channel, or NULL.
*
* Side effects:
* May open the channel.
*
*----------------------------------------------------------------------
*/
Tcl_Channel
TclWinOpenConsoleChannel(
HANDLE handle,
char *channelName,
int permissions)
{
ConsoleChannelInfo *chanInfoPtr;
| > | 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 |
* Returns the new channel, or NULL.
*
* Side effects:
* May open the channel.
*
*----------------------------------------------------------------------
*/
Tcl_Channel
TclWinOpenConsoleChannel(
HANDLE handle,
char *channelName,
int permissions)
{
ConsoleChannelInfo *chanInfoPtr;
|
| ︙ | ︙ | |||
2112 2113 2114 2115 2116 2117 2118 |
/*
* Use the pointer for the name of the result channel. This keeps the
* channel names unique, since some may share handles (stdin/stdout/stderr
* for instance).
*/
| | > | 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 |
/*
* Use the pointer for the name of the result channel. This keeps the
* channel names unique, since some may share handles (stdin/stdout/stderr
* for instance).
*/
snprintf(channelName, 16 + TCL_INTEGER_SPACE, "file%" TCL_Z_MODIFIER "x",
(size_t) chanInfoPtr);
if (permissions & TCL_READABLE) {
/*
* Make sure the console input buffer is ready for only character
* input notifications and the buffer is set for line buffering. IOW,
* we only want to catch when complete lines are ready for reading.
*/
|
| ︙ | ︙ | |||
2243 2244 2245 2246 2247 2248 2249 | * May modify an option on a console. Sets Error message if needed (by * calling Tcl_BadChannelOption). * *---------------------------------------------------------------------- */ static int ConsoleSetOptionProc( | | | 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 |
* May modify an option on a console. Sets Error message if needed (by
* calling Tcl_BadChannelOption).
*
*----------------------------------------------------------------------
*/
static int
ConsoleSetOptionProc(
void *instanceData, /* File state. */
Tcl_Interp *interp, /* For error reporting - can be NULL. */
const char *optionName, /* Which option to set? */
const char *value) /* New value for option. */
{
ConsoleChannelInfo *chanInfoPtr = (ConsoleChannelInfo *)instanceData;
int len = strlen(optionName);
int vlen = strlen(value);
|
| ︙ | ︙ | |||
2332 2333 2334 2335 2336 2337 2338 | * (by calling Tcl_BadChannelOption). * *---------------------------------------------------------------------- */ static int ConsoleGetOptionProc( | | | 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 |
* (by calling Tcl_BadChannelOption).
*
*----------------------------------------------------------------------
*/
static int
ConsoleGetOptionProc(
void *instanceData, /* File state. */
Tcl_Interp *interp, /* For error reporting - can be NULL. */
const char *optionName, /* Option to get. */
Tcl_DString *dsPtr) /* Where to store value(s). */
{
ConsoleChannelInfo *chanInfoPtr = (ConsoleChannelInfo *)instanceData;
int valid = 0; /* Flag if valid option parsed. */
unsigned int len;
|
| ︙ | ︙ |
Changes to win/tclWinDde.c.
| ︙ | ︙ | |||
306 307 308 309 310 311 312 |
*
*----------------------------------------------------------------------
*/
static const WCHAR *
DdeSetServerName(
Tcl_Interp *interp,
| | | | 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 |
*
*----------------------------------------------------------------------
*/
static const WCHAR *
DdeSetServerName(
Tcl_Interp *interp,
const WCHAR *name, /* The name that will be used to refer to the
* interpreter in later "send" commands. Must
* be globally unique. */
int flags, /* DDE_FLAG_FORCE or 0 */
Tcl_Obj *handlerPtr) /* Name of the optional proc/command to handle
* incoming Dde eval's */
{
int suffix;
RegisteredInterp *riPtr, *prevPtr;
Tcl_DString dString;
const WCHAR *actualName;
|
| ︙ | ︙ | |||
511 512 513 514 515 516 517 | * The interpreter given by riPtr is unregistered. * *---------------------------------------------------------------------- */ static void DeleteProc( | | | 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 |
* The interpreter given by riPtr is unregistered.
*
*----------------------------------------------------------------------
*/
static void
DeleteProc(
void *clientData) /* The interp we are deleting. */
{
RegisteredInterp *riPtr = (RegisteredInterp *) clientData;
RegisteredInterp *searchPtr, *prevPtr;
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
for (searchPtr = tsdPtr->interpListPtr, prevPtr = NULL;
(searchPtr != NULL) && (searchPtr != riPtr);
|
| ︙ | ︙ | |||
1252 1253 1254 1255 1256 1257 1258 | * The interp's result object is changed. * *---------------------------------------------------------------------- */ static void SetDdeError( | | | 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 |
* The interp's result object is changed.
*
*----------------------------------------------------------------------
*/
static void
SetDdeError(
Tcl_Interp *interp) /* The interp to put the message in. */
{
const char *errorMessage, *errorCode;
switch (DdeGetLastError(ddeInstance)) {
case DMLERR_DATAACKTIMEOUT:
case DMLERR_EXECACKTIMEOUT:
case DMLERR_POKEACKTIMEOUT:
|
| ︙ | ︙ | |||
1299 1300 1301 1302 1303 1304 1305 | * See the user documentation. * *---------------------------------------------------------------------- */ static int DdeObjCmd( | | | | 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 |
* See the user documentation.
*
*----------------------------------------------------------------------
*/
static int
DdeObjCmd(
void *dummy, /* Not used. */
Tcl_Interp *interp, /* The interp we are sending from */
Tcl_Size objc, /* Number of arguments */
Tcl_Obj *const *objv) /* The arguments */
{
static const char *const ddeCommands[] = {
"servername", "execute", "poke", "request", "services", "eval", NULL};
enum DdeSubcommands {
DDE_SERVERNAME, DDE_EXECUTE, DDE_POKE, DDE_REQUEST, DDE_SERVICES,
DDE_EVAL
|
| ︙ | ︙ | |||
1584 1585 1586 1587 1588 1589 1590 |
}
ddeData = DdeCreateDataHandle(ddeInstance, (BYTE *) dataString,
(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,
| | > | > | 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 |
}
ddeData = DdeCreateDataHandle(ddeInstance, (BYTE *) dataString,
(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);
DdeAbandonTransaction(ddeInstance, hConv, ddeResult);
} else {
ddeReturn = DdeClientTransaction((LPBYTE) ddeData, 0xFFFFFFFF,
hConv, 0, (flags & DDE_FLAG_BINARY) ? CF_TEXT : CF_UNICODETEXT,
XTYP_EXECUTE, 30000, NULL);
if (ddeReturn == 0) {
SetDdeError(interp);
result = TCL_ERROR;
}
}
DdeFreeDataHandle(ddeData);
} else {
|
| ︙ | ︙ | |||
1631 1632 1633 1634 1635 1636 1637 |
result = TCL_ERROR;
} else {
Tcl_Obj *returnObjPtr;
ddeItem = DdeCreateStringHandleW(ddeInstance, itemString,
CP_WINUNICODE);
if (ddeItem != NULL) {
ddeData = DdeClientTransaction(NULL, 0, hConv, ddeItem,
| | > | 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 |
result = TCL_ERROR;
} else {
Tcl_Obj *returnObjPtr;
ddeItem = DdeCreateStringHandleW(ddeInstance, itemString,
CP_WINUNICODE);
if (ddeItem != NULL) {
ddeData = DdeClientTransaction(NULL, 0, hConv, ddeItem,
(flags & DDE_FLAG_BINARY) ? CF_TEXT : CF_UNICODETEXT,
XTYP_REQUEST, 5000, NULL);
if (ddeData == NULL) {
SetDdeError(interp);
result = TCL_ERROR;
} else {
DWORD tmp;
WCHAR *dataString = (WCHAR *) DdeAccessData(ddeData, &tmp);
|
| ︙ | ︙ | |||
1709 1710 1711 1712 1713 1714 1715 |
SetDdeError(interp);
result = TCL_ERROR;
} else {
ddeItem = DdeCreateStringHandleW(ddeInstance, itemString,
CP_WINUNICODE);
if (ddeItem != NULL) {
ddeData = DdeClientTransaction(dataString, (DWORD) length,
| | > | 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 |
SetDdeError(interp);
result = TCL_ERROR;
} else {
ddeItem = DdeCreateStringHandleW(ddeInstance, itemString,
CP_WINUNICODE);
if (ddeItem != NULL) {
ddeData = DdeClientTransaction(dataString, (DWORD) length,
hConv, ddeItem, (flags & DDE_FLAG_BINARY) ? CF_TEXT : CF_UNICODETEXT,
XTYP_POKE, 5000, NULL);
if (ddeData == NULL) {
SetDdeError(interp);
result = TCL_ERROR;
}
} else {
SetDdeError(interp);
result = TCL_ERROR;
|
| ︙ | ︙ |
Changes to win/tclWinInit.c.
| ︙ | ︙ | |||
566 567 568 569 570 571 572 |
*----------------------------------------------------------------------
*/
Tcl_Size
TclpFindVariable(
const char *name, /* Name of desired environment variable
* (UTF-8). */
| | | 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 |
*----------------------------------------------------------------------
*/
Tcl_Size
TclpFindVariable(
const char *name, /* Name of desired environment variable
* (UTF-8). */
Tcl_Size *lengthPtr) /* Used to return length of name (for
* successful searches) or number of non-NULL
* entries in environ (for unsuccessful
* searches). */
{
Tcl_Size i, length, result = -1;
const WCHAR *env;
const char *p1, *p2;
|
| ︙ | ︙ |
Changes to win/tclWinInt.h.
| ︙ | ︙ | |||
70 71 72 73 74 75 76 |
typedef struct TclPipeThreadInfo {
HANDLE evControl; /* Auto-reset event used by the main thread to
* signal when the pipe thread should attempt
* to do read/write operation. Additionally
* used as signal to stop (state set to -1) */
volatile LONG state; /* Indicates current state of the thread */
| | | 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
typedef struct TclPipeThreadInfo {
HANDLE evControl; /* Auto-reset event used by the main thread to
* signal when the pipe thread should attempt
* to do read/write operation. Additionally
* used as signal to stop (state set to -1) */
volatile LONG state; /* Indicates current state of the thread */
void *clientData; /* Referenced data of the main thread */
HANDLE evWakeUp; /* Optional wake-up event worker set by shutdown */
} TclPipeThreadInfo;
/* If pipe-workers will use some tcl subsystem, we can use Tcl_Alloc without
* more overhead for finalize thread (should be executed anyway)
*
|
| ︙ | ︙ |
Changes to win/tclWinNotify.c.
| ︙ | ︙ | |||
144 145 146 147 148 149 150 | * May dispose of the notifier window and class. * *---------------------------------------------------------------------- */ void TclpFinalizeNotifier( | | | 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
* May dispose of the notifier window and class.
*
*----------------------------------------------------------------------
*/
void
TclpFinalizeNotifier(
void *clientData) /* Pointer to notifier data. */
{
ThreadSpecificData *tsdPtr = (ThreadSpecificData *) clientData;
/*
* Only finalize the notifier if a notifier was installed in the current
* thread; there is a route in which this is not guaranteed to be true
* (when tclWin32Dll.c:DllMain() is called with the flag
|
| ︙ | ︙ | |||
214 215 216 217 218 219 220 | * isn't already one pending. * *---------------------------------------------------------------------- */ void TclpAlertNotifier( | | | 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 |
* isn't already one pending.
*
*----------------------------------------------------------------------
*/
void
TclpAlertNotifier(
void *clientData) /* Pointer to thread data. */
{
ThreadSpecificData *tsdPtr = (ThreadSpecificData *) clientData;
/*
* Note that we do not need to lock around access to the hwnd because the
* race condition has no effect since any race condition implies that the
* notifier thread is already awake.
|
| ︙ | ︙ | |||
260 261 262 263 264 265 266 | * Replaces any previous timer. * *---------------------------------------------------------------------- */ void TclpSetTimer( | | | 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 |
* Replaces any previous timer.
*
*----------------------------------------------------------------------
*/
void
TclpSetTimer(
const Tcl_Time *timePtr) /* Maximum block time, or NULL. */
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
UINT timeout;
/*
* We only need to set up an interval timer if we're being called from an
* external event loop. If we don't have a window handle then we just
|
| ︙ | ︙ | |||
366 367 368 369 370 371 372 |
*----------------------------------------------------------------------
*/
int
TclAsyncNotifier(
TCL_UNUSED(int), /* Signal number. */
TCL_UNUSED(Tcl_ThreadId), /* Target thread. */
| | | | 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 |
*----------------------------------------------------------------------
*/
int
TclAsyncNotifier(
TCL_UNUSED(int), /* Signal number. */
TCL_UNUSED(Tcl_ThreadId), /* Target thread. */
TCL_UNUSED(void *), /* Notifier data. */
TCL_UNUSED(int *), /* Flag to mark. */
TCL_UNUSED(int)) /* Value of mark. */
{
return 0;
}
/*
*----------------------------------------------------------------------
*
|
| ︙ | ︙ | |||
460 461 462 463 464 465 466 | * Dispatches a message to a window procedure, which could do anything. * *---------------------------------------------------------------------- */ int TclpWaitForEvent( | | | 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 |
* Dispatches a message to a window procedure, which could do anything.
*
*----------------------------------------------------------------------
*/
int
TclpWaitForEvent(
const Tcl_Time *timePtr) /* Maximum block time, or NULL. */
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
MSG msg;
DWORD timeout, result;
int status;
/*
|
| ︙ | ︙ |
Changes to win/tclWinPipe.c.
| ︙ | ︙ | |||
1954 1955 1956 1957 1958 1959 1960 | * Sets the device into blocking or non-blocking mode. * *---------------------------------------------------------------------- */ static int PipeBlockModeProc( | | | 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 |
* Sets the device into blocking or non-blocking mode.
*
*----------------------------------------------------------------------
*/
static int
PipeBlockModeProc(
void *instanceData, /* Instance data for channel. */
int mode) /* TCL_MODE_BLOCKING or
* TCL_MODE_NONBLOCKING. */
{
PipeInfo *infoPtr = (PipeInfo *) instanceData;
/*
* Pipes on Windows can not be switched between blocking and nonblocking,
|
| ︙ | ︙ | |||
1993 1994 1995 1996 1997 1998 1999 | * Closes the physical channel. * *---------------------------------------------------------------------- */ static int PipeClose2Proc( | | | 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 |
* Closes the physical channel.
*
*----------------------------------------------------------------------
*/
static int
PipeClose2Proc(
void *instanceData, /* Pointer to PipeInfo structure. */
Tcl_Interp *interp, /* For error reporting. */
int flags) /* Flags that indicate which side to close. */
{
PipeInfo *pipePtr = (PipeInfo *) instanceData;
Tcl_Channel errChan;
int errorCode, result;
PipeInfo *infoPtr, **nextPtrPtr;
|
| ︙ | ︙ | |||
2165 2166 2167 2168 2169 2170 2171 | * Reads input from the actual channel. * *---------------------------------------------------------------------- */ static int PipeInputProc( | | | 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 |
* Reads input from the actual channel.
*
*----------------------------------------------------------------------
*/
static int
PipeInputProc(
void *instanceData, /* Pipe state. */
char *buf, /* Where to store data read. */
int bufSize, /* How much space is available in the
* buffer? */
int *errorCode) /* Where to store error code. */
{
PipeInfo *infoPtr = (PipeInfo *) instanceData;
WinFile *filePtr = (WinFile*) infoPtr->readFile;
|
| ︙ | ︙ | |||
2259 2260 2261 2262 2263 2264 2265 | * Writes output on the actual channel. * *---------------------------------------------------------------------- */ static int PipeOutputProc( | | | 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 |
* Writes output on the actual channel.
*
*----------------------------------------------------------------------
*/
static int
PipeOutputProc(
void *instanceData, /* Pipe state. */
const char *buf, /* The data buffer. */
int toWrite, /* How many bytes to write? */
int *errorCode) /* Where to store error code. */
{
PipeInfo *infoPtr = (PipeInfo *) instanceData;
WinFile *filePtr = (WinFile*) infoPtr->writeFile;
DWORD bytesWritten, timeout;
|
| ︙ | ︙ | |||
2441 2442 2443 2444 2445 2446 2447 | * None. * *---------------------------------------------------------------------- */ static void PipeWatchProc( | | | 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 |
* None.
*
*----------------------------------------------------------------------
*/
static void
PipeWatchProc(
void *instanceData, /* Pipe state. */
int mask) /* What events to watch for, OR-ed combination
* of TCL_READABLE, TCL_WRITABLE and
* TCL_EXCEPTION. */
{
PipeInfo **nextPtrPtr, *ptr;
PipeInfo *infoPtr = (PipeInfo *) instanceData;
int oldMask = infoPtr->watchMask;
|
| ︙ | ︙ | |||
2503 2504 2505 2506 2507 2508 2509 | * None. * *---------------------------------------------------------------------- */ static int PipeGetHandleProc( | | | | 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 |
* None.
*
*----------------------------------------------------------------------
*/
static int
PipeGetHandleProc(
void *instanceData, /* The pipe state. */
int direction, /* TCL_READABLE or TCL_WRITABLE */
void **handlePtr) /* Where to store the handle. */
{
PipeInfo *infoPtr = (PipeInfo *) instanceData;
WinFile *filePtr;
if (direction == TCL_READABLE && infoPtr->readFile) {
filePtr = (WinFile*) infoPtr->readFile;
*handlePtr = (void *) filePtr->handle;
|
| ︙ | ︙ |
Changes to win/tclWinReg.c.
| ︙ | ︙ | |||
289 290 291 292 293 294 295 | * None. * *---------------------------------------------------------------------- */ static int RegistryObjCmd( | | | | 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 |
* None.
*
*----------------------------------------------------------------------
*/
static int
RegistryObjCmd(
void *dummy, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
Tcl_Size objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument values. */
{
Tcl_Size n = 1, argc;
int index;
REGSAM mode = 0;
const char *errString = NULL;
|
| ︙ | ︙ | |||
1426 1427 1428 1429 1430 1431 1432 |
*
*----------------------------------------------------------------------
*/
static int
BroadcastValue(
Tcl_Interp *interp, /* Current interpreter. */
| | | 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 |
*
*----------------------------------------------------------------------
*/
static int
BroadcastValue(
Tcl_Interp *interp, /* Current interpreter. */
Tcl_Size objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument values. */
{
LRESULT result;
DWORD_PTR sendResult;
int timeout = 3000;
Tcl_Size len;
const char *str;
|
| ︙ | ︙ |
Changes to win/tclWinSerial.c.
| ︙ | ︙ | |||
557 558 559 560 561 562 563 | * Sets the device into blocking or non-blocking mode. * *---------------------------------------------------------------------- */ static int SerialBlockProc( | | | 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 |
* Sets the device into blocking or non-blocking mode.
*
*----------------------------------------------------------------------
*/
static int
SerialBlockProc(
void *instanceData, /* Instance data for channel. */
int mode) /* TCL_MODE_BLOCKING or
* TCL_MODE_NONBLOCKING. */
{
int errorCode = 0;
SerialInfo *infoPtr = (SerialInfo *) instanceData;
/*
|
| ︙ | ︙ | |||
596 597 598 599 600 601 602 | * Closes the physical channel. * *---------------------------------------------------------------------- */ static int SerialCloseProc( | | | 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 |
* Closes the physical channel.
*
*----------------------------------------------------------------------
*/
static int
SerialCloseProc(
void *instanceData, /* Pointer to SerialInfo structure. */
TCL_UNUSED(Tcl_Interp *),
int flags)
{
SerialInfo *serialPtr = (SerialInfo *) instanceData;
int errorCode = 0, result = 0;
SerialInfo *infoPtr, **nextPtrPtr;
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
|
| ︙ | ︙ | |||
851 852 853 854 855 856 857 | * Reads input from the actual channel. * *---------------------------------------------------------------------- */ static int SerialInputProc( | | | 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 |
* Reads input from the actual channel.
*
*----------------------------------------------------------------------
*/
static int
SerialInputProc(
void *instanceData, /* Serial state. */
char *buf, /* Where to store data read. */
int bufSize, /* How much space is available in the
* buffer? */
int *errorCode) /* Where to store error code. */
{
SerialInfo *infoPtr = (SerialInfo *) instanceData;
DWORD bytesRead = 0;
|
| ︙ | ︙ | |||
958 959 960 961 962 963 964 | * Writes output on the actual channel. * *---------------------------------------------------------------------- */ static int SerialOutputProc( | | | 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 |
* Writes output on the actual channel.
*
*----------------------------------------------------------------------
*/
static int
SerialOutputProc(
void *instanceData, /* Serial state. */
const char *buf, /* The data buffer. */
int toWrite, /* How many bytes to write? */
int *errorCode) /* Where to store error code. */
{
SerialInfo *infoPtr = (SerialInfo *) instanceData;
DWORD bytesWritten, timeout;
|
| ︙ | ︙ | |||
1188 1189 1190 1191 1192 1193 1194 | * None. * *---------------------------------------------------------------------- */ static void SerialWatchProc( | | | 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 |
* None.
*
*----------------------------------------------------------------------
*/
static void
SerialWatchProc(
void *instanceData, /* Serial state. */
int mask) /* What events to watch for, OR-ed combination
* of TCL_READABLE, TCL_WRITABLE and
* TCL_EXCEPTION. */
{
SerialInfo **nextPtrPtr, *ptr;
SerialInfo *infoPtr = (SerialInfo *) instanceData;
int oldMask = infoPtr->watchMask;
|
| ︙ | ︙ | |||
1245 1246 1247 1248 1249 1250 1251 | * None. * *---------------------------------------------------------------------- */ static int SerialGetHandleProc( | | | | | 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 |
* None.
*
*----------------------------------------------------------------------
*/
static int
SerialGetHandleProc(
void *instanceData, /* The serial state. */
TCL_UNUSED(int), /* Direction. */
void **handlePtr) /* Where to store the handle. */
{
SerialInfo *infoPtr = (SerialInfo *) instanceData;
*handlePtr = (void *) infoPtr->handle;
return TCL_OK;
}
|
| ︙ | ︙ | |||
1609 1610 1611 1612 1613 1614 1615 | * May modify an option on a device. * *---------------------------------------------------------------------- */ static int SerialSetOptionProc( | | | 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 |
* May modify an option on a device.
*
*----------------------------------------------------------------------
*/
static int
SerialSetOptionProc(
void *instanceData, /* File state. */
Tcl_Interp *interp, /* For error reporting - can be NULL. */
const char *optionName, /* Which option to set? */
const char *value) /* New value for option. */
{
SerialInfo *infoPtr;
DCB dcb;
BOOL result, flag;
|
| ︙ | ︙ | |||
2033 2034 2035 2036 2037 2038 2039 | * reused at any time subsequent to the call. * *---------------------------------------------------------------------- */ static int SerialGetOptionProc( | | | 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 |
* reused at any time subsequent to the call.
*
*----------------------------------------------------------------------
*/
static int
SerialGetOptionProc(
void *instanceData, /* File state. */
Tcl_Interp *interp, /* For error reporting - can be NULL. */
const char *optionName, /* Option to get. */
Tcl_DString *dsPtr) /* Where to store value(s). */
{
SerialInfo *infoPtr;
DCB dcb;
size_t len;
|
| ︙ | ︙ |
Changes to win/tclWinSock.c.
| ︙ | ︙ | |||
559 560 561 562 563 564 565 | * Sets the device into blocking or nonblocking mode. * *---------------------------------------------------------------------- */ static int TcpBlockModeProc( | | | 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 |
* Sets the device into blocking or nonblocking mode.
*
*----------------------------------------------------------------------
*/
static int
TcpBlockModeProc(
void *instanceData, /* Socket state. */
int mode) /* The mode to set. Can be one of
* TCL_MODE_BLOCKING or
* TCL_MODE_NONBLOCKING. */
{
TcpState *statePtr = (TcpState *)instanceData;
if (mode == TCL_MODE_NONBLOCKING) {
|
| ︙ | ︙ | |||
790 791 792 793 794 795 796 | * Reads input from the input device of the channel. * *---------------------------------------------------------------------- */ static int TcpInputProc( | | | 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 |
* Reads input from the input device of the channel.
*
*----------------------------------------------------------------------
*/
static int
TcpInputProc(
void *instanceData, /* Socket state. */
char *buf, /* Where to store data read. */
int bufSize, /* How much space is available in the
* buffer? */
int *errorCodePtr) /* Where to store error code. */
{
TcpState *statePtr = (TcpState *)instanceData;
int bytesRead;
|
| ︙ | ︙ | |||
923 924 925 926 927 928 929 | * Produces output on the socket. * *---------------------------------------------------------------------- */ static int TcpOutputProc( | | | 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 |
* Produces output on the socket.
*
*----------------------------------------------------------------------
*/
static int
TcpOutputProc(
void *instanceData, /* Socket state. */
const char *buf, /* The data buffer. */
int toWrite, /* How many bytes to write? */
int *errorCodePtr) /* Where to store error code. */
{
TcpState *statePtr = (TcpState *)instanceData;
int written;
DWORD error;
|
| ︙ | ︙ | |||
1027 1028 1029 1030 1031 1032 1033 | * Closes the socket. * *---------------------------------------------------------------------- */ static int TcpCloseProc( | | | 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 |
* Closes the socket.
*
*----------------------------------------------------------------------
*/
static int
TcpCloseProc(
void *instanceData, /* The socket to close. */
TCL_UNUSED(Tcl_Interp *))
{
TcpState *statePtr = (TcpState *)instanceData;
/* TIP #218 */
int errorCode = 0;
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
|
| ︙ | ︙ | |||
1113 1114 1115 1116 1117 1118 1119 | * Shuts down one side of the socket. * *---------------------------------------------------------------------- */ static int TcpClose2Proc( | | | 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 |
* Shuts down one side of the socket.
*
*----------------------------------------------------------------------
*/
static int
TcpClose2Proc(
void *instanceData, /* The socket to close. */
Tcl_Interp *interp, /* For error reporting. */
int flags) /* Flags that indicate which side to close. */
{
TcpState *statePtr = (TcpState *)instanceData;
int readError = 0;
int writeError = 0;
|
| ︙ | ︙ | |||
1163 1164 1165 1166 1167 1168 1169 | * Changes attributes of the socket at the system level. * *---------------------------------------------------------------------- */ static int TcpSetOptionProc( | | | 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 |
* Changes attributes of the socket at the system level.
*
*----------------------------------------------------------------------
*/
static int
TcpSetOptionProc(
void *instanceData, /* Socket state. */
Tcl_Interp *interp, /* For error reporting - can be NULL. */
const char *optionName, /* Name of the option to set. */
const char *value) /* New value for option. */
{
TcpState *statePtr = (TcpState *)instanceData;
SOCKET sock;
size_t len = 0;
|
| ︙ | ︙ | |||
1246 1247 1248 1249 1250 1251 1252 | * None. * *---------------------------------------------------------------------- */ static int TcpGetOptionProc( | | | 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 |
* None.
*
*----------------------------------------------------------------------
*/
static int
TcpGetOptionProc(
void *instanceData, /* Socket state. */
Tcl_Interp *interp, /* For error reporting - can be NULL. */
const char *optionName, /* Name of the option to retrieve the value
* for, or NULL to get all options and their
* values. */
Tcl_DString *dsPtr) /* Where to store the computed value;
* initialized by caller. */
{
|
| ︙ | ︙ | |||
1542 1543 1544 1545 1546 1547 1548 | * already true. * *---------------------------------------------------------------------- */ static void TcpWatchProc( | | | 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 |
* already true.
*
*----------------------------------------------------------------------
*/
static void
TcpWatchProc(
void *instanceData, /* The socket state. */
int mask) /* Events of interest; an OR-ed combination of
* TCL_READABLE, TCL_WRITABLE and
* TCL_EXCEPTION. */
{
TcpState *statePtr = (TcpState *)instanceData;
/*
|
| ︙ | ︙ | |||
1596 1597 1598 1599 1600 1601 1602 | * None. * *---------------------------------------------------------------------- */ static int TcpGetHandleProc( | | | | | 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 |
* None.
*
*----------------------------------------------------------------------
*/
static int
TcpGetHandleProc(
void *instanceData, /* The socket state. */
TCL_UNUSED(int), /* direction */
void **handlePtr) /* Where to store the handle. */
{
TcpState *statePtr = (TcpState *)instanceData;
*handlePtr = INT2PTR(statePtr->sockets->fd);
return TCL_OK;
}
|
| ︙ | ︙ | |||
2052 2053 2054 2055 2056 2057 2058 | * None. * *---------------------------------------------------------------------- */ Tcl_Channel Tcl_MakeTcpClientChannel( | | | 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 |
* None.
*
*----------------------------------------------------------------------
*/
Tcl_Channel
Tcl_MakeTcpClientChannel(
void *sock) /* The socket to wrap up into a channel. */
{
TcpState *statePtr;
char channelName[SOCK_CHAN_LENGTH];
ThreadSpecificData *tsdPtr;
TclInitSockets();
|
| ︙ | ︙ | |||
2303 2304 2305 2306 2307 2308 2309 | * connection acceptance mechanism. * *---------------------------------------------------------------------- */ static void TcpAccept( | | | | | 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 |
* connection acceptance mechanism.
*
*----------------------------------------------------------------------
*/
static void
TcpAccept(
TcpFdList *fds, /* Server socket that accepted newSocket. */
SOCKET newSocket, /* Newly accepted socket. */
address addr) /* Address of new socket. */
{
TcpState *newInfoPtr;
TcpState *statePtr = fds->statePtr;
int len = sizeof(addr);
char channelName[SOCK_CHAN_LENGTH];
char host[NI_MAXHOST], port[NI_MAXSERV];
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
|
| ︙ | ︙ | |||
2840 2841 2842 2843 2844 2845 2846 |
*/
fds->fd = socket;
fds->statePtr = statePtr;
fds->next = NULL;
}
| < | > | 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 |
*/
fds->fd = socket;
fds->statePtr = statePtr;
fds->next = NULL;
}
/*
*----------------------------------------------------------------------
*
* NewSocketInfo --
*
* This function allocates and initializes a new TcpState structure.
*
* Results:
* Returns a newly allocated TcpState.
*
* Side effects:
* None, except for allocation of memory.
*
*----------------------------------------------------------------------
*/
static TcpState *
NewSocketInfo(
SOCKET socket)
{
TcpState *statePtr = (TcpState *)Tcl_Alloc(sizeof(TcpState));
memset(statePtr, 0, sizeof(TcpState));
/*
* TIP #218. Removed the code inserting the new structure into the global
|
| ︙ | ︙ | |||
2895 2896 2897 2898 2899 2900 2901 | * Processes socket events off the system queue. * *---------------------------------------------------------------------- */ static int WaitForSocketEvent( | | | < | 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 |
* Processes socket events off the system queue.
*
*----------------------------------------------------------------------
*/
static int
WaitForSocketEvent(
TcpState *statePtr, /* Information about this socket. */
int events, /* Events to look for. May be one of
* FD_READ or FD_WRITE. */
int *errorCodePtr) /* Where to store errors? */
{
int result = 1;
int oldMode;
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
/*
|
| ︙ | ︙ |
Changes to win/tclWinThrd.c.
| ︙ | ︙ | |||
75 76 77 78 79 80 81 |
/*
* The per-thread event and queue pointers.
*/
#if TCL_THREADS
typedef struct ThreadSpecificData {
| | | | 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
/*
* The per-thread event and queue pointers.
*/
#if TCL_THREADS
typedef struct ThreadSpecificData {
HANDLE condEvent; /* Per-thread condition event */
struct ThreadSpecificData *nextPtr; /* Queue pointers */
struct ThreadSpecificData *prevPtr;
int flags; /* See flags below */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
#endif /* TCL_THREADS */
/*
* State bits for the thread.
|
| ︙ | ︙ | |||
127 128 129 130 131 132 133 |
/*
* The per thread data passed from TclpThreadCreate
* to TclWinThreadStart.
*/
typedef struct {
| | > | | | 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
/*
* The per thread data passed from TclpThreadCreate
* to TclWinThreadStart.
*/
typedef struct {
LPTHREAD_START_ROUTINE lpStartAddress;
/* Original startup routine */
LPVOID lpParameter; /* Original startup data */
unsigned int fpControl; /* Floating point control word from the
* main thread */
} WinThread;
/*
*----------------------------------------------------------------------
*
|
| ︙ | ︙ | |||
199 200 201 202 203 204 205 |
*----------------------------------------------------------------------
*/
int
TclpThreadCreate(
Tcl_ThreadId *idPtr, /* Return, the ID of the thread. */
Tcl_ThreadCreateProc *proc, /* Main() function of the thread. */
| | | | | 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
*----------------------------------------------------------------------
*/
int
TclpThreadCreate(
Tcl_ThreadId *idPtr, /* Return, the ID of the thread. */
Tcl_ThreadCreateProc *proc, /* Main() function of the thread. */
void *clientData, /* The one argument to Main(). */
size_t stackSize, /* Size of stack for the new thread. */
int flags) /* Flags controlling behaviour of the new
* thread. */
{
WinThread *winThreadPtr; /* Per-thread startup info */
HANDLE tHandle;
winThreadPtr = (WinThread *)Tcl_Alloc(sizeof(WinThread));
winThreadPtr->lpStartAddress = (LPTHREAD_START_ROUTINE) proc;
winThreadPtr->lpParameter = clientData;
winThreadPtr->fpControl = _controlfp(0, 0);
|
| ︙ | ︙ | |||
656 657 658 659 660 661 662 |
*----------------------------------------------------------------------
*/
void
Tcl_ConditionWait(
Tcl_Condition *condPtr, /* Really (WinCondition **) */
Tcl_Mutex *mutexPtr, /* Really (CRITICAL_SECTION **) */
| | | 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 |
*----------------------------------------------------------------------
*/
void
Tcl_ConditionWait(
Tcl_Condition *condPtr, /* Really (WinCondition **) */
Tcl_Mutex *mutexPtr, /* Really (CRITICAL_SECTION **) */
const Tcl_Time *timePtr) /* Timeout on waiting period */
{
WinCondition *winCondPtr; /* Per-condition queue head */
CRITICAL_SECTION *csPtr; /* Caller's Mutex, after casting */
DWORD wtime; /* Windows time value */
int timeout; /* True if we got a timeout */
int doExit = 0; /* True if we need to do exit setup */
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
|
| ︙ | ︙ |