Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | TIP 701 - Tcl_FSTildeExpand C API |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | core-8-branch |
Files: | files | file ages | folders |
SHA3-256: |
c2f3dbddd9af563f536e5506558b75dd |
User & Date: | apnadkarni 2024-10-30 11:38:45.459 |
Context
2024-10-31
| ||
13:30 | merge 8.6 (clock: load TZ failure normalization and test coverage) check-in: f788320fc9 user: sebres tags: core-8-branch | |
2024-10-30
| ||
12:24 | Merge 8.7 - TIP 701 - Tcl_FSTildeExpand C API check-in: ecb2b9d3b5 user: apnadkarni tags: trunk, main | |
11:38 | TIP 701 - Tcl_FSTildeExpand C API check-in: c2f3dbddd9 user: apnadkarni tags: core-8-branch | |
11:24 | Add Tcl_FSTildeExpand manpage. Do not depend on caller to clean up output DString on error Closed-Leaf check-in: 321a559f8c user: apnadkarni tags: tip-701 | |
2024-10-29
| ||
18:37 | merge 8.6: fixes regression and further bug [2c237beffbace823] check-in: 5f73876fe7 user: sebres tags: core-8-branch | |
Changes
Changes to doc/FileSystem.3.
1 2 3 4 5 6 7 8 9 10 11 | '\" '\" Copyright (c) 2001 Vincent Darley '\" Copyright (c) 2008-2010 Donal K. Fellows '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" .TH Filesystem 3 8.4 Tcl "Tcl Library Procedures" .so man.macros .BS .SH NAME | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | '\" '\" Copyright (c) 2001 Vincent Darley '\" Copyright (c) 2008-2010 Donal K. Fellows '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" .TH Filesystem 3 8.4 Tcl "Tcl Library Procedures" .so man.macros .BS .SH NAME Tcl_FSRegister, Tcl_FSUnregister, Tcl_FSData, Tcl_FSMountsChanged, Tcl_FSGetFileSystemForPath, Tcl_FSGetPathType, Tcl_FSCopyFile, Tcl_FSCopyDirectory, Tcl_FSCreateDirectory, Tcl_FSDeleteFile, Tcl_FSRemoveDirectory, Tcl_FSRenameFile, Tcl_FSListVolumes, Tcl_FSEvalFile, Tcl_FSEvalFileEx, Tcl_FSLoadFile, Tcl_FSUnloadFile, Tcl_FSMatchInDirectory, Tcl_FSLink, Tcl_FSLstat, Tcl_FSUtime, Tcl_FSFileAttrsGet, Tcl_FSFileAttrsSet, Tcl_FSFileAttrStrings, Tcl_FSStat, Tcl_FSAccess, Tcl_FSOpenFileChannel, Tcl_FSGetCwd, Tcl_FSChdir, Tcl_FSPathSeparator, Tcl_FSJoinPath, Tcl_FSSplitPath, Tcl_FSEqualPaths, Tcl_FSGetNormalizedPath, Tcl_FSJoinToPath, Tcl_FSConvertToPathType, Tcl_FSGetInternalRep, Tcl_FSGetTranslatedPath, Tcl_FSGetTranslatedStringPath, Tcl_FSNewNativePath, Tcl_FSGetNativePath, Tcl_FSFileSystemInfo, Tcl_GetAccessTimeFromStat, Tcl_GetBlockSizeFromStat, Tcl_GetBlocksFromStat, Tcl_GetChangeTimeFromStat, Tcl_GetDeviceTypeFromStat, Tcl_GetFSDeviceFromStat, Tcl_GetFSInodeFromStat, Tcl_GetGroupIdFromStat, Tcl_GetLinkCountFromStat, Tcl_GetModeFromStat, Tcl_GetModificationTimeFromStat, Tcl_GetSizeFromStat, Tcl_GetUserIdFromStat, Tcl_AllocStatBuf, Tcl_FSTildeExpand \- procedures to interact with any filesystem .SH SYNOPSIS .nf \fB#include <tcl.h>\fR .sp int \fBTcl_FSRegister\fR(\fIclientData, fsPtr\fR) .sp |
︙ | ︙ | |||
136 137 138 139 140 141 142 143 144 145 146 147 148 149 | .sp const void * \fBTcl_FSGetNativePath\fR(\fIpathPtr\fR) .sp Tcl_Obj * \fBTcl_FSFileSystemInfo\fR(\fIpathPtr\fR) .sp Tcl_StatBuf * \fBTcl_AllocStatBuf\fR() .sp long long \fBTcl_GetAccessTimeFromStat\fR(\fIstatPtr\fR) .sp unsigned | > > > | 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | .sp const void * \fBTcl_FSGetNativePath\fR(\fIpathPtr\fR) .sp Tcl_Obj * \fBTcl_FSFileSystemInfo\fR(\fIpathPtr\fR) .sp int \fBTcl_FSTildeExpand\fR(\fIinterp, pathStr, dsPtr\fR) .sp Tcl_StatBuf * \fBTcl_AllocStatBuf\fR() .sp long long \fBTcl_GetAccessTimeFromStat\fR(\fIstatPtr\fR) .sp unsigned |
︙ | ︙ | |||
183 184 185 186 187 188 189 190 191 192 193 194 195 196 | \fBTcl_GetUserIdFromStat\fR(\fIstatPtr\fR) .fi .SH ARGUMENTS .AS Tcl_GlobTypeData **srcPathPtr out .AP "const Tcl_Filesystem" *fsPtr in Points to a structure containing the addresses of procedures that can be called to perform the various filesystem operations. .AP Tcl_Obj *pathPtr in The path represented by this value is used for the operation in question. If the value does not already have an internal \fBpath\fR representation, it will be converted to have one. .AP Tcl_Obj *srcPathPtr in As for \fIpathPtr\fR, but used for the source file for a copy or rename operation. | > > | 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 | \fBTcl_GetUserIdFromStat\fR(\fIstatPtr\fR) .fi .SH ARGUMENTS .AS Tcl_GlobTypeData **srcPathPtr out .AP "const Tcl_Filesystem" *fsPtr in Points to a structure containing the addresses of procedures that can be called to perform the various filesystem operations. .AP "const char" *pathStr in Pointer to a NUL terminated string representing a file system path. .AP Tcl_Obj *pathPtr in The path represented by this value is used for the operation in question. If the value does not already have an internal \fBpath\fR representation, it will be converted to have one. .AP Tcl_Obj *srcPathPtr in As for \fIpathPtr\fR, but used for the source file for a copy or rename operation. |
︙ | ︙ | |||
285 286 287 288 289 290 291 292 293 294 295 296 297 298 | the symbolic link specified by \fIlinkNamePtr\fR is to be read. .AP int linkAction in OR-ed combination of flags indicating what kind of link should be created (will be ignored if \fItoPtr\fR is NULL). Valid bits to set are \fBTCL_CREATE_SYMBOLIC_LINK\fR and \fBTCL_CREATE_HARD_LINK\fR. When both flags are set and the underlying filesystem can do either, symbolic links are preferred. .BE .SH DESCRIPTION .PP There are several reasons for calling the \fBTcl_FS\fR API functions (e.g.\ \fBTcl_FSAccess\fR and \fBTcl_FSStat\fR) rather than calling system level functions like \fBaccess\fR and \fBstat\fR directly. First, they will work cross-platform, so an | > > | 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 | the symbolic link specified by \fIlinkNamePtr\fR is to be read. .AP int linkAction in OR-ed combination of flags indicating what kind of link should be created (will be ignored if \fItoPtr\fR is NULL). Valid bits to set are \fBTCL_CREATE_SYMBOLIC_LINK\fR and \fBTCL_CREATE_HARD_LINK\fR. When both flags are set and the underlying filesystem can do either, symbolic links are preferred. .AP Tcl_DString *dsPtr out Pointer to a \fBTcl_DString\fR to hold an output string result. .BE .SH DESCRIPTION .PP There are several reasons for calling the \fBTcl_FS\fR API functions (e.g.\ \fBTcl_FSAccess\fR and \fBTcl_FSStat\fR) rather than calling system level functions like \fBaccess\fR and \fBstat\fR directly. First, they will work cross-platform, so an |
︙ | ︙ | |||
783 784 785 786 787 788 789 790 791 792 793 794 795 796 | .PP \fBTcl_FSGetPathType\fR determines whether the given path is relative to the current directory, relative to the current volume, or absolute. .PP It returns one of \fBTCL_PATH_ABSOLUTE\fR, \fBTCL_PATH_RELATIVE\fR, or \fBTCL_PATH_VOLUME_RELATIVE\fR .SS "PORTABLE STAT RESULT API" .PP \fBTcl_AllocStatBuf\fR allocates a \fITcl_StatBuf\fR on the system heap (which may be deallocated by being passed to \fBckfree\fR). This allows extensions to invoke \fBTcl_FSStat\fR and \fBTcl_FSLstat\fR without being dependent on the size of the buffer. That in turn depends on the flags used to build Tcl. .PP | > > > > > > > > > > > | 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 | .PP \fBTcl_FSGetPathType\fR determines whether the given path is relative to the current directory, relative to the current volume, or absolute. .PP It returns one of \fBTCL_PATH_ABSOLUTE\fR, \fBTCL_PATH_RELATIVE\fR, or \fBTCL_PATH_VOLUME_RELATIVE\fR .PP \fBTcl_FSTildeExpand\fR performs tilde substitution on the input path passed via \fBpathStr\fR as described in the documentation for the \fBfile tildeexpand\fR Tcl command. On success, the function returns \fBTCL_OK\fR with the result of the substitution in \fBdsPtr\fR which must be subsequently freed by the caller. The \fBdsPtr\fR structure is initialized by the function. No guarantees are made about the form of the returned path such as the path separators used. The returned result should be passed to other Tcl C API functions such as \fBTcl_FSGetNormalizedPath\fR or \fBTcl_FSGetNativePath\fR if necessary. On error, the function returns \fBTCL_ERROR\fR with an error message in \fBinterp\fR which may be passed as NULL if error messages are not of interest. .SS "PORTABLE STAT RESULT API" .PP \fBTcl_AllocStatBuf\fR allocates a \fITcl_StatBuf\fR on the system heap (which may be deallocated by being passed to \fBckfree\fR). This allows extensions to invoke \fBTcl_FSStat\fR and \fBTcl_FSLstat\fR without being dependent on the size of the buffer. That in turn depends on the flags used to build Tcl. .PP |
︙ | ︙ |
Changes to generic/tcl.decls.
︙ | ︙ | |||
2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 | } declare 655 { const char *Tcl_UtfNext(const char *src) } declare 656 { const char *Tcl_UtfPrev(const char *src, const char *start) } # TIP 656 declare 658 { int Tcl_ExternalToUtfDStringEx(Tcl_Interp *interp, Tcl_Encoding encoding, const char *src, Tcl_Size srcLen, int flags, Tcl_DString *dsPtr, Tcl_Size *errorLocationPtr) } | > > > > > > | 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 | } declare 655 { const char *Tcl_UtfNext(const char *src) } declare 656 { const char *Tcl_UtfPrev(const char *src, const char *start) } # TIP 701 declare 657 { int Tcl_FSTildeExpand(Tcl_Interp *interp, const char *path, Tcl_DString *dsPtr) } # TIP 656 declare 658 { int Tcl_ExternalToUtfDStringEx(Tcl_Interp *interp, Tcl_Encoding encoding, const char *src, Tcl_Size srcLen, int flags, Tcl_DString *dsPtr, Tcl_Size *errorLocationPtr) } |
︙ | ︙ |
Changes to generic/tclDecls.h.
︙ | ︙ | |||
1944 1945 1946 1947 1948 1949 1950 | /* Slot 653 is reserved */ /* 654 */ EXTERN int Tcl_UtfCharComplete(const char *src, Tcl_Size length); /* 655 */ EXTERN const char * Tcl_UtfNext(const char *src); /* 656 */ EXTERN const char * Tcl_UtfPrev(const char *src, const char *start); | | > > | 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 | /* Slot 653 is reserved */ /* 654 */ EXTERN int Tcl_UtfCharComplete(const char *src, Tcl_Size length); /* 655 */ EXTERN const char * Tcl_UtfNext(const char *src); /* 656 */ EXTERN const char * Tcl_UtfPrev(const char *src, const char *start); /* 657 */ EXTERN int Tcl_FSTildeExpand(Tcl_Interp *interp, const char *path, Tcl_DString *dsPtr); /* 658 */ EXTERN int Tcl_ExternalToUtfDStringEx(Tcl_Interp *interp, Tcl_Encoding encoding, const char *src, Tcl_Size srcLen, int flags, Tcl_DString *dsPtr, Tcl_Size *errorLocationPtr); /* 659 */ |
︙ | ︙ | |||
2712 2713 2714 2715 2716 2717 2718 | void (*reserved650)(void); void (*reserved651)(void); void (*reserved652)(void); void (*reserved653)(void); int (*tcl_UtfCharComplete) (const char *src, Tcl_Size length); /* 654 */ const char * (*tcl_UtfNext) (const char *src); /* 655 */ const char * (*tcl_UtfPrev) (const char *src, const char *start); /* 656 */ | | | 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 | void (*reserved650)(void); void (*reserved651)(void); void (*reserved652)(void); void (*reserved653)(void); int (*tcl_UtfCharComplete) (const char *src, Tcl_Size length); /* 654 */ const char * (*tcl_UtfNext) (const char *src); /* 655 */ const char * (*tcl_UtfPrev) (const char *src, const char *start); /* 656 */ int (*tcl_FSTildeExpand) (Tcl_Interp *interp, const char *path, Tcl_DString *dsPtr); /* 657 */ int (*tcl_ExternalToUtfDStringEx) (Tcl_Interp *interp, Tcl_Encoding encoding, const char *src, Tcl_Size srcLen, int flags, Tcl_DString *dsPtr, Tcl_Size *errorLocationPtr); /* 658 */ int (*tcl_UtfToExternalDStringEx) (Tcl_Interp *interp, Tcl_Encoding encoding, const char *src, Tcl_Size srcLen, int flags, Tcl_DString *dsPtr, Tcl_Size *errorLocationPtr); /* 659 */ int (*tcl_AsyncMarkFromSignal) (Tcl_AsyncHandler async, int sigNumber); /* 660 */ void (*reserved661)(void); void (*reserved662)(void); void (*reserved663)(void); void (*reserved664)(void); |
︙ | ︙ | |||
4086 4087 4088 4089 4090 4091 4092 | /* Slot 653 is reserved */ #define Tcl_UtfCharComplete \ (tclStubsPtr->tcl_UtfCharComplete) /* 654 */ #define Tcl_UtfNext \ (tclStubsPtr->tcl_UtfNext) /* 655 */ #define Tcl_UtfPrev \ (tclStubsPtr->tcl_UtfPrev) /* 656 */ | > | | 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 | /* Slot 653 is reserved */ #define Tcl_UtfCharComplete \ (tclStubsPtr->tcl_UtfCharComplete) /* 654 */ #define Tcl_UtfNext \ (tclStubsPtr->tcl_UtfNext) /* 655 */ #define Tcl_UtfPrev \ (tclStubsPtr->tcl_UtfPrev) /* 656 */ #define Tcl_FSTildeExpand \ (tclStubsPtr->tcl_FSTildeExpand) /* 657 */ #define Tcl_ExternalToUtfDStringEx \ (tclStubsPtr->tcl_ExternalToUtfDStringEx) /* 658 */ #define Tcl_UtfToExternalDStringEx \ (tclStubsPtr->tcl_UtfToExternalDStringEx) /* 659 */ #define Tcl_AsyncMarkFromSignal \ (tclStubsPtr->tcl_AsyncMarkFromSignal) /* 660 */ /* Slot 661 is reserved */ |
︙ | ︙ |
Changes to generic/tclPathObj.c.
︙ | ︙ | |||
2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 | } return Tcl_DStringToObj(&dirString); } /* *---------------------------------------------------------------------- * * TclResolveTildePath -- * * If the passed path is begins with a tilde, does tilde resolution * and returns a Tcl_Obj containing the resolved path. If the tilde * component cannot be resolved, returns NULL. If the path does not * begin with a tilde, returns as is. * | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 | } return Tcl_DStringToObj(&dirString); } /* *---------------------------------------------------------------------- * * Tcl_FSTildeExpand -- * * Copies the path passed in to the output Tcl_DString dsPtr, * resolving leading ~ and ~user components in the path if present. * An error is returned if such a component IS present AND cannot * be resolved. * * The output dsPtr must be cleared by caller on success. * * Results: * TCL_OK - path did not contain leading ~ or it was successful resolved * TCL_ERROR - ~ component could not be resolved. * *---------------------------------------------------------------------- */ int Tcl_FSTildeExpand( Tcl_Interp *interp, /* May be NULL. Only used for error messages */ const char *path, /* Path to resolve tilde */ Tcl_DString *dsPtr) /* Output DString for resolved path. */ { Tcl_Size split; int result; assert(path); assert(dsPtr); Tcl_DStringInit(dsPtr); if (path[0] != '~') { Tcl_DStringAppend(dsPtr, path, -1); return TCL_OK; } /* * We have multiple cases '~', '~user', '~/foo/bar...', '~user/foo...' * FindSplitPos returns 1 for '~/...' as well as for '~'. Note on * Windows FindSplitPos implicitly checks for '\' as separator * in addition to what is passed. */ split = FindSplitPos(path, '/'); if (split == 1) { /* No user name specified '~' or '~/...' -> current user */ result = MakeTildeRelativePath(interp, NULL, path[1] ? 2 + path : NULL, dsPtr); } else { /* User name specified - ~user, ~user/... */ const char *user; Tcl_DString dsUser; Tcl_DStringInit(&dsUser); Tcl_DStringAppend(&dsUser, path+1, split-1); user = Tcl_DStringValue(&dsUser); /* path[split] is / for ~user/... or \0 for ~user */ result = MakeTildeRelativePath(interp, user, path[split] ? &path[split + 1] : NULL, dsPtr); Tcl_DStringFree(&dsUser); } if (result != TCL_OK) { /* Do not rely on caller to free in case of errors */ Tcl_DStringFree(dsPtr); } return result; } /* *---------------------------------------------------------------------- * * TclResolveTildePath -- * * If the passed path is begins with a tilde, does tilde resolution * and returns a Tcl_Obj containing the resolved path. If the tilde * component cannot be resolved, returns NULL. If the path does not * begin with a tilde, returns as is. * |
︙ | ︙ | |||
2708 2709 2710 2711 2712 2713 2714 | */ Tcl_Obj * TclResolveTildePath( Tcl_Interp *interp, /* May be NULL. Only used for error messages */ Tcl_Obj *pathObj) { const char *path; | | < > < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < | | < | | 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 | */ Tcl_Obj * TclResolveTildePath( Tcl_Interp *interp, /* May be NULL. Only used for error messages */ Tcl_Obj *pathObj) { const char *path; Tcl_Size len; Tcl_DString resolvedPath; path = TclGetStringFromObj(pathObj, &len); /* Optimize to skip unnecessary calls below */ if (path[0] != '~') { return pathObj; } if (Tcl_FSTildeExpand(interp, path, &resolvedPath) != TCL_OK) { return NULL; } return Tcl_DStringToObj(&resolvedPath); } /* *---------------------------------------------------------------------- * * TclResolveTildePathList -- |
︙ | ︙ |
Changes to generic/tclStubInit.c.
︙ | ︙ | |||
1949 1950 1951 1952 1953 1954 1955 | 0, /* 650 */ 0, /* 651 */ 0, /* 652 */ 0, /* 653 */ Tcl_UtfCharComplete, /* 654 */ Tcl_UtfNext, /* 655 */ Tcl_UtfPrev, /* 656 */ | | | 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 | 0, /* 650 */ 0, /* 651 */ 0, /* 652 */ 0, /* 653 */ Tcl_UtfCharComplete, /* 654 */ Tcl_UtfNext, /* 655 */ Tcl_UtfPrev, /* 656 */ Tcl_FSTildeExpand, /* 657 */ Tcl_ExternalToUtfDStringEx, /* 658 */ Tcl_UtfToExternalDStringEx, /* 659 */ Tcl_AsyncMarkFromSignal, /* 660 */ 0, /* 661 */ 0, /* 662 */ 0, /* 663 */ 0, /* 664 */ |
︙ | ︙ |
Changes to generic/tclTest.c.
︙ | ︙ | |||
304 305 306 307 308 309 310 311 312 313 314 315 316 317 | static Tcl_CmdProc Testset2Cmd; static Tcl_CmdProc TestseterrorcodeCmd; static Tcl_ObjCmdProc TestsetobjerrorcodeCmd; static Tcl_CmdProc TestsetplatformCmd; static Tcl_ObjCmdProc TestSizeCmd; static Tcl_CmdProc TeststaticlibraryCmd; static Tcl_CmdProc TesttranslatefilenameCmd; static Tcl_CmdProc TestupvarCmd; static Tcl_ObjCmdProc2 TestWrongNumArgsObjCmd; static Tcl_ObjCmdProc TestGetIndexFromObjStructObjCmd; static Tcl_CmdProc TestChannelCmd; static Tcl_CmdProc TestChannelEventCmd; static Tcl_CmdProc TestSocketCmd; static Tcl_ObjCmdProc TestFilesystemObjCmd; | > | 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 | static Tcl_CmdProc Testset2Cmd; static Tcl_CmdProc TestseterrorcodeCmd; static Tcl_ObjCmdProc TestsetobjerrorcodeCmd; static Tcl_CmdProc TestsetplatformCmd; static Tcl_ObjCmdProc TestSizeCmd; static Tcl_CmdProc TeststaticlibraryCmd; static Tcl_CmdProc TesttranslatefilenameCmd; static Tcl_ObjCmdProc TestfstildeexpandCmd; static Tcl_CmdProc TestupvarCmd; static Tcl_ObjCmdProc2 TestWrongNumArgsObjCmd; static Tcl_ObjCmdProc TestGetIndexFromObjStructObjCmd; static Tcl_CmdProc TestChannelCmd; static Tcl_CmdProc TestChannelEventCmd; static Tcl_CmdProc TestSocketCmd; static Tcl_ObjCmdProc TestFilesystemObjCmd; |
︙ | ︙ | |||
722 723 724 725 726 727 728 729 730 731 732 733 734 735 | Tcl_CreateObjCommand(interp, "testsize", TestSizeCmd, NULL, NULL); Tcl_CreateCommand(interp, "testsocket", TestSocketCmd, NULL, NULL); Tcl_CreateCommand(interp, "teststaticlibrary", TeststaticlibraryCmd, NULL, NULL); Tcl_CreateCommand(interp, "testtranslatefilename", TesttranslatefilenameCmd, NULL, NULL); Tcl_CreateCommand(interp, "testupvar", TestupvarCmd, NULL, NULL); Tcl_CreateCommand(interp, "testmainthread", TestmainthreadCmd, NULL, NULL); Tcl_CreateCommand(interp, "testsetmainloop", TestsetmainloopCmd, NULL, NULL); Tcl_CreateCommand(interp, "testexitmainloop", TestexitmainloopCmd, NULL, NULL); | > > | 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 | Tcl_CreateObjCommand(interp, "testsize", TestSizeCmd, NULL, NULL); Tcl_CreateCommand(interp, "testsocket", TestSocketCmd, NULL, NULL); Tcl_CreateCommand(interp, "teststaticlibrary", TeststaticlibraryCmd, NULL, NULL); Tcl_CreateCommand(interp, "testtranslatefilename", TesttranslatefilenameCmd, NULL, NULL); Tcl_CreateObjCommand(interp, "testfstildeexpand", TestfstildeexpandCmd, NULL, NULL); Tcl_CreateCommand(interp, "testupvar", TestupvarCmd, NULL, NULL); Tcl_CreateCommand(interp, "testmainthread", TestmainthreadCmd, NULL, NULL); Tcl_CreateCommand(interp, "testsetmainloop", TestsetmainloopCmd, NULL, NULL); Tcl_CreateCommand(interp, "testexitmainloop", TestexitmainloopCmd, NULL, NULL); |
︙ | ︙ | |||
4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 | if (result == NULL) { return TCL_ERROR; } Tcl_AppendResult(interp, result, (char *)NULL); Tcl_DStringFree(&buffer); return TCL_OK; } /* *---------------------------------------------------------------------- * * TestupvarCmd -- * * This procedure implements the "testupvar" command. It is used | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 | if (result == NULL) { return TCL_ERROR; } Tcl_AppendResult(interp, result, (char *)NULL); Tcl_DStringFree(&buffer); return TCL_OK; } /* *---------------------------------------------------------------------- * * TestfstildeexpandCmd -- * * This procedure implements the "testfstildeexpand" command. * It is used to test the Tcl_FSTildeExpand command. It differs * from the script level "file tildeexpand" tests because of a * slightly different code path. * * Results: * A standard Tcl result. * * Side effects: * None. * *---------------------------------------------------------------------- */ static int TestfstildeexpandCmd( TCL_UNUSED(void *), Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* The argument objects. */ { Tcl_DString buffer; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "PATH"); return TCL_ERROR; } if (Tcl_FSTildeExpand(interp, Tcl_GetString(objv[1]), &buffer) != TCL_OK) { return TCL_ERROR; } Tcl_SetObjResult(interp, Tcl_DStringToObj(&buffer)); return TCL_OK; } /* *---------------------------------------------------------------------- * * TestupvarCmd -- * * This procedure implements the "testupvar" command. It is used |
︙ | ︙ |
Changes to tests/fCmd.test.
︙ | ︙ | |||
82 83 84 85 86 87 88 89 90 91 92 93 94 95 | testConstraint notDarwin9 [expr {![testConstraint darwin9]}] testConstraint notContinuousIntegration [expr {![info exists ::env(CI)]}] testConstraint fileSharing 0 testConstraint notFileSharing 1 testConstraint linkFile 1 testConstraint linkDirectory 1 # Several tests require need to match results against the Unix username set user {} if {[testConstraint unix]} { catch { set user [exec whoami] } | > | 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | testConstraint notDarwin9 [expr {![testConstraint darwin9]}] testConstraint notContinuousIntegration [expr {![info exists ::env(CI)]}] testConstraint fileSharing 0 testConstraint notFileSharing 1 testConstraint linkFile 1 testConstraint linkDirectory 1 testConstraint testfstildeexpand [llength [info commands testfstildeexpand]] # Several tests require need to match results against the Unix username set user {} if {[testConstraint unix]} { catch { set user [exec whoami] } |
︙ | ︙ | |||
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 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 | set ::env(HOME) [file join $::env(HOME) foo] } -cleanup { set ::env(HOME) [file dirname $::env(HOME)] } -body { string tolower [file home $::tcl_platform(user)] } -match glob -result [gethomedirglob $::tcl_platform(user)] test fCmd-32.1 {file tildeexpand ~} -body { file tildeexpand ~ } -result [file join $::env(HOME)] test fCmd-32.2 {file tildeexpand ~ - obeys env} -setup { set ::env(HOME) $::env(HOME)/xxx } -cleanup { set ::env(HOME) [file dirname $::env(HOME)] } -body { file tildeexpand ~ } -result [file join $::env(HOME) xxx] test fCmd-32.3 {file tildeexpand ~ - error} -setup { set saved $::env(HOME) unset ::env(HOME) } -cleanup { set ::env(HOME) $saved } -body { file tildeexpand ~ } -returnCodes error -result {couldn't find HOME environment variable to expand path} test fCmd-32.4 { file tildeexpand ~ - relative path. Following 8.x ~ expansion behavior, relative paths are not made absolute } -setup { set saved $::env(HOME) set ::env(HOME) relative/path } -cleanup { set ::env(HOME) $saved } -body { file tildeexpand ~ } -result relative/path test fCmd-32.5 {file tildeexpand ~USER} -body { # Note - as in 8.x this form does NOT necessarily give same result as # env(HOME) even when user is current user. Assume result contains user # name, else not sure how to check string tolower [file tildeexpand ~$::tcl_platform(user)] } -match glob -result [gethomedirglob $::tcl_platform(user)] test fCmd-32.6 {file tildeexpand ~UNKNOWNUSER} -body { file tildeexpand ~nosuchuser } -returnCodes error -result {user "nosuchuser" doesn't exist} test fCmd-32.7 {file tildeexpand ~extra arg} -body { file tildeexpand ~ arg } -returnCodes error -result {wrong # args: should be "file tildeexpand path"} test fCmd-32.8 {file tildeexpand ~/path} -body { file tildeexpand ~/foo } -result [file join $::env(HOME)/foo] test fCmd-32.9 {file tildeexpand ~USER/bar} -body { # Note - as in 8.x this form does NOT necessarily give same result as # env(HOME) even when user is current user. Assume result contains user # name, else not sure how to check string tolower [file tildeexpand ~$::tcl_platform(user)/bar] } -match glob -result [file join [gethomedirglob $::tcl_platform(user)] bar] test fCmd-32.10 {file tildeexpand ~UNKNOWNUSER} -body { file tildeexpand ~nosuchuser/foo } -returnCodes error -result {user "nosuchuser" doesn't exist} test fCmd-32.11 {file tildeexpand /~/path} -body { file tildeexpand /~/foo } -result /~/foo test fCmd-32.12 {file tildeexpand /~user/path} -body { file tildeexpand /~$::tcl_platform(user)/foo } -result /~$::tcl_platform(user)/foo test fCmd-32.13 {file tildeexpand ./~} -body { file tildeexpand ./~ } -result ./~ test fCmd-32.14 {file tildeexpand relative/path} -body { file tildeexpand relative/path } -result relative/path test fCmd-32.15 {file tildeexpand ~\\path} -body { file tildeexpand ~\\foo } -constraints win -result [file join $::env(HOME)/foo] test fCmd-32.16 {file tildeexpand ~USER\\bar} -body { # Note - as in 8.x this form does NOT necessarily give same result as # env(HOME) even when user is current user. Assume result contains user # name, else not sure how to check string tolower [file tildeexpand ~$::tcl_platform(user)\\bar] } -constraints win -match glob -result [file join [gethomedirglob $::tcl_platform(user)] bar] test fCmd-32.17 {file tildeexpand ~USER does not mirror HOME} -setup { set ::env(HOME) [file join $::env(HOME) foo] } -cleanup { set ::env(HOME) [file dirname $::env(HOME)] } -body { string tolower [file tildeexpand ~$::tcl_platform(user)] } -match glob -result [gethomedirglob $::tcl_platform(user)] # cleanup cleanup if {[testConstraint unix]} { removeDirectory tcl[pid] /tmp | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 2739 2740 2741 2742 2743 2744 2745 2746 2747 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 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 | set ::env(HOME) [file join $::env(HOME) foo] } -cleanup { set ::env(HOME) [file dirname $::env(HOME)] } -body { string tolower [file home $::tcl_platform(user)] } -match glob -result [gethomedirglob $::tcl_platform(user)] # file tildeexpand and testfstildexpand are identical in behavior # but tested separately as the former is a script wrapper that does some # sanitization/optimization while the latter is a raw call to Tcl_FSTildeExpand. test fCmd-32.1 {file tildeexpand ~} -body { file tildeexpand ~ } -result [file join $::env(HOME)] test fCmd-32.1.1 {Tcl_FSTildeExpand ~} -constraints testfstildeexpand -body { testfstildeexpand ~ } -result [file join $::env(HOME)] test fCmd-32.2 {file tildeexpand ~ - obeys env} -setup { set ::env(HOME) $::env(HOME)/xxx } -cleanup { set ::env(HOME) [file dirname $::env(HOME)] } -body { file tildeexpand ~ } -result [file join $::env(HOME) xxx] test fCmd-32.2.1 {Tcl_FSTildeExpand ~ - obeys env} -setup { set ::env(HOME) $::env(HOME)/xxx } -cleanup { set ::env(HOME) [file dirname $::env(HOME)] } -constraints testfstildeexpand -body { testfstildeexpand ~ } -result [file join $::env(HOME) xxx] test fCmd-32.3 {file tildeexpand ~ - error} -setup { set saved $::env(HOME) unset ::env(HOME) } -cleanup { set ::env(HOME) $saved } -body { file tildeexpand ~ } -returnCodes error -result {couldn't find HOME environment variable to expand path} test fCmd-32.3.1 {Tcl_FSTildeExpand ~ - error} -setup { set saved $::env(HOME) unset ::env(HOME) } -cleanup { set ::env(HOME) $saved } -constraints testfstildeexpand -body { testfstildeexpand ~ } -returnCodes error -result {couldn't find HOME environment variable to expand path} test fCmd-32.4 { file tildeexpand ~ - relative path. Following 8.x ~ expansion behavior, relative paths are not made absolute } -setup { set saved $::env(HOME) set ::env(HOME) relative/path } -cleanup { set ::env(HOME) $saved } -body { file tildeexpand ~ } -result relative/path test fCmd-32.4.1 { Tcl_FSTildeExpand ~ - relative path. Following 8.x ~ expansion behavior, relative paths are not made absolute } -setup { set saved $::env(HOME) set ::env(HOME) relative/path } -cleanup { set ::env(HOME) $saved } -constraints testfstildeexpand -body { testfstildeexpand ~ } -result relative/path test fCmd-32.5 {file tildeexpand ~USER} -body { # Note - as in 8.x this form does NOT necessarily give same result as # env(HOME) even when user is current user. Assume result contains user # name, else not sure how to check string tolower [file tildeexpand ~$::tcl_platform(user)] } -match glob -result [gethomedirglob $::tcl_platform(user)] test fCmd-32.5.1 {Tcl_FSTildeExpand ~USER} -constraints testfstildeexpand -body { # Note - as in 8.x this form does NOT necessarily give same result as # env(HOME) even when user is current user. Assume result contains user # name, else not sure how to check string tolower [testfstildeexpand ~$::tcl_platform(user)] } -match glob -result [gethomedirglob $::tcl_platform(user)] test fCmd-32.6 {file tildeexpand ~UNKNOWNUSER} -body { file tildeexpand ~nosuchuser } -returnCodes error -result {user "nosuchuser" doesn't exist} test fCmd-32.6.1 {Tcl_FSTildeExpand ~UNKNOWNUSER} -constraints testfstildeexpand -body { testfstildeexpand ~nosuchuser } -returnCodes error -result {user "nosuchuser" doesn't exist} test fCmd-32.7 {file tildeexpand ~extra arg} -body { file tildeexpand ~ arg } -returnCodes error -result {wrong # args: should be "file tildeexpand path"} test fCmd-32.7.1 {Tcl_FSTildeExpand ~extra arg} -constraints testfstildeexpand -body { testfstildeexpand ~ arg } -returnCodes error -result {wrong # args: should be "testfstildeexpand PATH"} test fCmd-32.8 {file tildeexpand ~/path} -body { file tildeexpand ~/foo } -result [file join $::env(HOME)/foo] test fCmd-32.8.1 {Tcl_FSTildeExpand ~/path} -constraints testfstildeexpand -body { testfstildeexpand ~/foo } -result [file join $::env(HOME)/foo] test fCmd-32.9 {file tildeexpand ~USER/bar} -body { # Note - as in 8.x this form does NOT necessarily give same result as # env(HOME) even when user is current user. Assume result contains user # name, else not sure how to check string tolower [file tildeexpand ~$::tcl_platform(user)/bar] } -match glob -result [file join [gethomedirglob $::tcl_platform(user)] bar] test fCmd-32.9.1 {Tcl_FSTildeExpand ~USER/bar} -constraints testfstildeexpand -body { # Note - as in 8.x this form does NOT necessarily give same result as # env(HOME) even when user is current user. Assume result contains user # name, else not sure how to check string tolower [testfstildeexpand ~$::tcl_platform(user)/bar] } -match glob -result [file join [gethomedirglob $::tcl_platform(user)] bar] test fCmd-32.10 {file tildeexpand ~UNKNOWNUSER} -body { file tildeexpand ~nosuchuser/foo } -returnCodes error -result {user "nosuchuser" doesn't exist} test fCmd-32.10.1 {Tcl_FSTildeExpand ~UNKNOWNUSER} -constraints testfstildeexpand -body { testfstildeexpand ~nosuchuser/foo } -returnCodes error -result {user "nosuchuser" doesn't exist} test fCmd-32.11 {file tildeexpand /~/path} -body { file tildeexpand /~/foo } -result /~/foo test fCmd-32.11.1 {Tcl_FSTildeExpand /~/path} -constraints testfstildeexpand -body { testfstildeexpand /~/foo } -result /~/foo test fCmd-32.12 {file tildeexpand /~user/path} -body { file tildeexpand /~$::tcl_platform(user)/foo } -result /~$::tcl_platform(user)/foo test fCmd-32.12.1 {Tcl_FSTildeExpand /~user/path} -constraints testfstildeexpand -body { testfstildeexpand /~$::tcl_platform(user)/foo } -result /~$::tcl_platform(user)/foo test fCmd-32.13 {file tildeexpand ./~} -body { file tildeexpand ./~ } -result ./~ test fCmd-32.13.1 {Tcl_FSTildeExpand ./~} -constraints testfstildeexpand -body { testfstildeexpand ./~ } -result ./~ test fCmd-32.14 {file tildeexpand relative/path} -body { file tildeexpand relative/path } -result relative/path test fCmd-32.14.1 {Tcl_FSTildeExpand relative/path} -constraints testfstildeexpand -body { testfstildeexpand relative/path } -result relative/path test fCmd-32.15 {file tildeexpand ~\\path} -body { file tildeexpand ~\\foo } -constraints win -result [file join $::env(HOME)/foo] test fCmd-32.15.1 {Tcl_FSTildeExpand ~\\path} -constraints testfstildeexpand -body { testfstildeexpand ~\\foo } -constraints win -result [file join $::env(HOME)/foo] test fCmd-32.16 {file tildeexpand ~USER\\bar} -body { # Note - as in 8.x this form does NOT necessarily give same result as # env(HOME) even when user is current user. Assume result contains user # name, else not sure how to check string tolower [file tildeexpand ~$::tcl_platform(user)\\bar] } -constraints win -match glob -result [file join [gethomedirglob $::tcl_platform(user)] bar] test fCmd-32.16.1 {Tcl_FSTildeExpand ~USER\\bar} -constraints testfstildeexpand -body { # Note - as in 8.x this form does NOT necessarily give same result as # env(HOME) even when user is current user. Assume result contains user # name, else not sure how to check string tolower [testfstildeexpand ~$::tcl_platform(user)\\bar] } -constraints win -match glob -result [file join [gethomedirglob $::tcl_platform(user)] bar] test fCmd-32.17 {file tildeexpand ~USER does not mirror HOME} -setup { set ::env(HOME) [file join $::env(HOME) foo] } -cleanup { set ::env(HOME) [file dirname $::env(HOME)] } -body { string tolower [file tildeexpand ~$::tcl_platform(user)] } -match glob -result [gethomedirglob $::tcl_platform(user)] test fCmd-32.17.1 {Tcl_FSTildeExpand ~USER does not mirror HOME} -setup { set ::env(HOME) [file join $::env(HOME) foo] } -cleanup { set ::env(HOME) [file dirname $::env(HOME)] } -constraints testfstildeexpand -body { string tolower [testfstildeexpand ~$::tcl_platform(user)] } -match glob -result [gethomedirglob $::tcl_platform(user)] # cleanup cleanup if {[testConstraint unix]} { removeDirectory tcl[pid] /tmp |
︙ | ︙ |