Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Moving variable declarations to better places |
|---|---|
| Timelines: | family | ancestors | descendants | both | c-std-update |
| Files: | files | file ages | folders |
| SHA3-256: |
f569640c350debf06ffd4d9fd68c9abd |
| User & Date: | dkf 2025-07-16 10:43:24.137 |
Context
|
2025-07-19
| ||
| 12:31 | More moving of variable declarations check-in: c149575323 user: dkf tags: c-std-update | |
|
2025-07-16
| ||
| 10:43 | Moving variable declarations to better places check-in: f569640c35 user: dkf tags: c-std-update | |
|
2025-07-15
| ||
| 15:04 | merge trunk check-in: 64fb4b537d user: dkf tags: c-std-update | |
Changes
Changes to generic/tclProc.c.
| ︙ | ︙ | |||
405 406 407 408 409 410 411 |
Tcl_Obj *argsPtr, /* Description of arguments. */
Tcl_Obj *bodyPtr, /* Command body. */
Proc **procPtrPtr) /* Returns: pointer to proc data. */
{
Interp *iPtr = (Interp *) interp;
Proc *procPtr = NULL;
| | | 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 |
Tcl_Obj *argsPtr, /* Description of arguments. */
Tcl_Obj *bodyPtr, /* Command body. */
Proc **procPtrPtr) /* Returns: pointer to proc data. */
{
Interp *iPtr = (Interp *) interp;
Proc *procPtr = NULL;
Tcl_Size numArgs;
CompiledLocal *localPtr = NULL;
Tcl_Obj **argArray;
int precompiled = 0, result;
const char *errorCode = NULL;
ProcGetInternalRep(bodyPtr, procPtr);
if (procPtr != NULL) {
|
| ︙ | ︙ | |||
506 507 508 509 510 511 512 |
}
localPtr = procPtr->firstLocalPtr;
} else {
procPtr->numArgs = numArgs;
procPtr->numCompiledLocals = numArgs;
}
| | | 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 |
}
localPtr = procPtr->firstLocalPtr;
} else {
procPtr->numArgs = numArgs;
procPtr->numCompiledLocals = numArgs;
}
for (Tcl_Size i = 0; i < numArgs; i++) {
const char *argname, *argnamei, *argnamelast;
Tcl_Size fieldCount, nameLength;
Tcl_Obj **fieldValues;
/*
* Now divide the specifier up into name and default.
*/
|
| ︙ | ︙ | |||
1075 1076 1077 1078 1079 1080 1081 |
static int
ProcWrongNumArgs(
Tcl_Interp *interp,
int skip)
{
CallFrame *framePtr = ((Interp *)interp)->varFramePtr;
Proc *procPtr = framePtr->procPtr;
| | | 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 |
static int
ProcWrongNumArgs(
Tcl_Interp *interp,
int skip)
{
CallFrame *framePtr = ((Interp *)interp)->varFramePtr;
Proc *procPtr = framePtr->procPtr;
Tcl_Size localCt = procPtr->numCompiledLocals, numArgs;
Tcl_Obj **desiredObjs;
const char *final = NULL;
/*
* Build up desired argument list for Tcl_WrongNumArgs
*/
|
| ︙ | ︙ | |||
1097 1098 1099 1100 1101 1102 1103 |
desiredObjs[0] = framePtr->objv[skip-1];
}
Tcl_IncrRefCount(desiredObjs[0]);
if (localCt > 0) {
Var *defPtr = (Var *)(&framePtr->localCachePtr->varName0 + localCt);
| | | 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 |
desiredObjs[0] = framePtr->objv[skip-1];
}
Tcl_IncrRefCount(desiredObjs[0]);
if (localCt > 0) {
Var *defPtr = (Var *)(&framePtr->localCachePtr->varName0 + localCt);
for (Tcl_Size i=1 ; i<=numArgs ; i++, defPtr++) {
Tcl_Obj *argObj;
Tcl_Obj *namePtr = localName(framePtr, i-1);
if (defPtr->value.objPtr != NULL) {
TclNewObj(argObj);
TclAppendStringsToObj(argObj, "?", TclGetString(namePtr), "?");
} else if (defPtr->flags & VAR_IS_ARGS) {
|
| ︙ | ︙ | |||
1119 1120 1121 1122 1123 1124 1125 |
desiredObjs[i] = argObj;
}
}
Tcl_ResetResult(interp);
Tcl_WrongNumArgs(interp, numArgs+1, desiredObjs, final);
| | | 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 |
desiredObjs[i] = argObj;
}
}
Tcl_ResetResult(interp);
Tcl_WrongNumArgs(interp, numArgs+1, desiredObjs, final);
for (Tcl_Size i=0 ; i<=numArgs ; i++) {
Tcl_DecrRefCount(desiredObjs[i]);
}
TclStackFree(interp, desiredObjs);
return TCL_ERROR;
}
/*
|
| ︙ | ︙ | |||
1257 1258 1259 1260 1261 1262 1263 |
}
void
TclFreeLocalCache(
Tcl_Interp *interp,
LocalCache *localCachePtr)
{
| < | | 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 |
}
void
TclFreeLocalCache(
Tcl_Interp *interp,
LocalCache *localCachePtr)
{
Tcl_Obj **namePtrPtr = &localCachePtr->varName0;
for (Tcl_Size i = 0; i < localCachePtr->numVars; i++, namePtrPtr++) {
Tcl_Obj *objPtr = *namePtrPtr;
if (objPtr) {
/* TclReleaseLiteral calls Tcl_DecrRefCount for us */
TclReleaseLiteral(interp, objPtr);
}
}
|
| ︙ | ︙ | |||
1722 1723 1724 1725 1726 1727 1728 |
TclStackFree(interp, freePtr); /* Free CallFrame. */
return TCL_ERROR;
}
#if defined(TCL_COMPILE_DEBUG)
if (tclTraceExec >= TCL_TRACE_BYTECODE_EXEC_PROCS) {
CallFrame *framePtr = iPtr->varFramePtr;
| < | < | < | 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 |
TclStackFree(interp, freePtr); /* Free CallFrame. */
return TCL_ERROR;
}
#if defined(TCL_COMPILE_DEBUG)
if (tclTraceExec >= TCL_TRACE_BYTECODE_EXEC_PROCS) {
CallFrame *framePtr = iPtr->varFramePtr;
if (framePtr->isProcCallFrame & FRAME_IS_LAMBDA) {
fprintf(stdout, "Calling lambda ");
} else {
fprintf(stdout, "Calling proc ");
}
for (Tcl_Size i = 0; i < framePtr->objc; i++) {
TclPrintObject(stdout, framePtr->objv[i], 15);
fprintf(stdout, " ");
}
fprintf(stdout, "\n");
fflush(stdout);
}
#endif /*TCL_COMPILE_DEBUG*/
#ifdef USE_DTRACE
if (TCL_DTRACE_PROC_ARGS_ENABLED()) {
Tcl_Size l = iPtr->varFramePtr->isProcCallFrame & FRAME_IS_LAMBDA ? 1 : 0;
const char *a[10];
for (Tcl_Size i = 0 ; i < 10 ; i++, l++) {
a[i] = (l < iPtr->varFramePtr->objc ?
TclGetString(iPtr->varFramePtr->objv[l]) : NULL);
}
TCL_DTRACE_PROC_ARGS(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7],
a[8], a[9]);
}
if (TCL_DTRACE_PROC_INFO_ENABLED() && iPtr->cmdFramePtr) {
Tcl_Obj *info = TclInfoFrame(interp, iPtr->cmdFramePtr);
const char *a[6];
|
| ︙ | ︙ | |||
1995 1996 1997 1998 1999 2000 2001 |
*/
iPtr->compiledProcPtr = procPtr;
if (procPtr->numCompiledLocals > procPtr->numArgs) {
CompiledLocal *clPtr = procPtr->firstLocalPtr;
CompiledLocal *lastPtr = NULL;
| | | | 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 |
*/
iPtr->compiledProcPtr = procPtr;
if (procPtr->numCompiledLocals > procPtr->numArgs) {
CompiledLocal *clPtr = procPtr->firstLocalPtr;
CompiledLocal *lastPtr = NULL;
Tcl_Size numArgs = procPtr->numArgs;
for (Tcl_Size i = 0; i < numArgs; i++) {
lastPtr = clPtr;
clPtr = clPtr->nextPtr;
}
if (lastPtr) {
lastPtr->nextPtr = NULL;
} else {
|
| ︙ | ︙ |
Changes to generic/tclProcess.c.
| ︙ | ︙ | |||
483 484 485 486 487 488 489 |
Tcl_Obj *const objv[]) /* Argument objects. */
{
Tcl_Obj *dict;
int options = WNOHANG;
Tcl_HashEntry *entry;
Tcl_HashSearch search;
ProcessInfo *info;
| | | 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 |
Tcl_Obj *const objv[]) /* Argument objects. */
{
Tcl_Obj *dict;
int options = WNOHANG;
Tcl_HashEntry *entry;
Tcl_HashSearch search;
ProcessInfo *info;
Tcl_Size numPids;
Tcl_Obj **pidObjs;
int result;
int pid;
Tcl_Obj *const *savedobjv = objv;
static const char *const switches[] = {
"-wait", "--", NULL
};
|
| ︙ | ︙ | |||
559 560 561 562 563 564 565 |
result = TclListObjGetElements(interp, objv[1], &numPids, &pidObjs);
if (result != TCL_OK) {
return result;
}
dict = Tcl_NewDictObj();
Tcl_MutexLock(&infoTablesMutex);
| | | 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 |
result = TclListObjGetElements(interp, objv[1], &numPids, &pidObjs);
if (result != TCL_OK) {
return result;
}
dict = Tcl_NewDictObj();
Tcl_MutexLock(&infoTablesMutex);
for (Tcl_Size i = 0; i < numPids; i++) {
result = Tcl_GetIntFromObj(interp, pidObjs[i], &pid);
if (result != TCL_OK) {
Tcl_MutexUnlock(&infoTablesMutex);
Tcl_DecrRefCount(dict);
return result;
}
|
| ︙ | ︙ | |||
627 628 629 630 631 632 633 |
ProcessPurgeObjCmd(
TCL_UNUSED(void *),
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
Tcl_HashEntry *entry;
| < < < < > > > | | > | 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 |
ProcessPurgeObjCmd(
TCL_UNUSED(void *),
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
Tcl_HashEntry *entry;
ProcessInfo *info;
if (objc != 1 && objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, "?pids?");
return TCL_ERROR;
}
/*
* First reap detached procs so that their purge flag is up-to-date.
*/
Tcl_ReapDetachedProcs();
if (objc == 1) {
/*
* Purge all terminated processes.
*/
Tcl_MutexLock(&infoTablesMutex);
Tcl_HashSearch search;
for (entry = Tcl_FirstHashEntry(&infoTablePerResolvedPid, &search);
entry != NULL; entry = Tcl_NextHashEntry(&search)) {
info = (ProcessInfo *) Tcl_GetHashValue(entry);
if (info->purge) {
Tcl_DeleteHashEntry(entry);
entry = Tcl_FindHashEntry(&infoTablePerPid, info->pid);
Tcl_DeleteHashEntry(entry);
FreeProcessInfo(info);
}
}
Tcl_MutexUnlock(&infoTablesMutex);
} else {
/*
* Purge only provided processes.
*/
Tcl_Size numPids;
Tcl_Obj **pidObjs;
int result = TclListObjGetElements(interp, objv[1], &numPids, &pidObjs);
if (result != TCL_OK) {
return result;
}
Tcl_MutexLock(&infoTablesMutex);
for (Tcl_Size i = 0; i < numPids; i++) {
int pid;
result = Tcl_GetIntFromObj(interp, pidObjs[i], &pid);
if (result != TCL_OK) {
Tcl_MutexUnlock(&infoTablesMutex);
return result;
}
entry = Tcl_FindHashEntry(&infoTablePerResolvedPid, INT2PTR(pid));
|
| ︙ | ︙ |
Changes to generic/tclResult.c.
| ︙ | ︙ | |||
610 611 612 613 614 615 616 |
KEY_LAST * sizeof(Tcl_Obj *));
if (keys[0] == NULL) {
/*
* First call in this thread, create the keys...
*/
| < < | | 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 |
KEY_LAST * sizeof(Tcl_Obj *));
if (keys[0] == NULL) {
/*
* First call in this thread, create the keys...
*/
TclNewLiteralStringObj(keys[KEY_CODE], "-code");
TclNewLiteralStringObj(keys[KEY_ERRORCODE], "-errorcode");
TclNewLiteralStringObj(keys[KEY_ERRORINFO], "-errorinfo");
TclNewLiteralStringObj(keys[KEY_ERRORLINE], "-errorline");
TclNewLiteralStringObj(keys[KEY_ERRORSTACK],"-errorstack");
TclNewLiteralStringObj(keys[KEY_LEVEL], "-level");
TclNewLiteralStringObj(keys[KEY_OPTIONS], "-options");
for (int i = KEY_CODE; i < KEY_LAST; i++) {
Tcl_IncrRefCount(keys[i]);
}
/*
* ... and arrange for their clenaup.
*/
|
| ︙ | ︙ | |||
655 656 657 658 659 660 661 |
*/
static void
ReleaseKeys(
void *clientData)
{
Tcl_Obj **keys = (Tcl_Obj **)clientData;
| < | | 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 |
*/
static void
ReleaseKeys(
void *clientData)
{
Tcl_Obj **keys = (Tcl_Obj **)clientData;
for (int i = KEY_CODE; i < KEY_LAST; i++) {
Tcl_DecrRefCount(keys[i]);
keys[i] = NULL;
}
}
/*
*----------------------------------------------------------------------
|
| ︙ | ︙ |
Changes to generic/tclZipfs.c.
| ︙ | ︙ | |||
554 555 556 557 558 559 560 |
int
TclIsZipfsPath(
const char *path)
{
#ifdef _WIN32
return strncmp(path, ZIPFS_VOLUME, ZIPFS_VOLUME_LEN) ? 0 : ZIPFS_VOLUME_LEN;
#else
| < | | 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 |
int
TclIsZipfsPath(
const char *path)
{
#ifdef _WIN32
return strncmp(path, ZIPFS_VOLUME, ZIPFS_VOLUME_LEN) ? 0 : ZIPFS_VOLUME_LEN;
#else
for (int i = 0; i < ZIPFS_VOLUME_LEN; ++i) {
if (path[i] != ZIPFS_VOLUME[i] &&
(path[i] != '\\' || ZIPFS_VOLUME[i] != '/')) {
return 0;
}
}
return ZIPFS_VOLUME_LEN;
#endif
|
| ︙ | ︙ | |||
1306 1307 1308 1309 1310 1311 1312 |
/*
* We are looking for the case where the path is //zipfs:/a/b
* and there is a mount point //zipfs:/a/b/c/.. below it
*/
for (hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); hPtr;
hPtr = Tcl_NextHashEntry(&search)) {
| | < | | 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 |
/*
* We are looking for the case where the path is //zipfs:/a/b
* and there is a mount point //zipfs:/a/b/c/.. below it
*/
for (hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); hPtr;
hPtr = Tcl_NextHashEntry(&search)) {
const ZipFile *zf = (ZipFile *) Tcl_GetHashValue(hPtr);
if (zf->mountPointLen == 0) {
/*
* Enumerate the contents of the ZIP; it's mounted on the root.
* TODO - a holdover from androwish? Tcl does not allow mounting
* outside of the //zipfs:/ area.
*/
for (const ZipEntry *z = zf->topEnts; z; z = z->tnext) {
int lenz = (int) strlen(z->name);
if ((lenz >= pathLen) &&
(z->name[pathLen] == '/' || z->name[pathLen] == '\0') &&
(strncmp(z->name, path, pathLen) == 0)) {
return 1;
}
}
|
| ︙ | ︙ | |||
1926 1927 1928 1929 1930 1931 1932 |
ZipFile *zf, /* Temporary buffer hold archive descriptors */
const char *mountPoint, /* Mount point path. Must be fully normalized */
const char *passwd, /* Password for opening the ZIP, or NULL if
* the ZIP is unprotected. */
const char *zipname) /* Path to ZIP file to build a catalog of. */
{
int isNew;
| | | 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 |
ZipFile *zf, /* Temporary buffer hold archive descriptors */
const char *mountPoint, /* Mount point path. Must be fully normalized */
const char *passwd, /* Password for opening the ZIP, or NULL if
* the ZIP is unprotected. */
const char *zipname) /* Path to ZIP file to build a catalog of. */
{
int isNew;
size_t pwlen;
ZipFile *zf0;
ZipEntry *z;
Tcl_HashEntry *hPtr;
Tcl_DString ds, fpBuf;
unsigned char *q;
assert(TclIsZipfsPath(mountPoint)); /* Caller should have normalized */
|
| ︙ | ︙ | |||
1997 1998 1999 2000 2001 2002 2003 |
memcpy(zf->name, zipname, zf->nameLength + 1);
Tcl_SetHashValue(hPtr, zf);
if ((zf->passBuf[0] == 0) && pwlen) {
int k = 0;
zf->passBuf[k++] = pwlen;
| | | 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 |
memcpy(zf->name, zipname, zf->nameLength + 1);
Tcl_SetHashValue(hPtr, zf);
if ((zf->passBuf[0] == 0) && pwlen) {
int k = 0;
zf->passBuf[k++] = pwlen;
for (size_t i = pwlen; i-- > 0 ;) {
zf->passBuf[k++] = (passwd[i] & 0x0f)
| pwrot[(passwd[i] >> 4) & 0x0f];
}
zf->passBuf[k] = '\0';
}
/* TODO - is this test necessary? When will mountPoint[0] be \0 ? */
if (mountPoint[0] != '\0') {
|
| ︙ | ︙ | |||
2029 2030 2031 2032 2033 2034 2035 |
z->timestamp = t.sec;
z->next = zf->entries;
zf->entries = z;
}
}
q = zf->data + zf->directoryOffset;
Tcl_DStringInit(&fpBuf);
| | | < < < | | | | | | > | | 2027 2028 2029 2030 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 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 |
z->timestamp = t.sec;
z->next = zf->entries;
zf->entries = z;
}
}
q = zf->data + zf->directoryOffset;
Tcl_DStringInit(&fpBuf);
for (size_t i = 0; i < zf->numFiles; i++) {
const unsigned char *start = zf->data;
const unsigned char *end = zf->data + zf->length;
int isdir = 0;
size_t pathlen = ZipReadShort(start, end, q + ZIP_CENTRAL_PATHLEN_OFFS);
size_t comlen = ZipReadShort(start, end, q + ZIP_CENTRAL_FCOMMENTLEN_OFFS);
unsigned extra = ZipReadShort(start, end, q + ZIP_CENTRAL_EXTRALEN_OFFS);
Tcl_DStringSetLength(&ds, 0);
char *path = DecodeZipEntryText(q + ZIP_CENTRAL_HEADER_LEN, pathlen, &ds);
if ((pathlen > 0) && (path[pathlen - 1] == '/')) {
Tcl_DStringSetLength(&ds, pathlen - 1);
path = Tcl_DStringValue(&ds);
isdir = 1;
}
if ((strcmp(path, ".") == 0) || (strcmp(path, "..") == 0)) {
goto nextent;
}
unsigned char *lq = zf->data + zf->baseOffset
+ ZipReadInt(start, end, q + ZIP_CENTRAL_LOCALHDR_OFFS);
if ((lq < start) || (lq + ZIP_LOCAL_HEADER_LEN > end)) {
goto nextent;
}
int nbcompr = ZipReadInt(start, end, lq + ZIP_LOCAL_COMPLEN_OFFS);
unsigned char *gq = NULL;
if (!isdir && (nbcompr == 0)
&& (ZipReadInt(start, end, lq + ZIP_LOCAL_UNCOMPLEN_OFFS) == 0)
&& (ZipReadInt(start, end, lq + ZIP_LOCAL_CRC32_OFFS) == 0)) {
gq = q;
nbcompr = ZipReadInt(start, end, gq + ZIP_CENTRAL_COMPLEN_OFFS);
}
size_t offs = (lq - zf->data)
+ ZIP_LOCAL_HEADER_LEN
+ ZipReadShort(start, end, lq + ZIP_LOCAL_PATHLEN_OFFS)
+ ZipReadShort(start, end, lq + ZIP_LOCAL_EXTRALEN_OFFS);
if (offs + nbcompr > zf->length) {
goto nextent;
}
|
| ︙ | ︙ | |||
2104 2105 2106 2107 2108 2109 2110 | * Regular files skipped when mounting on root. */ goto nextent; #endif /* ANDROID */ } Tcl_DStringSetLength(&fpBuf, 0); | | > | 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 |
* Regular files skipped when mounting on root.
*/
goto nextent;
#endif /* ANDROID */
}
Tcl_DStringSetLength(&fpBuf, 0);
char *fullpath = MapPathToZipfs(interp, mountPoint, path, &fpBuf);
z = AllocateZipEntry();
z->depth = CountSlashes(fullpath);
assert(z->depth >= ZIPFS_ROOTDIR_DEPTH);
z->zipFilePtr = zf;
z->isDirectory = isdir;
z->isEncrypted =
(ZipReadShort(start, end, lq + ZIP_LOCAL_FLAGS_OFFS) & 1)
&& (nbcompr > ZIP_CRYPT_HDR_LEN);
z->offset = offs;
int dosTime, dosDate;
if (gq) {
z->crc32 = ZipReadInt(start, end, gq + ZIP_CENTRAL_CRC32_OFFS);
dosDate = ZipReadShort(start, end, gq + ZIP_CENTRAL_MDATE_OFFS);
dosTime = ZipReadShort(start, end, gq + ZIP_CENTRAL_MTIME_OFFS);
z->timestamp = DosTimeDate(dosDate, dosTime);
z->numBytes = ZipReadInt(start, end,
gq + ZIP_CENTRAL_UNCOMPLEN_OFFS);
|
| ︙ | ︙ | |||
2156 2157 2158 2159 2160 2161 2162 |
/*
* Make any directory nodes we need. ZIPs are not consistent about
* containing directory nodes.
*/
if (!z->isDirectory && (z->depth > ZIPFS_ROOTDIR_DEPTH)) {
| < < < | | | | 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 |
/*
* Make any directory nodes we need. ZIPs are not consistent about
* containing directory nodes.
*/
if (!z->isDirectory && (z->depth > ZIPFS_ROOTDIR_DEPTH)) {
Tcl_DStringSetLength(&ds, strlen(z->name) + 8);
Tcl_DStringSetLength(&ds, 0);
Tcl_DStringAppend(&ds, z->name, -1);
char *dir = Tcl_DStringValue(&ds);
for (char *endPtr = strrchr(dir, '/'); endPtr && (endPtr != dir);
endPtr = strrchr(dir, '/')) {
Tcl_DStringSetLength(&ds, endPtr - dir);
hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, dir, &isNew);
if (!isNew) {
/*
* Already made. That's fine.
*/
break;
}
ZipEntry *zd = AllocateZipEntry();
zd->depth = CountSlashes(dir);
assert(zd->depth > ZIPFS_ROOTDIR_DEPTH);
zd->zipFilePtr = zf;
zd->isDirectory = 1;
zd->offset = z->offset;
zd->timestamp = z->timestamp;
zd->compressMethod = ZIP_COMPMETH_STORED;
|
| ︙ | ︙ | |||
2310 2311 2312 2313 2314 2315 2316 |
* Memory associated with the mounted archive is deallocated.
*------------------------------------------------------------------------
*/
static void
CleanupMount(
ZipFile *zf) /* Mount point */
{
| < < | | | 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 |
* Memory associated with the mounted archive is deallocated.
*------------------------------------------------------------------------
*/
static void
CleanupMount(
ZipFile *zf) /* Mount point */
{
for (ZipEntry *z = zf->entries, *znext; z; z = znext) {
znext = z->next;
Tcl_HashEntry *hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, z->name);
if (hPtr) {
Tcl_DeleteHashEntry(hPtr);
}
if (z->data) {
Tcl_Free(z->data);
}
Tcl_Free(z);
|
| ︙ | ︙ | |||
3169 3170 3171 3172 3173 3174 3175 |
deflateEnd(&stream);
Tcl_Close(interp, in);
Tcl_DStringFree(&zpathDs);
return TCL_ERROR;
}
olen = sizeof(obuf) - stream.avail_out;
if (passwd) {
| | | < < | 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 |
deflateEnd(&stream);
Tcl_Close(interp, in);
Tcl_DStringFree(&zpathDs);
return TCL_ERROR;
}
olen = sizeof(obuf) - stream.avail_out;
if (passwd) {
for (Tcl_Size i = 0; i < olen; i++) {
int tmp;
obuf[i] = (char) zencode(keys, crc32tab, obuf[i], tmp);
}
}
if (olen && (Tcl_Write(out, obuf, olen) != olen)) {
deflateEnd(&stream);
goto writeErrorWithChannelOpen;
}
|
| ︙ | ︙ | |||
3216 3217 3218 3219 3220 3221 3222 |
len = Tcl_Read(in, buf, bufsize);
if (len < 0) {
goto readErrorWithChannelOpen;
} else if (len == 0) {
break;
}
if (passwd) {
| | | < < | 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 |
len = Tcl_Read(in, buf, bufsize);
if (len < 0) {
goto readErrorWithChannelOpen;
} else if (len == 0) {
break;
}
if (passwd) {
for (Tcl_Size i = 0; i < len; i++) {
int tmp;
buf[i] = (char) zencode(keys0, crc32tab, buf[i], tmp);
}
}
if (Tcl_Write(out, buf, len) != len) {
goto writeErrorWithChannelOpen;
}
nbytecompr += len;
|
| ︙ | ︙ | |||
3425 3426 3427 3428 3429 3430 3431 |
* do not strip anything (except for dirRoot
* itself). */
Tcl_Obj *passwordObj) /* The password for encoding things. NULL if
* there's no password protection. */
{
Tcl_Channel out;
int count, ret = TCL_ERROR;
| | | 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 |
* do not strip anything (except for dirRoot
* itself). */
Tcl_Obj *passwordObj) /* The password for encoding things. NULL if
* there's no password protection. */
{
Tcl_Channel out;
int count, ret = TCL_ERROR;
Tcl_Size pwlen = 0, slen = 0, len;
Tcl_Size lobjc;
long long dataStartOffset; /* The overall file offset of the start of the
* data section of the file. */
long long directoryStartOffset;
/* The overall file offset of the start of the
* central directory. */
long long suffixStartOffset;/* The overall file offset of the start of the
|
| ︙ | ︙ | |||
3506 3507 3508 3509 3510 3511 3512 |
int isMounted = 0;
const char *imgName;
// TODO: normalize the origin file name
imgName = (originFile != NULL) ? TclGetString(originFile) :
Tcl_GetNameOfExecutable();
if (pwlen) {
| | | 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 |
int isMounted = 0;
const char *imgName;
// TODO: normalize the origin file name
imgName = (originFile != NULL) ? TclGetString(originFile) :
Tcl_GetNameOfExecutable();
if (pwlen) {
Tcl_Size i = 0;
for (len = pwlen; len-- > 0;) {
int ch = pw[len];
passBuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f];
i++;
}
passBuf[i] = i;
|
| ︙ | ︙ | |||
3590 3591 3592 3593 3594 3595 3596 |
/*
* Store the password so that the automounter can find it.
*/
len = strlen(passBuf);
if (len > 0) {
| | | 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 |
/*
* Store the password so that the automounter can find it.
*/
len = strlen(passBuf);
if (len > 0) {
Tcl_Size i = Tcl_Write(out, passBuf, len);
if (i != len) {
Tcl_DecrRefCount(list);
TclPrintfResult(interp, "write error: %s",
Tcl_PosixError(interp));
Tcl_Close(interp, out);
return TCL_ERROR;
}
|
| ︙ | ︙ | |||
3617 3618 3619 3620 3621 3622 3623 |
Tcl_InitHashTable(&fileHash, TCL_STRING_KEYS);
if (mappingList == NULL && stripPrefix != NULL) {
strip = TclGetStringFromObj(stripPrefix, &slen);
if (!slen) {
strip = NULL;
}
}
| | | | 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 |
Tcl_InitHashTable(&fileHash, TCL_STRING_KEYS);
if (mappingList == NULL && stripPrefix != NULL) {
strip = TclGetStringFromObj(stripPrefix, &slen);
if (!slen) {
strip = NULL;
}
}
for (Tcl_Size i = 0; i < lobjc; i += (mappingList ? 2 : 1)) {
Tcl_Obj *pathObj = lobjv[i];
const char *name = ComputeNameInArchive(pathObj,
(mappingList ? lobjv[i + 1] : NULL), strip, slen);
if (name[0] == '\0') {
continue;
}
if (ZipAddFile(interp, pathObj, name, out, pw, buf, sizeof(buf),
&fileHash) != TCL_OK) {
goto done;
}
}
/*
* Construct the contents of the ZIP central directory.
*/
directoryStartOffset = Tcl_Tell(out);
count = 0;
for (Tcl_Size i = 0; i < lobjc; i += (mappingList ? 2 : 1)) {
const char *name = ComputeNameInArchive(lobjv[i],
(mappingList ? lobjv[i + 1] : NULL), strip, slen);
Tcl_DString ds;
hPtr = Tcl_FindHashEntry(&fileHash, name);
if (!hPtr) {
continue;
|
| ︙ | ︙ | |||
3724 3725 3726 3727 3728 3729 3730 |
static int
CopyImageFile(
Tcl_Interp *interp, /* For error reporting. */
const char *imgName, /* Where to copy from. */
Tcl_Channel out) /* Where to copy to; already open for writing
* binary data. */
{
| < < < | | > | | 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 |
static int
CopyImageFile(
Tcl_Interp *interp, /* For error reporting. */
const char *imgName, /* Where to copy from. */
Tcl_Channel out) /* Where to copy to; already open for writing
* binary data. */
{
char buf[4096];
const char *errMsg;
Tcl_ResetResult(interp);
Tcl_Channel in = Tcl_OpenFileChannel(interp, imgName, "rb", 0644);
if (!in) {
return TCL_ERROR;
}
/*
* Get the length of the file (and exclude non-files).
*/
Tcl_WideInt i = Tcl_Seek(in, 0, SEEK_END);
if (i == -1) {
errMsg = "seek error";
goto copyError;
}
Tcl_Seek(in, 0, SEEK_SET);
/*
* Copy the whole file, 8 blocks at a time (reasonably efficient). Note
* that this totally ignores things like Windows's Alternate File Streams.
*/
Tcl_Size m, n;
for (Tcl_WideInt k = 0; k < i; k += m) {
m = i - k;
if (m > (Tcl_Size) sizeof(buf)) {
m = sizeof(buf);
}
n = Tcl_Read(in, buf, m);
if (n == -1) {
errMsg = "read error";
|
| ︙ | ︙ | |||
4575 4576 4577 4578 4579 4580 4581 |
toRead = info->numBytes - info->cursor;
nextpos = info->numBytes;
}
if (toRead == 0) {
return 0;
}
if (info->isEncrypted) {
| < | | 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 |
toRead = info->numBytes - info->cursor;
nextpos = info->numBytes;
}
if (toRead == 0) {
return 0;
}
if (info->isEncrypted) {
/*
* TODO - when is this code ever exercised? Cannot reach it from
* tests. In particular, decryption is always done at channel open
* to allow for seeks and random reads.
*/
for (int i = 0; i < toRead; i++) {
int ch = info->ubuf[i + info->cursor];
buf[i] = zdecode(info->keys, crc32tab, ch);
}
} else {
memcpy(buf, info->ubuf + info->cursor, toRead);
}
|
| ︙ | ︙ | |||
5013 5014 5015 5016 5017 5018 5019 |
Tcl_Interp *interp, /* Current interpreter, or NULL (when errors
* will be silent). */
ZipChannel *info, /* The channel to set up. */
ZipEntry *z, /* The zipped file that the channel will write
* to. */
int mode) /* O_APPEND, O_TRUNC */
{
| | | 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 5011 5012 |
Tcl_Interp *interp, /* Current interpreter, or NULL (when errors
* will be silent). */
ZipChannel *info, /* The channel to set up. */
ZipEntry *z, /* The zipped file that the channel will write
* to. */
int mode) /* O_APPEND, O_TRUNC */
{
int ch;
unsigned char *cbuf = NULL;
/*
* Set up a writable channel.
*/
info->mode = mode;
|
| ︙ | ︙ | |||
5073 5074 5075 5076 5077 5078 5079 |
memset(&stream, 0, sizeof(z_stream));
stream.zalloc = Z_NULL;
stream.zfree = Z_NULL;
stream.opaque = Z_NULL;
stream.avail_in = z->numCompressedBytes;
if (z->isEncrypted) {
| < < | | 5058 5059 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 5075 5076 5077 5078 5079 5080 |
memset(&stream, 0, sizeof(z_stream));
stream.zalloc = Z_NULL;
stream.zfree = Z_NULL;
stream.opaque = Z_NULL;
stream.avail_in = z->numCompressedBytes;
if (z->isEncrypted) {
/* Min length ZIP_CRYPT_HDR_LEN for keys should already been checked. */
assert(stream.avail_in >= ZIP_CRYPT_HDR_LEN);
stream.avail_in -= ZIP_CRYPT_HDR_LEN;
cbuf = (unsigned char *) Tcl_AttemptAlloc(stream.avail_in ? stream.avail_in : 1);
if (!cbuf) {
goto memoryError;
}
for (unsigned j = 0; j < stream.avail_in; j++) {
ch = zbuf[j];
cbuf[j] = zdecode(info->keys, crc32tab, ch);
}
stream.next_in = cbuf;
} else {
stream.next_in = zbuf;
}
|
| ︙ | ︙ | |||
5120 5121 5122 5123 5124 5125 5126 |
*/
if (z->numCompressedBytes <= ZIP_CRYPT_HDR_LEN ||
(z->numCompressedBytes - ZIP_CRYPT_HDR_LEN) != z->numBytes) {
goto corruptionError;
}
int len = z->numCompressedBytes - ZIP_CRYPT_HDR_LEN;
assert(len <= info->ubufSize);
| | | 5103 5104 5105 5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 |
*/
if (z->numCompressedBytes <= ZIP_CRYPT_HDR_LEN ||
(z->numCompressedBytes - ZIP_CRYPT_HDR_LEN) != z->numBytes) {
goto corruptionError;
}
int len = z->numCompressedBytes - ZIP_CRYPT_HDR_LEN;
assert(len <= info->ubufSize);
for (int i = 0; i < len; i++) {
ch = zbuf[i];
info->ubuf[i] = zdecode(info->keys, crc32tab, ch);
}
info->numBytes = len;
} else {
/*
* Simple stored data. Copy into our working buffer.
|
| ︙ | ︙ | |||
5215 5216 5217 5218 5219 5220 5221 |
goto error_cleanup;
}
info->ubuf += ZIP_CRYPT_HDR_LEN;
}
if (info->iscompr) {
z_stream stream;
| < < | | | 5198 5199 5200 5201 5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 5240 5241 5242 5243 5244 5245 5246 5247 5248 5249 5250 5251 5252 |
goto error_cleanup;
}
info->ubuf += ZIP_CRYPT_HDR_LEN;
}
if (info->iscompr) {
z_stream stream;
/*
* Data to decode is compressed, and possibly encrpyted too. If
* encrypted, local variable ubuf is used to hold the decrypted but
* still compressed data.
*/
memset(&stream, 0, sizeof(z_stream));
stream.zalloc = Z_NULL;
stream.zfree = Z_NULL;
stream.opaque = Z_NULL;
stream.avail_in = z->numCompressedBytes;
if (info->isEncrypted) {
assert(stream.avail_in >= ZIP_CRYPT_HDR_LEN);
stream.avail_in -= ZIP_CRYPT_HDR_LEN;
ubuf = (unsigned char *) Tcl_AttemptAlloc(stream.avail_in ? stream.avail_in : 1);
if (!ubuf) {
goto memoryError;
}
for (unsigned j = 0; j < stream.avail_in; j++) {
ch = info->ubuf[j];
ubuf[j] = zdecode(info->keys, crc32tab, ch);
}
stream.next_in = ubuf;
} else {
stream.next_in = info->ubuf;
}
info->ubufSize = info->numBytes ? info->numBytes : 1;
info->ubufToFree = (unsigned char *)Tcl_AttemptAlloc(info->ubufSize);
info->ubuf = info->ubufToFree;
stream.next_out = info->ubuf;
if (!info->ubuf) {
goto memoryError;
}
stream.avail_out = info->numBytes;
if (inflateInit2(&stream, -15) != Z_OK) {
goto corruptionError;
}
int err = inflate(&stream, Z_SYNC_FLUSH);
inflateEnd(&stream);
/*
* Decompression was successful if we're either in the END state, or
* in the OK state with no buffered bytes.
*/
|
| ︙ | ︙ | |||
5280 5281 5282 5283 5284 5285 5286 |
if (ubuf) {
info->isEncrypted = 0;
memset(info->keys, 0, sizeof(info->keys));
Tcl_Free(ubuf);
}
} else if (info->isEncrypted) {
| < < | | | 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 |
if (ubuf) {
info->isEncrypted = 0;
memset(info->keys, 0, sizeof(info->keys));
Tcl_Free(ubuf);
}
} else if (info->isEncrypted) {
/*
* Decode encrypted but uncompressed file, since we support Tcl_Seek()
* on it, and it can be randomly accessed later.
*/
if (z->numCompressedBytes <= ZIP_CRYPT_HDR_LEN ||
(z->numCompressedBytes - ZIP_CRYPT_HDR_LEN) != z->numBytes) {
goto corruptionError;
}
unsigned len = z->numCompressedBytes - ZIP_CRYPT_HDR_LEN;
ubuf = (unsigned char *) Tcl_AttemptAlloc(len);
if (ubuf == NULL) {
goto memoryError;
}
for (unsigned j = 0; j < len; j++) {
ch = info->ubuf[j];
ubuf[j] = zdecode(info->keys, crc32tab, ch);
}
info->ubufSize = len;
info->ubufToFree = ubuf;
info->ubuf = info->ubufToFree;
ubuf = NULL; /* So it does not inadvertently get free on future changes */
|
| ︙ | ︙ | |||
5828 5829 5830 5831 5832 5833 5834 |
* list. */
Tcl_DString *prefix) /* Workspace filled with a prefix for all the
* filenames, or NULL if no prefix is to be
* used. */
{
Tcl_HashEntry *hPtr;
Tcl_HashSearch search;
| < | < < | | 5807 5808 5809 5810 5811 5812 5813 5814 5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 5825 5826 5827 5828 5829 5830 5831 5832 5833 5834 5835 5836 5837 5838 5839 5840 5841 5842 5843 5844 5845 5846 5847 5848 5849 5850 5851 5852 5853 |
* list. */
Tcl_DString *prefix) /* Workspace filled with a prefix for all the
* filenames, or NULL if no prefix is to be
* used. */
{
Tcl_HashEntry *hPtr;
Tcl_HashSearch search;
Tcl_Size normLength;
const char *path = TclGetStringFromObj(normPathPtr, &normLength);
Tcl_Size len = normLength;
if (len < 1) {
/*
* Shouldn't happen. But "shouldn't"...
*/
return;
}
int l = CountSlashes(path);
if (path[len - 1] == '/') {
len--;
} else {
l++;
}
if (!pattern || (pattern[0] == '\0')) {
pattern = "*";
}
for (hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); hPtr;
hPtr = Tcl_NextHashEntry(&search)) {
ZipFile *zf = (ZipFile *) Tcl_GetHashValue(hPtr);
if (zf->mountPointLen == 0) {
/*
* Enumerate the contents of the ZIP; it's mounted on the root.
* TODO - a holdover from androwish? Tcl does not allow mounting
* outside of the //zipfs:/ area.
*/
for (ZipEntry *z = zf->topEnts; z; z = z->tnext) {
Tcl_Size lenz = strlen(z->name);
if ((lenz > len + 1) && (strncmp(z->name, path, len) == 0)
&& (z->name[len] == '/')
&& ((int) CountSlashes(z->name) == l)
&& Tcl_StringCaseMatch(z->name + len + 1, pattern, 0)) {
AppendWithPrefix(result, prefix, z->name, lenz);
|
| ︙ | ︙ |
Changes to generic/tclZlib.c.
| ︙ | ︙ | |||
1333 1334 1335 1336 1337 1338 1339 |
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;
| | | 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 |
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, itemLen = 0, dataPos = 0;
Tcl_Obj *itemObj;
unsigned char *dataPtr, *itemPtr;
Tcl_Size existing = 0;
/*
* Getting beyond the of stream, just return empty string.
*/
|
| ︙ | ︙ | |||
1509 1510 1511 1512 1513 1514 1515 |
}
inflateEnd(&zshPtr->stream);
}
} else {
TclListObjLength(NULL, zshPtr->outData, &listLen);
if (count < 0) {
count = 0;
| | | 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 |
}
inflateEnd(&zshPtr->stream);
}
} else {
TclListObjLength(NULL, zshPtr->outData, &listLen);
if (count < 0) {
count = 0;
for (Tcl_Size i=0; i<listLen; i++) {
Tcl_ListObjIndex(NULL, zshPtr->outData, i, &itemObj);
(void) Tcl_GetBytesFromObj(NULL, itemObj, &itemLen);
if (i == 0) {
count += itemLen - zshPtr->outPos;
} else {
count += itemLen;
}
|
| ︙ | ︙ |
Changes to unix/tclUnixTest.c.
| ︙ | ︙ | |||
133 134 135 136 137 138 139 |
TestfilehandlerCmd(
TCL_UNUSED(void *),
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const *objv) /* Argument strings. */
{
Pipe *pipePtr;
| | | | 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 |
TestfilehandlerCmd(
TCL_UNUSED(void *),
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const *objv) /* Argument strings. */
{
Pipe *pipePtr;
int mask, timeout;
static int initialized = 0;
char buffer[4000];
TclFile file;
/*
* NOTE: When we make this code work on Windows also, the following
* variable needs to be made Unix-only.
*/
if (!initialized) {
for (int i = 0; i < MAX_PIPES; i++) {
testPipes[i].readFile = NULL;
}
initialized = 1;
}
if (objc < 2) {
Tcl_WrongNumArgs(interp, 1, objv, "option ...");
|
| ︙ | ︙ | |||
167 168 169 170 171 172 173 |
TclPrintfResult(interp, "bad index %s", TclGetString(objv[2]));
return TCL_ERROR;
}
pipePtr = &testPipes[i];
}
if (strcmp(Tcl_GetString(objv[1]), "close") == 0) {
| | | 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
TclPrintfResult(interp, "bad index %s", TclGetString(objv[2]));
return TCL_ERROR;
}
pipePtr = &testPipes[i];
}
if (strcmp(Tcl_GetString(objv[1]), "close") == 0) {
for (int i = 0; i < MAX_PIPES; i++) {
if (testPipes[i].readFile != NULL) {
TclpCloseFile(testPipes[i].readFile);
testPipes[i].readFile = NULL;
TclpCloseFile(testPipes[i].writeFile);
testPipes[i].writeFile = NULL;
}
}
|
| ︙ | ︙ |
Changes to win/tclWin32Dll.c.
| ︙ | ︙ | |||
205 206 207 208 209 210 211 |
*-------------------------------------------------------------------------
*/
char *
TclWinNoBackslash(
char *path) /* String to change. */
{
| < < | | 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
*-------------------------------------------------------------------------
*/
char *
TclWinNoBackslash(
char *path) /* String to change. */
{
for (char *p = path; *p != '\0'; p++) {
if (*p == '\\') {
*p = '/';
}
}
return path;
}
|
| ︙ | ︙ |
Changes to win/tclWinChan.c.
| ︙ | ︙ | |||
1704 1705 1706 1707 1708 1709 1710 |
*/
static int
NativeIsComPort(
const WCHAR *nativePath) /* Path of file to access, native encoding. */
{
const WCHAR *p = (const WCHAR *) nativePath;
| | | 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 |
*/
static int
NativeIsComPort(
const WCHAR *nativePath) /* Path of file to access, native encoding. */
{
const WCHAR *p = (const WCHAR *) nativePath;
size_t len = wcslen(p);
/*
* 1. Look for com[1-9]:?
*/
if ((len == 4) && (_wcsnicmp(p, L"com", 3) == 0)) {
/*
|
| ︙ | ︙ | |||
1730 1731 1732 1733 1734 1735 1736 |
*/
if ((len >= 8) && (_wcsnicmp(p, L"\\\\.\\com", 7) == 0)) {
/*
* Charaters 8..end must be a digits 0..9
*/
| | | 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 |
*/
if ((len >= 8) && (_wcsnicmp(p, L"\\\\.\\com", 7) == 0)) {
/*
* Charaters 8..end must be a digits 0..9
*/
for (size_t i=7; i<len; i++) {
if ((p[i] < '0') || (p[i] > '9')) {
return 0;
}
}
return 1;
}
return 0;
|
| ︙ | ︙ |
Changes to win/tclWinConsole.c.
| ︙ | ︙ | |||
1587 1588 1589 1590 1591 1592 1593 |
*/
static int
ConsoleDataAvailable(
HANDLE consoleHandle)
{
INPUT_RECORD input[10];
DWORD count;
| < | | 1587 1588 1589 1590 1591 1592 1593 1594 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 |
*/
static int
ConsoleDataAvailable(
HANDLE consoleHandle)
{
INPUT_RECORD input[10];
DWORD count;
/*
* Need at least one keyboard event.
*/
if (PeekConsoleInputW(consoleHandle, input,
sizeof(input) / sizeof(input[0]), &count) == FALSE) {
return -1;
}
/*
* Even if windows size and mouse events are disabled, can still have
* events other than keyboard, like focus events. Look for at least one
* keydown event because a trailing LF keyup is always present from the
* last input. However, if our buffer is full, assume there is a key
* down somewhere in the unread buffer. I suppose we could expand the
* buffer but not worth...
*/
if (count == (sizeof(input)/sizeof(input[0]))) {
return 1;
}
for (DWORD i = 0; i < count; ++i) {
if (input[i].EventType == KEY_EVENT
&& input[i].Event.KeyEvent.bKeyDown) {
return 1;
}
}
return 0;
}
|
| ︙ | ︙ |
Changes to win/tclWinFCmd.c.
| ︙ | ︙ | |||
1589 1590 1591 1592 1593 1594 1595 |
ConvertFileNameFormat(
Tcl_Interp *interp, /* The interp we are using for errors. */
TCL_UNUSED(int) /*objIndex*/,
Tcl_Obj *fileName, /* The name of the file. */
int longShort, /* 0 to short name, 1 to long name. */
Tcl_Obj **attributePtrPtr) /* A pointer to return the object with. */
{
| | < < | | > | 1589 1590 1591 1592 1593 1594 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 |
ConvertFileNameFormat(
Tcl_Interp *interp, /* The interp we are using for errors. */
TCL_UNUSED(int) /*objIndex*/,
Tcl_Obj *fileName, /* The name of the file. */
int longShort, /* 0 to short name, 1 to long name. */
Tcl_Obj **attributePtrPtr) /* A pointer to return the object with. */
{
Tcl_Size pathc;
Tcl_Obj *splitPath = Tcl_FSSplitPath(fileName, &pathc);
if (splitPath == NULL || pathc == 0) {
if (interp != NULL) {
TclPrintfResult(interp, "could not read \"%s\": "
"no such file or directory",
TclGetString(fileName));
errno = ENOENT;
Tcl_PosixError(interp);
}
goto cleanup;
}
/*
* We will decrement this again at the end. It is safer to do this in
* case any of the calls below retain a reference to splitPath.
*/
Tcl_IncrRefCount(splitPath);
for (Tcl_Size i = 0; i < pathc; i++) {
Tcl_Obj *elt;
char *pathv;
Tcl_Size length;
Tcl_ListObjIndex(NULL, splitPath, i, &elt);
pathv = TclGetStringFromObj(elt, &length);
if ((pathv[0] == '/') || ((length == 3) && (pathv[1] == ':'))
|| (strcmp(pathv, ".") == 0) || (strcmp(pathv, "..") == 0)) {
/*
|
| ︙ | ︙ | |||
1905 1906 1907 1908 1909 1910 1911 |
*/
Tcl_Obj *
TclpObjListVolumes(void)
{
Tcl_Obj *resultPtr, *elemPtr;
char buf[40 * 4]; /* There couldn't be more than 30 drives??? */
| < < | 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 |
*/
Tcl_Obj *
TclpObjListVolumes(void)
{
Tcl_Obj *resultPtr, *elemPtr;
char buf[40 * 4]; /* There couldn't be more than 30 drives??? */
TclNewObj(resultPtr);
/*
* On Win32s:
* GetLogicalDriveStrings() isn't implemented.
* GetLogicalDrives() returns incorrect information.
|
| ︙ | ︙ | |||
1930 1931 1932 1933 1934 1935 1936 | * avoid calling it. */ buf[1] = ':'; buf[2] = '/'; buf[3] = '\0'; | | | | 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 |
* avoid calling it.
*/
buf[1] = ':';
buf[2] = '/';
buf[3] = '\0';
for (int i = 0; i < 26; i++) {
buf[0] = (char) ('a' + i);
if (GetVolumeInformationA(buf, NULL, 0, NULL, NULL, NULL, NULL, 0)
|| (GetLastError() == ERROR_NOT_READY)) {
elemPtr = Tcl_NewStringObj(buf, TCL_INDEX_NONE);
Tcl_ListObjAppendElement(NULL, resultPtr, elemPtr);
}
}
} else {
for (char *p = buf; *p != '\0'; p += 4) {
p[2] = '/';
elemPtr = Tcl_NewStringObj(p, TCL_INDEX_NONE);
Tcl_ListObjAppendElement(NULL, resultPtr, elemPtr);
}
}
Tcl_IncrRefCount(resultPtr);
|
| ︙ | ︙ | |||
2024 2025 2026 2027 2028 2029 2030 |
* SUFFIX_LENGTH is longer than on Unix because we expect to be not on a
* case-sensitive filesystem.
*/
baseLen = Tcl_DStringLength(&base);
do {
char tempbuf[SUFFIX_LENGTH + 1];
| < | | 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 |
* SUFFIX_LENGTH is longer than on Unix because we expect to be not on a
* case-sensitive filesystem.
*/
baseLen = Tcl_DStringLength(&base);
do {
char tempbuf[SUFFIX_LENGTH + 1];
static const char randChars[] =
"QWERTYUIOPASDFGHJKLZXCVBNM1234567890";
static const int numRandChars = sizeof(randChars) - 1;
/*
* Put a random suffix on the end.
*/
error = ERROR_SUCCESS;
tempbuf[SUFFIX_LENGTH] = '\0';
for (int i = 0 ; i < SUFFIX_LENGTH; i++) {
tempbuf[i] = randChars[(int) (rand() % numRandChars)];
}
Tcl_DStringSetLength(&base, baseLen);
Tcl_UtfToWCharDString(tempbuf, TCL_INDEX_NONE, &base);
} while (!CreateDirectoryW((LPCWSTR) Tcl_DStringValue(&base), NULL)
&& (error = GetLastError()) == ERROR_ALREADY_EXISTS);
|
| ︙ | ︙ |
Changes to win/tclWinFile.c.
| ︙ | ︙ | |||
1500 1501 1502 1503 1504 1505 1506 |
rc = NetGetDCName(NULL, NULL, (LPBYTE *) &wDomain);
if (rc != 0) {
break;
}
domain = (const char *)INT2PTR(-1); /* repeat once */
}
if (rc == 0) {
| | | 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 |
rc = NetGetDCName(NULL, NULL, (LPBYTE *) &wDomain);
if (rc != 0) {
break;
}
domain = (const char *)INT2PTR(-1); /* repeat once */
}
if (rc == 0) {
DWORD size = MAX_PATH;
wHomeDir = uiPtr->usri1_home_dir;
if ((wHomeDir != NULL) && (wHomeDir[0] != '\0')) {
size = lstrlenW(wHomeDir);
Tcl_WCharToUtfDString(wHomeDir, size, bufferPtr);
} else {
WCHAR buf[MAX_PATH];
|
| ︙ | ︙ | |||
1524 1525 1526 1527 1528 1529 1530 | } result = Tcl_DStringValue(bufferPtr); /* * Be sure we return normalized path */ | | | 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 |
}
result = Tcl_DStringValue(bufferPtr);
/*
* Be sure we return normalized path
*/
for (DWORD i = 0; i < size; ++i) {
if (result[i] == '\\') {
result[i] = '/';
}
}
NetApiBufferFree((void *)uiPtr);
}
Tcl_DStringFree(&ds);
|
| ︙ | ︙ | |||
2561 2562 2563 2564 2565 2566 2567 |
size_t len = WinIsReserved(path);
if (len > 0) {
/*
* Actually it does exist - COM1, etc.
*/
| < < | | 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 |
size_t len = WinIsReserved(path);
if (len > 0) {
/*
* Actually it does exist - COM1, etc.
*/
for (size_t i=0 ; i<len ; i++) {
WCHAR wc = ((WCHAR *)nativePath)[i];
if (wc >= 'a') {
wc -= ('a' - 'A');
((WCHAR *) nativePath)[i] = wc;
}
}
|
| ︙ | ︙ | |||
2950 2951 2952 2953 2954 2955 2956 |
*/
Tcl_Obj *
TclpNativeToNormalized(
void *clientData)
{
Tcl_DString ds;
| < < | | 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 |
*/
Tcl_Obj *
TclpNativeToNormalized(
void *clientData)
{
Tcl_DString ds;
size_t len;
Tcl_DStringInit(&ds);
Tcl_WCharToUtfDString((const WCHAR *) clientData, TCL_INDEX_NONE, &ds);
char *copy = Tcl_DStringValue(&ds);
len = Tcl_DStringLength(&ds);
/*
* Certain native path representations on Windows have this special prefix
* to indicate that they are to be treated specially. For example
* extremely long paths, or symlinks.
*/
|
| ︙ | ︙ | |||
2979 2980 2981 2982 2983 2984 2985 |
}
}
/*
* Ensure we are using forward slashes only.
*/
| | | < | 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 |
}
}
/*
* Ensure we are using forward slashes only.
*/
for (char *p = copy; *p != '\0'; p++) {
if (*p == '\\') {
*p = '/';
}
}
Tcl_Obj *objPtr = Tcl_NewStringObj(copy, len);
Tcl_DStringFree(&ds);
return objPtr;
}
/*
*---------------------------------------------------------------------------
*
* TclNativeCreateNativeRep --
|
| ︙ | ︙ |
Changes to win/tclWinLoad.c.
| ︙ | ︙ | |||
337 338 339 340 341 342 343 |
static int
InitDLLDirectoryName(void)
{
size_t nameLen; /* Length of the temp folder name. */
WCHAR name[MAX_PATH]; /* Path name of the temp folder. */
DWORD id; /* The process id. */
DWORD lastError; /* Last error to happen in Win API. */
| < | | 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 |
static int
InitDLLDirectoryName(void)
{
size_t nameLen; /* Length of the temp folder name. */
WCHAR name[MAX_PATH]; /* Path name of the temp folder. */
DWORD id; /* The process id. */
DWORD lastError; /* Last error to happen in Win API. */
/*
* Determine the name of the directory to use, and create it. (Keep
* trying with new names until an attempt to create the directory
* succeeds)
*/
nameLen = GetTempPathW(MAX_PATH, name);
if (nameLen >= MAX_PATH-12) {
Tcl_SetErrno(ENAMETOOLONG);
return TCL_ERROR;
}
wcscpy(name+nameLen, L"TCLXXXXXXXX");
nameLen += 11;
id = GetCurrentProcessId();
lastError = ERROR_ALREADY_EXISTS;
for (int i=0 ; i<256 ; i++) {
wsprintfW(name+nameLen-8, L"%08x", id);
if (CreateDirectoryW(name, NULL)) {
/*
* Issue: we don't schedule this directory for deletion by anyone.
* Can we ask the OS to do this for us? There appears to be
* potential for using CreateFile (with the flag
* FILE_FLAG_BACKUP_SEMANTICS) and RemoveDirectory to do this...
|
| ︙ | ︙ |
Changes to win/tclWinPipe.c.
| ︙ | ︙ | |||
1553 1554 1555 1556 1557 1558 1559 |
size_t argc, /* Number of arguments. */
const char **argv, /* Argument strings in UTF. */
Tcl_DString *linePtr) /* Initialized Tcl_DString that receives the
* command line (WCHAR). */
{
const char *arg, *start, *special, *bspos;
int quote = 0;
| < | 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 |
size_t argc, /* Number of arguments. */
const char **argv, /* Argument strings in UTF. */
Tcl_DString *linePtr) /* Initialized Tcl_DString that receives the
* command line (WCHAR). */
{
const char *arg, *start, *special, *bspos;
int quote = 0;
Tcl_DString ds;
#ifdef TCL_WIN_PIPE_FULLESC
/* full escape inclusive %-subst avoidance */
static const char specMetaChars[] = "&|^<>!()%";
/* Characters to enclose in quotes if unpaired
* quote flag set. */
static const char specMetaChars2[] = "%";
|
| ︙ | ︙ | |||
1588 1589 1590 1591 1592 1593 1594 |
*/
TclDStringAppendDString(&ds, linePtr);
if (Tcl_DStringLength(linePtr) > 0) {
TclDStringAppendLiteral(&ds, " ");
}
| | | 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 |
*/
TclDStringAppendDString(&ds, linePtr);
if (Tcl_DStringLength(linePtr) > 0) {
TclDStringAppendLiteral(&ds, " ");
}
for (size_t i = 0; i < argc; i++) {
if (i == 0) {
arg = executable;
} else {
arg = argv[i];
TclDStringAppendLiteral(&ds, " ");
}
|
| ︙ | ︙ | |||
1917 1918 1919 1920 1921 1922 1923 |
TclGetAndDetachPids(
Tcl_Interp *interp,
Tcl_Channel chan)
{
PipeInfo *pipePtr;
const Tcl_ChannelType *chanTypePtr;
Tcl_Obj *pidsObj;
| < | | 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 |
TclGetAndDetachPids(
Tcl_Interp *interp,
Tcl_Channel chan)
{
PipeInfo *pipePtr;
const Tcl_ChannelType *chanTypePtr;
Tcl_Obj *pidsObj;
/*
* Punt if the channel is not a command channel.
*/
chanTypePtr = Tcl_GetChannelType(chan);
if (chanTypePtr != &pipeChannelType) {
return;
}
pipePtr = (PipeInfo *)Tcl_GetChannelInstanceData(chan);
TclNewObj(pidsObj);
for (size_t i = 0; i < pipePtr->numPids; i++) {
Tcl_ListObjAppendElement(NULL, pidsObj, Tcl_NewWideIntObj(
TclpGetPid(pipePtr->pidPtr[i])));
Tcl_DetachPids(1, &pipePtr->pidPtr[i]);
}
Tcl_SetObjResult(interp, pidsObj);
if (pipePtr->numPids > 0) {
Tcl_Free(pipePtr->pidPtr);
|
| ︙ | ︙ |
Changes to win/tclWinReg.c.
| ︙ | ︙ | |||
1269 1270 1271 1272 1273 1274 1275 |
}
value = ConvertDWORD((DWORD) type, (DWORD) value);
result = RegSetValueExW(key, (WCHAR *) valueName, 0,
(DWORD) type, (BYTE *) &value, sizeof(DWORD));
} else if (type == REG_MULTI_SZ) {
Tcl_DString data, buf;
| | | | 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 |
}
value = ConvertDWORD((DWORD) type, (DWORD) value);
result = RegSetValueExW(key, (WCHAR *) valueName, 0,
(DWORD) type, (BYTE *) &value, sizeof(DWORD));
} else if (type == REG_MULTI_SZ) {
Tcl_DString data, buf;
Tcl_Size objc;
Tcl_Obj **objv;
if (Tcl_ListObjGetElements(interp, dataObj, &objc, &objv) != TCL_OK) {
RegCloseKey(key);
Tcl_DStringFree(&nameBuf);
return TCL_ERROR;
}
/*
* Append the elements as null terminated strings. Note that we must
* not assume the length of the string in case there are embedded
* nulls, which aren't allowed in REG_MULTI_SZ values.
*/
Tcl_DStringInit(&data);
for (Tcl_Size i = 0; i < objc; i++) {
const char *bytes = Tcl_GetStringFromObj(objv[i], &len);
Tcl_DStringAppend(&data, bytes, len);
/*
* Add a null character to separate this value from the next.
*/
|
| ︙ | ︙ |
Changes to win/tclWinSerial.c.
| ︙ | ︙ | |||
1815 1816 1817 1818 1819 1820 1821 |
}
/*
* Option -ttycontrol {DTR 1 RTS 0 BREAK 0}
*/
if ((len > 4) && (strncmp(optionName, "-ttycontrol", len) == 0)) {
| < | | 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 |
}
/*
* Option -ttycontrol {DTR 1 RTS 0 BREAK 0}
*/
if ((len > 4) && (strncmp(optionName, "-ttycontrol", len) == 0)) {
int res = TCL_OK;
if (Tcl_SplitList(interp, value, &argc, &argv) == TCL_ERROR) {
return TCL_ERROR;
}
if ((argc % 2) == 1) {
if (interp != NULL) {
TclPrintfResult(interp,
"bad value \"%s\" for -ttycontrol: should be "
"a list of signal,value pairs", value);
TclSetErrorCode(interp, "TCL", "VALUE", "TTYCONTROL");
}
Tcl_Free((void *)argv);
return TCL_ERROR;
}
for (Tcl_Size i = 0; i < argc - 1; i += 2) {
if (Tcl_GetBoolean(interp, argv[i+1], &flag) == TCL_ERROR) {
res = TCL_ERROR;
break;
}
if (strncasecmp(argv[i], "DTR", strlen(argv[i])) == 0) {
if (!EscapeCommFunction(infoPtr->handle,
(DWORD) (flag ? SETDTR : CLRDTR))) {
|
| ︙ | ︙ |
Changes to win/tclWinTest.c.
| ︙ | ︙ | |||
633 634 635 636 637 638 639 |
static int
TestchmodCmd(
TCL_UNUSED(void *),
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Parameter count */
Tcl_Obj *const * objv) /* Parameter vector */
{
| | | | 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 |
static int
TestchmodCmd(
TCL_UNUSED(void *),
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Parameter count */
Tcl_Obj *const * objv) /* Parameter vector */
{
int mode;
if (objc < 2) {
Tcl_WrongNumArgs(interp, 1, objv, "mode file ?file ...?");
return TCL_ERROR;
}
if (Tcl_GetIntFromObj(interp, objv[1], &mode) != TCL_OK) {
return TCL_ERROR;
}
for (int i = 2; i < objc; i++) {
Tcl_DString buffer;
const char *translated;
translated = Tcl_TranslateFileName(interp, Tcl_GetString(objv[i]), &buffer);
if (translated == NULL) {
return TCL_ERROR;
}
|
| ︙ | ︙ |
Changes to win/tclWinTime.c.
| ︙ | ︙ | |||
1072 1073 1074 1075 1076 1077 1078 |
static void
ResetCounterSamples(
unsigned long long fileTime,/* Current file time */
long long perfCounter, /* Current performance counter */
long long perfFreq) /* Target performance frequency */
{
| < < | | 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 |
static void
ResetCounterSamples(
unsigned long long fileTime,/* Current file time */
long long perfCounter, /* Current performance counter */
long long perfFreq) /* Target performance frequency */
{
for (int i = SAMPLES - 1 ; i >= 0 ; --i) {
timeInfo.perfCounterSample[i] = perfCounter;
timeInfo.fileTimeSample[i] = fileTime;
perfCounter -= perfFreq;
fileTime -= 10000000;
}
timeInfo.sampleNo = 0;
}
|
| ︙ | ︙ |