Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch tip-431 Excluding Merge-Ins
This is equivalent to a diff from 2c56cc8106 to b1549abd3f
2019-05-25
| ||
07:46 | Implement TIP 431: [file tempdir] check-in: 974c5d161d user: dkf tags: core-8-branch | |
2019-05-17
| ||
10:40 | merge 8.6 check-in: 645515e90f user: sebres tags: core-8-branch | |
08:13 | Remove misleading comment in nroff source Closed-Leaf check-in: b1549abd3f user: dkf tags: tip-431 | |
08:09 | Add test for what happens when the directory in the template doesn't exist; doc it too. check-in: 92fce1400e user: dkf tags: tip-431 | |
07:31 | merge core-8-branch check-in: 8cdb898408 user: dkf tags: tip-431 | |
2019-05-15
| ||
14:58 | TIP #544 implementation. Documentation still missing. check-in: 13417ed7df user: jan.nijtmans tags: tip-544 | |
2019-05-14
| ||
19:28 | Merge 8.7 check-in: 26ddaf45e0 user: jan.nijtmans tags: trunk | |
19:26 | Merge 8.6 check-in: 2c56cc8106 user: jan.nijtmans tags: core-8-branch | |
19:13 | Merge 8.5 check-in: 3f4bd3bf4e user: jan.nijtmans tags: core-8-6-branch | |
10:31 | Tweak the unix build instructions; general cleanup of a few bits and fixing of old maintainer-only t... check-in: 3f32db392d user: dkf tags: core-8-branch | |
Changes to doc/file.n.
︙ | ︙ | |||
428 429 430 431 432 433 434 435 436 437 438 439 440 441 | \fBfile tail \fIname\fR . Returns all of the characters in the last filesystem component of \fIname\fR. Any trailing directory separator in \fIname\fR is ignored. If \fIname\fR contains no separators then returns \fIname\fR. So, \fBfile tail a/b\fR, \fBfile tail a/b/\fR and \fBfile tail b\fR all return \fBb\fR. .TP \fBfile tempfile\fR ?\fInameVar\fR? ?\fItemplate\fR? '\" TIP #210 .VS 8.6 Creates a temporary file and returns a read-write channel opened on that file. If the \fInameVar\fR is given, it specifies a variable that the name of the temporary file will be written into; if absent, Tcl will attempt to arrange | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 428 429 430 431 432 433 434 435 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 | \fBfile tail \fIname\fR . Returns all of the characters in the last filesystem component of \fIname\fR. Any trailing directory separator in \fIname\fR is ignored. If \fIname\fR contains no separators then returns \fIname\fR. So, \fBfile tail a/b\fR, \fBfile tail a/b/\fR and \fBfile tail b\fR all return \fBb\fR. .TP \fBfile tempdir\fR ?\fItemplate\fR? .VS "8.7, TIP 431" Creates a temporary directory (guaranteed to be newly created and writable by the current script) and returns its name. If \fItemplate\fR is given, it specifies one of or both of the existing directory (on a filesystem controlled by the operating system) to contain the temporary directory, and the base part of the directory name; it is considered to have the location of the directory if there is a directory separator in the name, and the base part is everything after the last directory separator (if non-empty). The default containing directory is determined by system-specific operations, and the default base name prefix is .QW \fBtcl\fR . .RS .PP The following output is typical and illustrative; the actual output will vary between platforms: .PP .CS % \fBfile tempdir\fR /var/tmp/tcl_u0kuy5 % \fBfile tempdir\fR /tmp/myapp /tmp/myapp_8o7r9L % \fBfile tempdir\fR /tmp/ /tmp/tcl_1mOJHD % \fBfile tempdir\fR myapp /var/tmp/myapp_0ihS0n .CE .RE .VE "8.7, TIP 431" .TP \fBfile tempfile\fR ?\fInameVar\fR? ?\fItemplate\fR? '\" TIP #210 .VS 8.6 Creates a temporary file and returns a read-write channel opened on that file. If the \fInameVar\fR is given, it specifies a variable that the name of the temporary file will be written into; if absent, Tcl will attempt to arrange |
︙ | ︙ |
Changes to generic/tclBasic.c.
︙ | ︙ | |||
362 363 364 365 366 367 368 369 370 371 372 373 374 375 | {"file", "readable"}, {"file", "readlink"}, {"file", "rename"}, {"file", "rootname"}, {"file", "size"}, {"file", "stat"}, {"file", "tail"}, {"file", "tempfile"}, {"file", "type"}, {"file", "volumes"}, {"file", "writable"}, /* [info] has two unsafe commands */ {"info", "cmdtype"}, {"info", "nameofexecutable"}, | > | 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 | {"file", "readable"}, {"file", "readlink"}, {"file", "rename"}, {"file", "rootname"}, {"file", "size"}, {"file", "stat"}, {"file", "tail"}, {"file", "tempdir"}, {"file", "tempfile"}, {"file", "type"}, {"file", "volumes"}, {"file", "writable"}, /* [info] has two unsafe commands */ {"info", "cmdtype"}, {"info", "nameofexecutable"}, |
︙ | ︙ |
Changes to generic/tclCmdAH.c.
︙ | ︙ | |||
1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 | {"rootname", PathRootNameCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1}, {"separator", FilesystemSeparatorCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0}, {"size", FileAttrSizeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1}, {"split", PathSplitCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0}, {"stat", FileAttrStatCmd, TclCompileBasic2ArgCmd, NULL, NULL, 1}, {"system", PathFilesystemCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0}, {"tail", PathTailCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1}, {"tempfile", TclFileTemporaryCmd, TclCompileBasic0To2ArgCmd, NULL, NULL, 1}, {"type", FileAttrTypeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1}, {"volumes", FilesystemVolumesCmd, TclCompileBasic0ArgCmd, NULL, NULL, 1}, {"writable", FileAttrIsWritableCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1}, {NULL, NULL, NULL, NULL, NULL, 0} }; return TclMakeEnsemble(interp, "file", initMap); | > | 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 | {"rootname", PathRootNameCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1}, {"separator", FilesystemSeparatorCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0}, {"size", FileAttrSizeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1}, {"split", PathSplitCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0}, {"stat", FileAttrStatCmd, TclCompileBasic2ArgCmd, NULL, NULL, 1}, {"system", PathFilesystemCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0}, {"tail", PathTailCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1}, {"tempdir", TclFileTempDirCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 1}, {"tempfile", TclFileTemporaryCmd, TclCompileBasic0To2ArgCmd, NULL, NULL, 1}, {"type", FileAttrTypeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1}, {"volumes", FilesystemVolumesCmd, TclCompileBasic0ArgCmd, NULL, NULL, 1}, {"writable", FileAttrIsWritableCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1}, {NULL, NULL, NULL, NULL, NULL, 0} }; return TclMakeEnsemble(interp, "file", initMap); |
︙ | ︙ |
Changes to generic/tclFCmd.c.
︙ | ︙ | |||
1341 1342 1343 1344 1345 1346 1347 | Tcl_DecrRefCount(contents); return TCL_OK; } /* *--------------------------------------------------------------------------- * | | | 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 | Tcl_DecrRefCount(contents); return TCL_OK; } /* *--------------------------------------------------------------------------- * * TclFileTemporaryCmd -- * * This function implements the "tempfile" subcommand of the "file" * command. * * Results: * Returns a standard Tcl result. * |
︙ | ︙ | |||
1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 | Tcl_UnregisterChannel(interp, chan); return TCL_ERROR; } } Tcl_SetObjResult(interp, Tcl_NewStringObj(Tcl_GetChannelName(chan), -1)); return TCL_OK; } /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * End: */ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 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 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 1650 1651 1652 1653 1654 1655 1656 1657 1658 | Tcl_UnregisterChannel(interp, chan); return TCL_ERROR; } } Tcl_SetObjResult(interp, Tcl_NewStringObj(Tcl_GetChannelName(chan), -1)); return TCL_OK; } /* *--------------------------------------------------------------------------- * * TclFileTempDirCmd -- * * This function implements the "tempdir" subcommand of the "file" * command. * * Results: * Returns a standard Tcl result. * * Side effects: * Creates a temporary directory. * *--------------------------------------------------------------------------- */ int TclFileTempDirCmd( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Tcl_Obj *dirNameObj; /* Object that will contain the directory * name. */ Tcl_Obj *baseDirObj = NULL, *nameBaseObj = NULL; /* Pieces of template. Each piece is NULL if * it is omitted. The platform temporary file * engine might ignore some pieces. */ if (objc < 1 || objc > 2) { Tcl_WrongNumArgs(interp, 1, objv, "?template?"); return TCL_ERROR; } if (objc > 1) { int length; Tcl_Obj *templateObj = objv[1]; const char *string = TclGetStringFromObj(templateObj, &length); const int onWindows = (tclPlatform == TCL_PLATFORM_WINDOWS); /* * Treat an empty string as if it wasn't there. */ if (length == 0) { goto makeTemporary; } /* * The template only gives a directory if there is a directory * separator in it, and only gives a base name if there's at least one * character after the last directory separator. */ if (strchr(string, '/') == NULL && (!onWindows || strchr(string, '\\') == NULL)) { /* * No directory separator, so just assume we have a file name. * This is a bit wrong on Windows where we could have problems * with disk name prefixes... but those are much less common in * naked form so we just pass through and let the OS figure it out * instead. */ nameBaseObj = templateObj; Tcl_IncrRefCount(nameBaseObj); } else if (string[length-1] != '/' && (!onWindows || string[length-1] != '\\')) { /* * If the template has a non-terminal directory separator, split * into dirname and tail. */ baseDirObj = TclPathPart(interp, templateObj, TCL_PATH_DIRNAME); nameBaseObj = TclPathPart(interp, templateObj, TCL_PATH_TAIL); } else { /* * Otherwise, there must be a terminal directory separator, so * just the directory is given. */ baseDirObj = templateObj; Tcl_IncrRefCount(baseDirObj); } /* * Only allow creation of temporary directories in the native * filesystem since they are frequently used for integration with * external tools or system libraries. */ if (baseDirObj != NULL && Tcl_FSGetFileSystemForPath(baseDirObj) != &tclNativeFilesystem) { TclDecrRefCount(baseDirObj); baseDirObj = NULL; } } /* * Convert empty parts of the template into unspecified parts. */ if (baseDirObj && !TclGetString(baseDirObj)[0]) { TclDecrRefCount(baseDirObj); baseDirObj = NULL; } if (nameBaseObj && !TclGetString(nameBaseObj)[0]) { TclDecrRefCount(nameBaseObj); nameBaseObj = NULL; } /* * Create and open the temporary file. */ makeTemporary: dirNameObj = TclpCreateTemporaryDirectory(baseDirObj, nameBaseObj); /* * If we created pieces of template, get rid of them now. */ if (baseDirObj) { TclDecrRefCount(baseDirObj); } if (nameBaseObj) { TclDecrRefCount(nameBaseObj); } /* * Deal with results. */ if (dirNameObj == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't create temporary directory: %s", Tcl_PosixError(interp))); return TCL_ERROR; } Tcl_SetObjResult(interp, dirNameObj); return TCL_OK; } /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * End: */ |
Changes to generic/tclInt.decls.
︙ | ︙ | |||
1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 | int TclPtrUnsetVar(Tcl_Interp *interp, Tcl_Var varPtr, Tcl_Var arrayPtr, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, const int flags) } declare 257 { void TclStaticPackage(Tcl_Interp *interp, const char *pkgName, Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc) } ############################################################################## # Define the platform specific internal Tcl interface. These functions are # only available on the designated platform. interface tclIntPlat | > > > > > > | 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 | int TclPtrUnsetVar(Tcl_Interp *interp, Tcl_Var varPtr, Tcl_Var arrayPtr, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, const int flags) } declare 257 { void TclStaticPackage(Tcl_Interp *interp, const char *pkgName, Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc) } # TIP 431: temporary directory creation function declare 258 { Tcl_Obj *TclpCreateTemporaryDirectory(Tcl_Obj *dirObj, Tcl_Obj *basenameObj) } ############################################################################## # Define the platform specific internal Tcl interface. These functions are # only available on the designated platform. interface tclIntPlat |
︙ | ︙ |
Changes to generic/tclInt.h.
︙ | ︙ | |||
2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 | MODULE_SCOPE Tcl_ObjCmdProc TclFileAttrsCmd; MODULE_SCOPE Tcl_ObjCmdProc TclFileCopyCmd; MODULE_SCOPE Tcl_ObjCmdProc TclFileDeleteCmd; MODULE_SCOPE Tcl_ObjCmdProc TclFileLinkCmd; MODULE_SCOPE Tcl_ObjCmdProc TclFileMakeDirsCmd; MODULE_SCOPE Tcl_ObjCmdProc TclFileReadLinkCmd; MODULE_SCOPE Tcl_ObjCmdProc TclFileRenameCmd; MODULE_SCOPE Tcl_ObjCmdProc TclFileTemporaryCmd; MODULE_SCOPE void TclCreateLateExitHandler(Tcl_ExitProc *proc, ClientData clientData); MODULE_SCOPE void TclDeleteLateExitHandler(Tcl_ExitProc *proc, ClientData clientData); MODULE_SCOPE char * TclDStringAppendObj(Tcl_DString *dsPtr, Tcl_Obj *objPtr); | > | 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 | MODULE_SCOPE Tcl_ObjCmdProc TclFileAttrsCmd; MODULE_SCOPE Tcl_ObjCmdProc TclFileCopyCmd; MODULE_SCOPE Tcl_ObjCmdProc TclFileDeleteCmd; MODULE_SCOPE Tcl_ObjCmdProc TclFileLinkCmd; MODULE_SCOPE Tcl_ObjCmdProc TclFileMakeDirsCmd; MODULE_SCOPE Tcl_ObjCmdProc TclFileReadLinkCmd; MODULE_SCOPE Tcl_ObjCmdProc TclFileRenameCmd; MODULE_SCOPE Tcl_ObjCmdProc TclFileTempDirCmd; MODULE_SCOPE Tcl_ObjCmdProc TclFileTemporaryCmd; MODULE_SCOPE void TclCreateLateExitHandler(Tcl_ExitProc *proc, ClientData clientData); MODULE_SCOPE void TclDeleteLateExitHandler(Tcl_ExitProc *proc, ClientData clientData); MODULE_SCOPE char * TclDStringAppendObj(Tcl_DString *dsPtr, Tcl_Obj *objPtr); |
︙ | ︙ |
Changes to generic/tclIntDecls.h.
︙ | ︙ | |||
649 650 651 652 653 654 655 656 657 658 659 660 661 662 | Tcl_Var arrayPtr, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, const int flags); /* 257 */ EXTERN void TclStaticPackage(Tcl_Interp *interp, const char *pkgName, Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc); typedef struct TclIntStubs { int magic; void *hooks; void (*reserved0)(void); void (*reserved1)(void); | > > > | 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 | Tcl_Var arrayPtr, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, const int flags); /* 257 */ EXTERN void TclStaticPackage(Tcl_Interp *interp, const char *pkgName, Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc); /* 258 */ EXTERN Tcl_Obj * TclpCreateTemporaryDirectory(Tcl_Obj *dirObj, Tcl_Obj *basenameObj); typedef struct TclIntStubs { int magic; void *hooks; void (*reserved0)(void); void (*reserved1)(void); |
︙ | ︙ | |||
912 913 914 915 916 917 918 919 920 921 922 923 924 925 | int (*tclRegisterLiteral) (void *envPtr, const char *bytes, int length, int flags); /* 251 */ Tcl_Obj * (*tclPtrGetVar) (Tcl_Interp *interp, Tcl_Var varPtr, Tcl_Var arrayPtr, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, const int flags); /* 252 */ Tcl_Obj * (*tclPtrSetVar) (Tcl_Interp *interp, Tcl_Var varPtr, Tcl_Var arrayPtr, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, Tcl_Obj *newValuePtr, const int flags); /* 253 */ Tcl_Obj * (*tclPtrIncrObjVar) (Tcl_Interp *interp, Tcl_Var varPtr, Tcl_Var arrayPtr, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, Tcl_Obj *incrPtr, const int flags); /* 254 */ int (*tclPtrObjMakeUpvar) (Tcl_Interp *interp, Tcl_Var otherPtr, Tcl_Obj *myNamePtr, int myFlags); /* 255 */ int (*tclPtrUnsetVar) (Tcl_Interp *interp, Tcl_Var varPtr, Tcl_Var arrayPtr, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, const int flags); /* 256 */ void (*tclStaticPackage) (Tcl_Interp *interp, const char *pkgName, Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc); /* 257 */ } TclIntStubs; extern const TclIntStubs *tclIntStubsPtr; #ifdef __cplusplus } #endif | > | 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 | int (*tclRegisterLiteral) (void *envPtr, const char *bytes, int length, int flags); /* 251 */ Tcl_Obj * (*tclPtrGetVar) (Tcl_Interp *interp, Tcl_Var varPtr, Tcl_Var arrayPtr, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, const int flags); /* 252 */ Tcl_Obj * (*tclPtrSetVar) (Tcl_Interp *interp, Tcl_Var varPtr, Tcl_Var arrayPtr, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, Tcl_Obj *newValuePtr, const int flags); /* 253 */ Tcl_Obj * (*tclPtrIncrObjVar) (Tcl_Interp *interp, Tcl_Var varPtr, Tcl_Var arrayPtr, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, Tcl_Obj *incrPtr, const int flags); /* 254 */ int (*tclPtrObjMakeUpvar) (Tcl_Interp *interp, Tcl_Var otherPtr, Tcl_Obj *myNamePtr, int myFlags); /* 255 */ int (*tclPtrUnsetVar) (Tcl_Interp *interp, Tcl_Var varPtr, Tcl_Var arrayPtr, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, const int flags); /* 256 */ void (*tclStaticPackage) (Tcl_Interp *interp, const char *pkgName, Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc); /* 257 */ Tcl_Obj * (*tclpCreateTemporaryDirectory) (Tcl_Obj *dirObj, Tcl_Obj *basenameObj); /* 258 */ } TclIntStubs; extern const TclIntStubs *tclIntStubsPtr; #ifdef __cplusplus } #endif |
︙ | ︙ | |||
1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 | (tclIntStubsPtr->tclPtrIncrObjVar) /* 254 */ #define TclPtrObjMakeUpvar \ (tclIntStubsPtr->tclPtrObjMakeUpvar) /* 255 */ #define TclPtrUnsetVar \ (tclIntStubsPtr->tclPtrUnsetVar) /* 256 */ #define TclStaticPackage \ (tclIntStubsPtr->tclStaticPackage) /* 257 */ #endif /* defined(USE_TCL_STUBS) */ /* !END!: Do not edit above this line. */ #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT | > > | 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 | (tclIntStubsPtr->tclPtrIncrObjVar) /* 254 */ #define TclPtrObjMakeUpvar \ (tclIntStubsPtr->tclPtrObjMakeUpvar) /* 255 */ #define TclPtrUnsetVar \ (tclIntStubsPtr->tclPtrUnsetVar) /* 256 */ #define TclStaticPackage \ (tclIntStubsPtr->tclStaticPackage) /* 257 */ #define TclpCreateTemporaryDirectory \ (tclIntStubsPtr->tclpCreateTemporaryDirectory) /* 258 */ #endif /* defined(USE_TCL_STUBS) */ /* !END!: Do not edit above this line. */ #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT |
︙ | ︙ |
Changes to generic/tclStubInit.c.
︙ | ︙ | |||
747 748 749 750 751 752 753 754 755 756 757 758 759 760 | TclRegisterLiteral, /* 251 */ TclPtrGetVar, /* 252 */ TclPtrSetVar, /* 253 */ TclPtrIncrObjVar, /* 254 */ TclPtrObjMakeUpvar, /* 255 */ TclPtrUnsetVar, /* 256 */ TclStaticPackage, /* 257 */ }; static const TclIntPlatStubs tclIntPlatStubs = { TCL_STUB_MAGIC, 0, #if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* UNIX */ TclGetAndDetachPids, /* 0 */ | > | 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 | TclRegisterLiteral, /* 251 */ TclPtrGetVar, /* 252 */ TclPtrSetVar, /* 253 */ TclPtrIncrObjVar, /* 254 */ TclPtrObjMakeUpvar, /* 255 */ TclPtrUnsetVar, /* 256 */ TclStaticPackage, /* 257 */ TclpCreateTemporaryDirectory, /* 258 */ }; static const TclIntPlatStubs tclIntPlatStubs = { TCL_STUB_MAGIC, 0, #if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* UNIX */ TclGetAndDetachPids, /* 0 */ |
︙ | ︙ |
Changes to tests/cmdAH.test.
︙ | ︙ | |||
231 232 233 234 235 236 237 | } -result iso8859-1 test cmdAH-5.1 {Tcl_FileObjCmd} -returnCodes error -body { file } -result {wrong # args: should be "file subcommand ?arg ...?"} test cmdAH-5.2 {Tcl_FileObjCmd} -returnCodes error -body { file x | | | 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 | } -result iso8859-1 test cmdAH-5.1 {Tcl_FileObjCmd} -returnCodes error -body { file } -result {wrong # args: should be "file subcommand ?arg ...?"} test cmdAH-5.2 {Tcl_FileObjCmd} -returnCodes error -body { file x } -result {unknown or ambiguous subcommand "x": must be atime, attributes, channels, copy, delete, dirname, executable, exists, extension, isdirectory, isfile, join, link, lstat, mkdir, mtime, nativename, normalize, owned, pathtype, readable, readlink, rename, rootname, separator, size, split, stat, system, tail, tempdir, tempfile, type, volumes, or writable} test cmdAH-5.3 {Tcl_FileObjCmd} -returnCodes error -body { file exists } -result {wrong # args: should be "file exists name"} test cmdAH-5.4 {Tcl_FileObjCmd} { file exists "" } 0 |
︙ | ︙ | |||
1522 1523 1524 1525 1526 1527 1528 | } set res } -result "characterSpecial" # Error conditions test cmdAH-30.1 {Tcl_FileObjCmd: error conditions} -returnCodes error -body { file gorp x | | | 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 | } set res } -result "characterSpecial" # Error conditions test cmdAH-30.1 {Tcl_FileObjCmd: error conditions} -returnCodes error -body { file gorp x } -result {unknown or ambiguous subcommand "gorp": must be atime, attributes, channels, copy, delete, dirname, executable, exists, extension, isdirectory, isfile, join, link, lstat, mkdir, mtime, nativename, normalize, owned, pathtype, readable, readlink, rename, rootname, separator, size, split, stat, system, tail, tempdir, tempfile, type, volumes, or writable} test cmdAH-30.2 {Tcl_FileObjCmd: error conditions} -returnCodes error -body { file ex x } -match glob -result {unknown or ambiguous subcommand "ex": must be *} test cmdAH-30.3 {Tcl_FileObjCmd: error conditions} -returnCodes error -body { file is x } -match glob -result {unknown or ambiguous subcommand "is": must be *} test cmdAH-30.4 {Tcl_FileObjCmd: error conditions} -returnCodes error -body { |
︙ | ︙ | |||
1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 | set template [file join $dirfile foo] close [file tempfile name $template.bar] expr {[string match $template*.bar $name] ? "ok" : "$template.bar produced $name"} } -constraints {unix nonPortable} -cleanup { catch {file delete $name} } -result ok # This shouldn't work, but just in case a test above failed... catch {close $newFileId} interp delete safeInterp interp delete simpleInterp | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 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 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 | set template [file join $dirfile foo] close [file tempfile name $template.bar] expr {[string match $template*.bar $name] ? "ok" : "$template.bar produced $name"} } -constraints {unix nonPortable} -cleanup { catch {file delete $name} } -result ok test cmdAH-33.1 {file tempdir} -body { file tempdir a b } -returnCodes error -result {wrong # args: should be "file tempdir ?template?"} test cmdAH-33.2 {file tempdir} -body { set d [file tempdir] list [file tail $d] [file exists $d] [file type $d] \ [glob -nocomplain -directory $d *] } -match glob -result {tcl_* 1 directory {}} -cleanup { catch {file delete $d} } test cmdAH-33.3 {file tempdir} -body { set d [file tempdir gorp] list [file tail $d] [file exists $d] [file type $d] \ [glob -nocomplain -directory $d *] } -match glob -result {gorp_* 1 directory {}} -cleanup { catch {file delete $d} } test cmdAH-33.4 {file tempdir} -setup { set base [file join [temporaryDirectory] gorp] file mkdir $base } -body { set pre [glob -nocomplain -directory $base *] set d [file normalize [file tempdir $base/]] list [string map [list $base GORP:] $d] [file exists $d] [file type $d] \ $pre [glob -nocomplain -directory $d *] } -match glob -result {GORP:/tcl_* 1 directory {} {}} -cleanup { catch {file delete -force $base} } test cmdAH-33.5 {file tempdir} -setup { set base [file join [temporaryDirectory] gorp] file mkdir $base } -body { set pre [glob -nocomplain -directory $base *] set d [file normalize [file tempdir $base/gorp]] list [string map [list $base GORP:] $d] [file exists $d] [file type $d] \ $pre [glob -nocomplain -directory $d *] } -match glob -result {GORP:/gorp_* 1 directory {} {}} -cleanup { catch {file delete -force $base} } test cmdAH-33.6 {file tempdir: missing parent dir} -setup { set base [file join [temporaryDirectory] gorp] file mkdir $base } -returnCodes error -body { file tempdir $base/quux/ } -cleanup { catch {file delete -force $base} } -result {can't create temporary directory: no such file or directory} test cmdAH-33.7 {file tempdir: missing parent dir} -setup { set base [file join [temporaryDirectory] gorp] file mkdir $base } -returnCodes error -body { file tempdir $base/quux/foobar } -cleanup { catch {file delete -force $base} } -result {can't create temporary directory: no such file or directory} # This shouldn't work, but just in case a test above failed... catch {close $newFileId} interp delete safeInterp interp delete simpleInterp |
︙ | ︙ |
Changes to tests/interp.test.
︙ | ︙ | |||
16 17 18 19 20 21 22 | } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] testConstraint testinterpdelete [llength [info commands testinterpdelete]] | | | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | } ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] testConstraint testinterpdelete [llength [info commands testinterpdelete]] set hidden_cmds {cd encoding exec exit fconfigure file glob load open pwd socket source tcl:encoding:dirs tcl:encoding:system tcl:file:atime tcl:file:attributes tcl:file:copy tcl:file:delete tcl:file:dirname tcl:file:executable tcl:file:exists tcl:file:extension tcl:file:isdirectory tcl:file:isfile tcl:file:link tcl:file:lstat tcl:file:mkdir tcl:file:mtime tcl:file:nativename tcl:file:normalize tcl:file:owned tcl:file:readable tcl:file:readlink tcl:file:rename tcl:file:rootname tcl:file:size tcl:file:stat tcl:file:tail tcl:file:tempdir tcl:file:tempfile tcl:file:type tcl:file:volumes tcl:file:writable tcl:info:cmdtype tcl:info:nameofexecutable tcl:process:autopurge tcl:process:list tcl:process:purge tcl:process:status tcl:zipfs:lmkimg tcl:zipfs:lmkzip tcl:zipfs:mkimg tcl:zipfs:mkkey tcl:zipfs:mkzip tcl:zipfs:mount tcl:zipfs:mount_data tcl:zipfs:unmount unload} foreach i [interp slaves] { interp delete $i } # Part 0: Check out options for interp command test interp-1.1 {options for interp command} -returnCodes error -body { |
︙ | ︙ |
Changes to unix/tclUnixFCmd.c.
︙ | ︙ | |||
2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 | * Assume that the default location ("/tmp" if not overridden) is always * an existing writable directory; we've no recovery mechanism if it * isn't. */ return TCL_TEMPORARY_FILE_DIRECTORY; } #if defined(__CYGWIN__) static void StatError( Tcl_Interp *interp, /* The interp that has the error */ Tcl_Obj *fileName) /* The name of the file which caused the | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 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 | * Assume that the default location ("/tmp" if not overridden) is always * an existing writable directory; we've no recovery mechanism if it * isn't. */ return TCL_TEMPORARY_FILE_DIRECTORY; } /* *---------------------------------------------------------------------- * * TclpCreateTemporaryDirectory -- * * Creates a temporary directory, possibly based on the supplied bits and * pieces of template supplied in the arguments. * * Results: * An object (refcount 0) containing the name of the newly-created * directory, or NULL on failure. * * Side effects: * Accesses the native filesystem. Makes a directory. * *---------------------------------------------------------------------- */ Tcl_Obj * TclpCreateTemporaryDirectory( Tcl_Obj *dirObj, Tcl_Obj *basenameObj) { Tcl_DString template, tmp; const char *string; #define DEFAULT_TEMP_DIR_PREFIX "tcl" /* * Build the template in writable memory from the user-supplied pieces and * some defaults. */ if (dirObj) { string = TclGetString(dirObj); Tcl_UtfToExternalDString(NULL, string, dirObj->length, &template); } else { Tcl_DStringInit(&template); Tcl_DStringAppend(&template, DefaultTempDir(), -1); /* INTL: native */ } if (Tcl_DStringValue(&template)[Tcl_DStringLength(&template) - 1] != '/') { TclDStringAppendLiteral(&template, "/"); } if (basenameObj) { string = TclGetString(basenameObj); if (basenameObj->length) { Tcl_UtfToExternalDString(NULL, string, basenameObj->length, &tmp); TclDStringAppendDString(&template, &tmp); Tcl_DStringFree(&tmp); } else { TclDStringAppendLiteral(&template, DEFAULT_TEMP_DIR_PREFIX); } } else { TclDStringAppendLiteral(&template, DEFAULT_TEMP_DIR_PREFIX); } TclDStringAppendLiteral(&template, "_XXXXXX"); /* * Make the temporary directory. */ if (mkdtemp(Tcl_DStringValue(&template)) == NULL) { Tcl_DStringFree(&template); return NULL; } /* * The template has been updated. Tell the caller what it was. */ Tcl_ExternalToUtfDString(NULL, Tcl_DStringValue(&template), Tcl_DStringLength(&template), &tmp); Tcl_DStringFree(&template); return TclDStringToObj(&tmp); } #if defined(__CYGWIN__) static void StatError( Tcl_Interp *interp, /* The interp that has the error */ Tcl_Obj *fileName) /* The name of the file which caused the |
︙ | ︙ |
Changes to win/tclWinFCmd.c.
︙ | ︙ | |||
1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 | Tcl_ListObjAppendElement(NULL, resultPtr, elemPtr); } } Tcl_IncrRefCount(resultPtr); return resultPtr; } /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * End: | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1951 1952 1953 1954 1955 1956 1957 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 1983 1984 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 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 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 | Tcl_ListObjAppendElement(NULL, resultPtr, elemPtr); } } Tcl_IncrRefCount(resultPtr); return resultPtr; } /* *---------------------------------------------------------------------- * * TclpCreateTemporaryDirectory -- * * Creates a temporary directory, possibly based on the supplied bits and * pieces of template supplied in the arguments. * * Results: * An object (refcount 0) containing the name of the newly-created * directory, or NULL on failure. * * Side effects: * Accesses the native filesystem. Makes a directory. * *---------------------------------------------------------------------- */ Tcl_Obj * TclpCreateTemporaryDirectory( Tcl_Obj *dirObj, Tcl_Obj *basenameObj) { Tcl_DString base, name; /* Contains WCHARs */ int baseLen; DWORD error; WCHAR tempBuf[MAX_PATH + 1]; DWORD len = GetTempPathW(MAX_PATH, tempBuf); /* * Build the path in writable memory from the user-supplied pieces and * some defaults. First, the parent temporary directory. */ if (dirObj) { Tcl_GetString(dirObj); if (dirObj->length < 1) { goto useSystemTemp; } Tcl_WinUtfToTChar(Tcl_GetString(dirObj), -1, &base); if (dirObj->bytes[dirObj->length - 1] != '\\') { TclUtfToWCharDString("\\", -1, &base); } } else { useSystemTemp: Tcl_DStringInit(&base); Tcl_DStringAppend(&base, (char *) tempBuf, len * sizeof(WCHAR)); } /* * Next, the base of the directory name. */ #define DEFAULT_TEMP_DIR_PREFIX "tcl" #define SUFFIX_LENGTH 8 if (basenameObj) { Tcl_WinUtfToTChar(Tcl_GetString(basenameObj), -1, &name); TclDStringAppendDString(&base, &name); Tcl_DStringFree(&name); } else { TclUtfToWCharDString(DEFAULT_TEMP_DIR_PREFIX, -1, &base); } TclUtfToWCharDString("_", -1, &base); /* * Now we keep on trying random suffixes until we get one that works * (i.e., that doesn't trigger the ERROR_ALREADY_EXISTS error). Note that * 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]; int i; 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 (i = 0 ; i < SUFFIX_LENGTH; i++) { tempbuf[i] = randChars[(int) (rand() % numRandChars)]; } Tcl_DStringSetLength(&base, baseLen); TclUtfToWCharDString(tempbuf, -1, &base); } while (!CreateDirectoryW((LPCWSTR) Tcl_DStringValue(&base), NULL) && (error = GetLastError()) == ERROR_ALREADY_EXISTS); /* * Check for other errors. The big ones are ERROR_PATH_NOT_FOUND and * ERROR_ACCESS_DENIED. */ if (error != ERROR_SUCCESS) { TclWinConvertError(error); Tcl_DStringFree(&base); return NULL; } /* * We actually made the directory, so we're done! Report what we made back * as a (clean) Tcl_Obj. */ Tcl_WinTCharToUtf((LPCWSTR) Tcl_DStringValue(&base), -1, &name); Tcl_DStringFree(&base); return TclDStringToObj(&name); } /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * End: |
︙ | ︙ |