Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Changes from TIP#17 "Redo Tcl's filesystem" The following files were impacted. * doc/Access.3: * doc/FileSystem.3: * doc/OpenFileChnl.3: * doc/file.n: * doc/glob.n: * generic/tcl.decls: * generic/tcl.h: * generic/tclCmdAH.c: * generic/tclCmdIL.c: * generic/tclCmdMZ.c: * generic/tclDate.c: * generic/tclDecls.h: * generic/tclEncoding.c: * generic/tclFCmd.c: * generic/tclFileName.c: * generic/tclGetDate.y: * generic/tclIO.c: * generic/tclIOCmd.c: * generic/tclIOUtil.c: * generic/tclInt.decls: * generic/tclInt.h: * generic/tclIntDecls.h: * generic/tclLoad.c: * generic/tclStubInit.c: * generic/tclTest.c: * generic/tclUtil.c: * library/init.tcl: * mac/tclMacFCmd.c: * mac/tclMacFile.c: * mac/tclMacInit.c: * mac/tclMacPort.h: * mac/tclMacResource.c: * mac/tclMacTime.c: * tests/cmdAH.test: * tests/event.test: * tests/fCmd.test: * tests/fileName.test: * tests/io.test: * tests/ioCmd.test: * tests/proc-old.test: * tests/registry.test: * tests/unixFCmd.test: * tests/winDde.test: * tests/winFCmd.test: * unix/mkLinks: * unix/tclUnixFCmd.c: * unix/tclUnixFile.c: * unix/tclUnixInit.c: * unix/tclUnixPipe.c: * win/tclWinFCmd.c: * win/tclWinFile.c: * win/tclWinInit.c: * win/tclWinPipe.c |
|---|---|
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA1: |
9461aca54800a289624dfe39d333e41e |
| User & Date: | vincentdarley 2001-07-31 19:12:05.000 |
Context
|
2001-07-31
| ||
| 19:15 | New documentation for TIP#17 check-in: 48e8499e35 user: vincentdarley tags: trunk | |
| 19:12 | Changes from TIP#17 "Redo Tcl's filesystem" The following files were impacted. * doc/Access.3: ... check-in: 9461aca548 user: vincentdarley tags: trunk | |
|
2001-07-24
| ||
| 19:47 | * win/tclWinThrd.c (Tcl_CreateThread): Close Windows HANDLE returned by _beginthreadex. The MS doc... check-in: e81a6a1d2c user: mdejong tags: trunk | |
Changes
Changes to ChangeLog.
1 2 3 4 5 6 7 | 2001-07-24 Mo DeJong <mdejong@redhat.com> * win/tclWinThrd.c (Tcl_CreateThread): Close Windows HANDLE returned by _beginthreadex. The MS documentation states that this handle is not closed by a later call to _endthreadex. | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
2001-07-31 Vince Darley <vincentdarley@users.sourceforge.net>
Changes from TIP#17 "Redo Tcl's filesystem"
The following files were impacted:
* doc/Access.3:
* doc/FileSystem.3:
* doc/OpenFileChnl.3:
* doc/file.n:
* doc/glob.n:
* generic/tcl.decls:
* generic/tcl.h:
* generic/tclCmdAH.c:
* generic/tclCmdIL.c:
* generic/tclCmdMZ.c:
* generic/tclDate.c:
* generic/tclDecls.h:
* generic/tclEncoding.c:
* generic/tclFCmd.c:
* generic/tclFileName.c:
* generic/tclGetDate.y:
* generic/tclIO.c:
* generic/tclIOCmd.c:
* generic/tclIOUtil.c:
* generic/tclInt.decls:
* generic/tclInt.h:
* generic/tclIntDecls.h:
* generic/tclLoad.c:
* generic/tclStubInit.c:
* generic/tclTest.c:
* generic/tclUtil.c:
* library/init.tcl:
* mac/tclMacFCmd.c:
* mac/tclMacFile.c:
* mac/tclMacInit.c:
* mac/tclMacPort.h:
* mac/tclMacResource.c:
* mac/tclMacTime.c:
* tests/cmdAH.test:
* tests/event.test:
* tests/fCmd.test:
* tests/fileName.test:
* tests/io.test:
* tests/ioCmd.test:
* tests/proc-old.test:
* tests/registry.test:
* tests/unixFCmd.test:
* tests/winDde.test:
* tests/winFCmd.test:
* unix/mkLinks:
* unix/tclUnixFCmd.c:
* unix/tclUnixFile.c:
* unix/tclUnixInit.c:
* unix/tclUnixPipe.c:
* win/tclWinFCmd.c:
* win/tclWinFile.c:
* win/tclWinInit.c:
* win/tclWinPipe.c
2001-07-24 Mo DeJong <mdejong@redhat.com>
* win/tclWinThrd.c (Tcl_CreateThread): Close Windows
HANDLE returned by _beginthreadex. The MS documentation
states that this handle is not closed by a later call to
_endthreadex.
|
| ︙ | ︙ |
Changes to doc/Access.3.
1 2 3 4 5 6 | '\" '\" Copyright (c) 1998-1999 Scriptics Corportation '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | '\" '\" Copyright (c) 1998-1999 Scriptics Corportation '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" '\" RCS: @(#) $Id: Access.3,v 1.4 2001/07/31 19:12:05 vincentdarley Exp $ '\" .so man.macros .TH Tcl_Access 3 8.1 Tcl "Tcl Library Procedures" .BS .SH NAME Tcl_Access, Tcl_Stat \- check file permissions and other attributes .SH SYNOPSIS |
| ︙ | ︙ | |||
30 31 32 33 34 35 36 37 38 39 40 41 42 43 | write and execute permissions, respectively. F_OK just requests checking for the existence of the file. .AP stat *statPtr out The structure that contains the result. .BE .SH DESCRIPTION .PP There are two reasons for calling \fBTcl_Access\fR and \fBTcl_Stat\fR rather than calling system level functions \fBaccess\fR and \fBstat\fR directly. First, the Windows implementation of both functions fixes some bugs in the system level calls. Second, both \fBTcl_Access\fR and \fBTcl_Stat\fR (as well as \fBTcl_OpenFileChannelProc\fR) hook into a linked list of functions. This allows the possibity to reroute | > > > > | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | write and execute permissions, respectively. F_OK just requests checking for the existence of the file. .AP stat *statPtr out The structure that contains the result. .BE .SH DESCRIPTION .PP As of Tcl 8.4, the object-based APIs \fBTcl_FSAccess\fR and \fBTcl_FSStat\fR should be used in preference to \fBTcl_Access\fR and \fBTcl_Stat\fR, wherever possible. .PP There are two reasons for calling \fBTcl_Access\fR and \fBTcl_Stat\fR rather than calling system level functions \fBaccess\fR and \fBstat\fR directly. First, the Windows implementation of both functions fixes some bugs in the system level calls. Second, both \fBTcl_Access\fR and \fBTcl_Stat\fR (as well as \fBTcl_OpenFileChannelProc\fR) hook into a linked list of functions. This allows the possibity to reroute |
| ︙ | ︙ |
Changes to doc/OpenFileChnl.3.
1 2 3 4 5 6 | '\" '\" Copyright (c) 1996-1997 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | '\" '\" Copyright (c) 1996-1997 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" '\" RCS: @(#) $Id: OpenFileChnl.3,v 1.10 2001/07/31 19:12:05 vincentdarley Exp $ .so man.macros .TH Tcl_OpenFileChannel 3 8.3 Tcl "Tcl Library Procedures" .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME Tcl_OpenFileChannel, Tcl_OpenCommandChannel, Tcl_MakeFileChannel, Tcl_GetChannel, Tcl_GetChannelNames, Tcl_GetChannelNamesEx, Tcl_RegisterChannel, Tcl_UnregisterChannel, Tcl_DetachChannel, Tcl_IsStandardChannel, Tcl_Close, Tcl_ReadChars, Tcl_Read, Tcl_GetsObj, Tcl_Gets, Tcl_WriteObj, Tcl_WriteChars, Tcl_Write, Tcl_Flush, Tcl_Seek, Tcl_Tell, Tcl_GetChannelOption, Tcl_SetChannelOption, Tcl_Eof, Tcl_InputBlocked, Tcl_InputBuffered, Tcl_Ungets \- buffered I/O facilities using channels .SH SYNOPSIS .nf \fB#include <tcl.h>\fR .sp typedef ... Tcl_Channel; .sp Tcl_Channel |
| ︙ | ︙ | |||
41 42 43 44 45 46 47 48 49 50 51 52 53 54 | .sp void \fBTcl_RegisterChannel\fR(\fIinterp, channel\fR) .sp int \fBTcl_UnregisterChannel\fR(\fIinterp, channel\fR) .sp int \fBTcl_Close\fR(\fIinterp, channel\fR) .sp .VS 8.1 int \fBTcl_ReadChars\fR(\fIchannel, readObjPtr, charsToRead, appendFlag\fR) .sp | > > > > > > | 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | .sp void \fBTcl_RegisterChannel\fR(\fIinterp, channel\fR) .sp int \fBTcl_UnregisterChannel\fR(\fIinterp, channel\fR) .sp int \fBTcl_DetachChannel\fR(\fIinterp, channel\fR) .sp int \fBTcl_IsStandardChannel\fR(\fIchannel\fR) .sp int \fBTcl_Close\fR(\fIinterp, channel\fR) .sp .VS 8.1 int \fBTcl_ReadChars\fR(\fIchannel, readObjPtr, charsToRead, appendFlag\fR) .sp |
| ︙ | ︙ | |||
232 233 234 235 236 237 238 | the Unix standard I/O library. The syntax and meaning of all arguments is similar to those given in the Tcl \fBopen\fR command when opening a file. If an error occurs while opening the channel, \fBTcl_OpenFileChannel\fR returns NULL and records a POSIX error code that can be retrieved with \fBTcl_GetErrno\fR. In addition, if \fIinterp\fR is non-NULL, \fBTcl_OpenFileChannel\fR | | > > > > | 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 | the Unix standard I/O library. The syntax and meaning of all arguments is similar to those given in the Tcl \fBopen\fR command when opening a file. If an error occurs while opening the channel, \fBTcl_OpenFileChannel\fR returns NULL and records a POSIX error code that can be retrieved with \fBTcl_GetErrno\fR. In addition, if \fIinterp\fR is non-NULL, \fBTcl_OpenFileChannel\fR leaves an error message in \fIinterp\fR's result after any error. As of Tcl 8.4, the object-based API \fBTcl_FSOpenFileChannel\fR should be used in preference to \fBTcl_OpenFileChannel\fR wherever possible. .PP .PP The newly created channel is not registered in the supplied interpreter; to register it, use \fBTcl_RegisterChannel\fR, described below. If one of the standard channels, \fBstdin, stdout\fR or \fBstderr\fR was previously closed, the act of creating the new channel also assigns it as a replacement for the standard channel. |
| ︙ | ︙ | |||
335 336 337 338 339 340 341 | able to use the channel's name to refer to the channel in that interpreter. If this operation removed the last registration of the channel in any interpreter, the channel is also closed and destroyed. .PP Code not associated with a Tcl interpreter can call \fBTcl_UnregisterChannel\fR with \fIinterp\fR as NULL, to indicate to Tcl that it no longer holds a reference to that channel. If this is the last | | > > > > > > > > > > > > > > > > > > > > > > > > > > | 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 | able to use the channel's name to refer to the channel in that interpreter. If this operation removed the last registration of the channel in any interpreter, the channel is also closed and destroyed. .PP Code not associated with a Tcl interpreter can call \fBTcl_UnregisterChannel\fR with \fIinterp\fR as NULL, to indicate to Tcl that it no longer holds a reference to that channel. If this is the last reference to the channel, it will now be closed. \fBTcl_UnregisterChannel\fR is very similar to \fBTcl_DetachChannel\fR except that it will also close the channel if no further references to it exist. .SH TCL_DETACHCHANNEL .PP \fBTcl_DetachChannel\fR removes a channel from the set of channels accessible in \fIinterp\fR. After this call, Tcl programs will no longer be able to use the channel's name to refer to the channel in that interpreter. Beyond that, this command has no further effect. It cannot be used on the standard channels (stdout, stderr, stdin), and will return TCL_ERROR if passed one of those channels. .PP Code not associated with a Tcl interpreter can call \fBTcl_DetachChannel\fR with \fIinterp\fR as NULL, to indicate to Tcl that it no longer holds a reference to that channel. If this is the last reference to the channel, unlike \fBTcl_UnregisterChannel\fR, it will not be closed. .SH TCL_ISSTANDARDCHANNEL .PP \fBTcl_IsStandardChannel\fR tests whether a channel is one of the three standard channels, stdin, stdout or stderr. If so, it returns 1, otherwise 0. .PP No attempt is made to check whether the given channel or the standard channels are initialized or otherwise valid. .SH TCL_CLOSE .PP \fBTcl_Close\fR destroys the channel \fIchannel\fR, which must denote a currently open channel. The channel should not be registered in any interpreter when \fBTcl_Close\fR is called. Buffered output is flushed to the channel's output device prior to destroying the channel, and any |
| ︙ | ︙ |
Changes to doc/file.n.
1 2 3 4 5 6 7 | '\" '\" Copyright (c) 1993 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | '\" '\" Copyright (c) 1993 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" '\" RCS: @(#) $Id: file.n,v 1.7 2001/07/31 19:12:06 vincentdarley Exp $ '\" .so man.macros .TH file n 8.3 Tcl "Tcl Built-In Commands" .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME file \- Manipulate file names and attributes |
| ︙ | ︙ | |||
212 213 214 215 216 217 218 219 220 221 222 223 224 225 | .TP \fBfile nativename \fIname\fR . Returns the platform-specific name of the file. This is useful if the filename is needed to pass to a platform-specific call, such as exec under Windows or AppleScript on the Macintosh. .TP \fBfile owned \fIname\fR . Returns \fB1\fR if file \fIname\fR is owned by the current user, \fB0\fR otherwise. .TP \fBfile pathtype \fIname\fR . | > > > > > > > > > > | 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 | .TP \fBfile nativename \fIname\fR . Returns the platform-specific name of the file. This is useful if the filename is needed to pass to a platform-specific call, such as exec under Windows or AppleScript on the Macintosh. .TP \fBfile normalize \fIname\fR . Returns a unique normalised path representation for the file, whose string value can be used as a unique identifier for the it. A normalized path is one which has all '../', './' removed. Also it is one which is in the 'standard' format for the native platform. On MacOS, Unix, this means the path must be free of symbolic links/aliases, and on Windows it means we want the long form, with the long form's case-dependence (which gives us a unique, case-dependent path). .TP \fBfile owned \fIname\fR . Returns \fB1\fR if file \fIname\fR is owned by the current user, \fB0\fR otherwise. .TP \fBfile pathtype \fIname\fR . |
| ︙ | ︙ | |||
262 263 264 265 266 267 268 269 270 271 272 273 274 275 | .RE .TP \fBfile rootname \fIname\fR . Returns all of the characters in \fIname\fR up to but not including the last ``.'' character in the last component of name. If the last component of \fIname\fR doesn't contain a dot, then returns \fIname\fR. .TP \fBfile size \fIname\fR . Returns a decimal string giving the size of file \fIname\fR in bytes. If the file doesn't exist or its size cannot be queried then an error is generated. .TP | > > > > > > > > | 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 | .RE .TP \fBfile rootname \fIname\fR . Returns all of the characters in \fIname\fR up to but not including the last ``.'' character in the last component of name. If the last component of \fIname\fR doesn't contain a dot, then returns \fIname\fR. .TP \fBfile separator ?\fIname\fR? . If no argument is given, returns the character which is used to separate path segments for native files on this platform. If a path is given, the filesystem responsible for that path is asked to return its separator character. If no file system accepts \fIname\fR, an error is generated. .TP \fBfile size \fIname\fR . Returns a decimal string giving the size of file \fIname\fR in bytes. If the file doesn't exist or its size cannot be queried then an error is generated. .TP |
| ︙ | ︙ | |||
299 300 301 302 303 304 305 306 307 308 309 310 311 312 | \fBuid\fR. Each element except \fBtype\fR is a decimal string with the value of the corresponding field from the \fBstat\fR return structure; see the manual entry for \fBstat\fR for details on the meanings of the values. The \fBtype\fR element gives the type of the file in the same form returned by the command \fBfile type\fR. This command returns an empty string. .TP \fBfile tail \fIname\fR . Returns all of the characters in \fIname\fR after the last directory separator. If \fIname\fR contains no separators then returns \fIname\fR. .TP \fBfile type \fIname\fR | > > > > > > > > > > > > > | 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 | \fBuid\fR. Each element except \fBtype\fR is a decimal string with the value of the corresponding field from the \fBstat\fR return structure; see the manual entry for \fBstat\fR for details on the meanings of the values. The \fBtype\fR element gives the type of the file in the same form returned by the command \fBfile type\fR. This command returns an empty string. .TP \fBfile system \fIname\fR . Returns a list of two elements, the first of which is the name of the filesystem to use for the file, and the second the type of the file within that filesystem. If a filesystem only supports one type of file, the second element may be null. For example the native files have a first element 'native', and a second element which is a platform-specific type name for the file (e.g. 'networked'), or possibly the empty string. A generic virtual file system might return the list 'vfs ftp' to represent a file on a remote ftp site mounted as a virtual filesystem through an extension called 'vfs'. If the file does not belong to any filesystem, an error is generated. .TP \fBfile tail \fIname\fR . Returns all of the characters in \fIname\fR after the last directory separator. If \fIname\fR contains no separators then returns \fIname\fR. .TP \fBfile type \fIname\fR |
| ︙ | ︙ |
Changes to doc/glob.n.
1 2 3 4 5 6 7 | '\" '\" Copyright (c) 1993 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | '\" '\" Copyright (c) 1993 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" '\" RCS: @(#) $Id: glob.n,v 1.9 2001/07/31 19:12:06 vincentdarley Exp $ '\" .so man.macros .TH glob n 8.3 Tcl "Tcl Built-In Commands" .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME glob \- Return names of files that match patterns |
| ︙ | ︙ | |||
48 49 50 51 52 53 54 55 56 57 58 59 60 61 | \fB\-path\fR \fIpathPrefix\fR Search for files with the given \fIpathPrefix\fR where the rest of the name matches the given patterns. This allows searching for files with names similar to a given file even when the names contain glob-sensitive characters. This option may not be used in conjunction with \fB\-directory\fR. .TP \fB\-types\fR \fItypeList\fR Only list files or directories which match \fItypeList\fR, where the items in the list have two forms. The first form is like the \-type option of the Unix find command: \fIb\fR (block special file), \fIc\fR (character special file), \fId\fR (directory), | > > > > > > > > > | 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | \fB\-path\fR \fIpathPrefix\fR Search for files with the given \fIpathPrefix\fR where the rest of the name matches the given patterns. This allows searching for files with names similar to a given file even when the names contain glob-sensitive characters. This option may not be used in conjunction with \fB\-directory\fR. .TP \fB\-tails\fR Only return the part of each file found which follows the last directory named in any \fB\-directory\fR or \fB\-path\fR path specification. Thus \fBglob -tails -dir $dir *\fR is equivalent to \fBset pwd [pwd] ; cd $dir ; glob *; cd $pwd\fR. For \fB\-path\fR specifications, the returned names will include the last path segment, so \fBglob -tails -path /usr/loc */*\fR will return paths like \fBlocal/bin local/lib\fR etc. .TP \fB\-types\fR \fItypeList\fR Only list files or directories which match \fItypeList\fR, where the items in the list have two forms. The first form is like the \-type option of the Unix find command: \fIb\fR (block special file), \fIc\fR (character special file), \fId\fR (directory), |
| ︙ | ︙ | |||
110 111 112 113 114 115 116 |
.TP 10
\fB\e\fIx\fR
Matches the character \fIx\fR.
.TP 10
\fB{\fIa\fB,\fIb\fB,\fI...\fR}
Matches any of the strings \fIa\fR, \fIb\fR, etc.
.LP
| | | > > > > > > | 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
.TP 10
\fB\e\fIx\fR
Matches the character \fIx\fR.
.TP 10
\fB{\fIa\fB,\fIb\fB,\fI...\fR}
Matches any of the strings \fIa\fR, \fIb\fR, etc.
.LP
On Unix, as with csh, a ``.'' at the beginning of a file's name or just
after a ``/'' must be matched explicitly or with a {} construct,
unless the ``-types hidden'' flag is given (since ``.'' at the beginning
of a file's name indicates that it is hidden). On other platforms,
files beginning with a ``.'' are handled no differently to any others,
except the special directories ``.'' and ``..'' which must be matched
explicitly (this is to avoid a recursive pattern like ``glob -join * *
* *'' from recursing up the directory hierarchy as well as down).
In addition, all ``/'' characters must be matched explicitly.
.LP
If the first character in a \fIpattern\fR is ``~'' then it refers
to the home directory for the user whose name follows the ``~''.
If the ``~'' is followed immediately by ``/'' then the value of
the HOME environment variable is used.
.LP
|
| ︙ | ︙ |
Changes to generic/tcl.decls.
1 2 3 4 5 6 7 8 9 10 11 12 | # tcl.decls -- # # This file contains the declarations for all supported public # functions that are exported by the Tcl library via the stubs table. # This file is used to generate the tclDecls.h, tclPlatDecls.h, # tclStub.c, and tclPlatStub.c files. # # # Copyright (c) 1998-1999 by Scriptics Corporation. # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | # tcl.decls -- # # This file contains the declarations for all supported public # functions that are exported by the Tcl library via the stubs table. # This file is used to generate the tclDecls.h, tclPlatDecls.h, # tclStub.c, and tclPlatStub.c files. # # # Copyright (c) 1998-1999 by Scriptics Corporation. # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: tcl.decls,v 1.51 2001/07/31 19:12:06 vincentdarley Exp $ library tcl # Define the tcl interface with several sub interfaces: # tclPlat - platform specific public # tclInt - generic private # tclPlatInt - platform specific private |
| ︙ | ︙ | |||
1510 1511 1512 1513 1514 1515 1516 |
}
declare 432 generic {
int Tcl_AttemptSetObjLength(Tcl_Obj *objPtr, int length)
}
declare 433 generic {
Tcl_ThreadId Tcl_GetChannelThread(Tcl_Channel channel)
}
| < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 1659 1660 1661 1662 1663 1664 1665 1666 |
}
declare 432 generic {
int Tcl_AttemptSetObjLength(Tcl_Obj *objPtr, int length)
}
declare 433 generic {
Tcl_ThreadId Tcl_GetChannelThread(Tcl_Channel channel)
}
# introduced in 8.4a3
declare 434 generic {
Tcl_UniChar * Tcl_GetUnicodeFromObj (Tcl_Obj *objPtr, int *lengthPtr)
}
declare 435 generic {
int Tcl_GetMathFuncInfo(Tcl_Interp *interp, CONST char *name,
int *numArgsPtr, Tcl_ValueType **argTypesPtr,
Tcl_MathProc **procPtr, ClientData *clientDataPtr)
}
declare 436 generic {
Tcl_Obj * Tcl_ListMathFuncs(Tcl_Interp *interp, CONST char *pattern)
}
declare 437 generic {
Tcl_Obj * Tcl_SubstObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int flags)
}
declare 438 generic {
int Tcl_DetachChannel(Tcl_Interp* interp, Tcl_Channel channel)
}
declare 439 generic {
int Tcl_IsStandardChannel(Tcl_Channel channel)
}
declare 440 generic {
int Tcl_FSCopyFile(Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr)
}
declare 441 generic {
int Tcl_FSCopyDirectory(Tcl_Obj *srcPathPtr, \
Tcl_Obj *destPathPtr, Tcl_Obj **errorPtr)
}
declare 442 generic {
int Tcl_FSCreateDirectory(Tcl_Obj *pathPtr)
}
declare 443 generic {
int Tcl_FSDeleteFile(Tcl_Obj *pathPtr)
}
declare 444 generic {
int Tcl_FSLoadFile(Tcl_Interp * interp, \
Tcl_Obj *pathPtr, char * sym1, char * sym2, \
Tcl_PackageInitProc ** proc1Ptr, \
Tcl_PackageInitProc ** proc2Ptr, \
ClientData * clientDataPtr, \
Tcl_FSUnloadFileProc **unloadProcPtr)
}
declare 445 generic {
int Tcl_FSMatchInDirectory(Tcl_Interp *interp, Tcl_Obj * result, \
Tcl_Obj *pathPtr, \
char * pattern, Tcl_GlobTypeData * types)
}
declare 446 generic {
Tcl_Obj* Tcl_FSReadlink(Tcl_Obj *pathPtr)
}
declare 447 generic {
int Tcl_FSRemoveDirectory(Tcl_Obj *pathPtr, \
int recursive, Tcl_Obj **errorPtr)
}
declare 448 generic {
int Tcl_FSRenameFile(Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr)
}
declare 449 generic {
int Tcl_FSLstat(Tcl_Obj *pathPtr, struct stat *buf)
}
declare 450 generic {
int Tcl_FSUtime(Tcl_Obj *pathPtr, struct utimbuf *tval)
}
declare 451 generic {
int Tcl_FSFileAttrsGet(Tcl_Interp *interp, \
int index, Tcl_Obj *pathPtr, \
Tcl_Obj **objPtrRef)
}
declare 452 generic {
int Tcl_FSFileAttrsSet(Tcl_Interp *interp, \
int index, Tcl_Obj *pathPtr, \
Tcl_Obj *objPtr)
}
declare 453 generic {
char** Tcl_FSFileAttrStrings(Tcl_Obj *pathPtr, Tcl_Obj **objPtrRef)
}
declare 454 generic {
int Tcl_FSStat(Tcl_Obj *pathPtr, struct stat *buf)
}
declare 455 generic {
int Tcl_FSAccess(Tcl_Obj *pathPtr, int mode)
}
declare 456 generic {
Tcl_Channel Tcl_FSOpenFileChannel(Tcl_Interp *interp, Tcl_Obj *pathPtr, \
char *modeString, int permissions)
}
declare 457 generic {
Tcl_Obj* Tcl_FSGetCwd(Tcl_Interp *interp)
}
declare 458 generic {
int Tcl_FSChdir(Tcl_Obj *pathPtr)
}
declare 459 generic {
int Tcl_FSConvertToPathType(Tcl_Interp *interp, Tcl_Obj *pathPtr)
}
declare 460 generic {
Tcl_Obj* Tcl_FSJoinPath(Tcl_Obj *listObj, int elements)
}
declare 461 generic {
Tcl_Obj* Tcl_FSSplitPath(Tcl_Obj* pathPtr, int *lenPtr)
}
declare 462 generic {
int Tcl_FSEqualPaths(Tcl_Obj* firstPtr, Tcl_Obj* secondPtr)
}
declare 463 generic {
Tcl_Obj* Tcl_FSGetNormalizedPath(Tcl_Interp *interp, Tcl_Obj* pathObjPtr)
}
declare 464 generic {
Tcl_Obj* Tcl_FSJoinToPath(Tcl_Obj *basePtr, int objc, Tcl_Obj *CONST objv[])
}
declare 465 generic {
ClientData Tcl_FSGetInternalRep(Tcl_Obj* pathObjPtr, Tcl_Filesystem *fsPtr)
}
declare 466 generic {
char* Tcl_FSGetTranslatedPath(Tcl_Interp *interp, Tcl_Obj* pathPtr)
}
declare 467 generic {
int Tcl_FSEvalFile(Tcl_Interp *interp, Tcl_Obj *fileName)
}
declare 468 generic {
Tcl_Obj* Tcl_FSNewNativePath(Tcl_Obj* fromFilesystem, ClientData clientData)
}
declare 469 generic {
char* Tcl_FSGetNativePath(Tcl_Obj* pathObjPtr)
}
declare 470 generic {
Tcl_Obj* Tcl_FSFileSystemInfo(Tcl_Obj* pathObjPtr)
}
declare 471 generic {
Tcl_Obj* Tcl_FSPathSeparator(Tcl_Obj* pathObjPtr)
}
declare 472 generic {
int Tcl_FSListVolumes(Tcl_Interp *interp)
}
declare 473 generic {
int Tcl_FSRegister(ClientData clientData, Tcl_Filesystem *fsPtr)
}
declare 474 generic {
int Tcl_FSUnregister(Tcl_Filesystem *fsPtr)
}
declare 475 generic {
ClientData Tcl_FSData(Tcl_Filesystem *fsPtr)
}
##############################################################################
# Define the platform specific public Tcl interface. These functions are
# only available on the designated platform.
interface tclPlat
|
| ︙ | ︙ |
Changes to generic/tcl.h.
| ︙ | ︙ | |||
8 9 10 11 12 13 14 | * Copyright (c) 1993-1996 Lucent Technologies. * Copyright (c) 1994-1998 Sun Microsystems, Inc. * Copyright (c) 1998-2000 by Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | * Copyright (c) 1993-1996 Lucent Technologies. * Copyright (c) 1994-1998 Sun Microsystems, Inc. * Copyright (c) 1998-2000 by Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tcl.h,v 1.94 2001/07/31 19:12:06 vincentdarley Exp $ */ #ifndef _TCL #define _TCL /* * For C++ compilers, use extern "C" |
| ︙ | ︙ | |||
1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 |
typedef enum Tcl_PathType {
TCL_PATH_ABSOLUTE,
TCL_PATH_RELATIVE,
TCL_PATH_VOLUME_RELATIVE
} Tcl_PathType;
/*
* The following structure represents the Notifier functions that
* you can override with the Tcl_SetNotifier call.
*/
typedef struct Tcl_NotifierProcs {
Tcl_SetTimerProc *setTimerProc;
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 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 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 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 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 |
typedef enum Tcl_PathType {
TCL_PATH_ABSOLUTE,
TCL_PATH_RELATIVE,
TCL_PATH_VOLUME_RELATIVE
} Tcl_PathType;
/*
* The following structure is used to pass glob type data amongst
* the various glob routines and Tcl_FSMatchInDirectory.
*/
typedef struct Tcl_GlobTypeData {
/* Corresponds to bcdpfls as in 'find -t' */
int type;
/* Corresponds to file permissions */
int perm;
/* Acceptable mac type */
Tcl_Obj* macType;
/* Acceptable mac creator */
Tcl_Obj* macCreator;
} Tcl_GlobTypeData;
/*
* type and permission definitions for glob command
*/
#define TCL_GLOB_TYPE_BLOCK (1<<0)
#define TCL_GLOB_TYPE_CHAR (1<<1)
#define TCL_GLOB_TYPE_DIR (1<<2)
#define TCL_GLOB_TYPE_PIPE (1<<3)
#define TCL_GLOB_TYPE_FILE (1<<4)
#define TCL_GLOB_TYPE_LINK (1<<5)
#define TCL_GLOB_TYPE_SOCK (1<<6)
#define TCL_GLOB_PERM_RONLY (1<<0)
#define TCL_GLOB_PERM_HIDDEN (1<<1)
#define TCL_GLOB_PERM_R (1<<2)
#define TCL_GLOB_PERM_W (1<<3)
#define TCL_GLOB_PERM_X (1<<4)
/*
* Typedefs for the various filesystem operations:
*/
typedef int (Tcl_FSStatProc) _ANSI_ARGS_((Tcl_Obj *pathPtr, struct stat *buf));
typedef int (Tcl_FSAccessProc) _ANSI_ARGS_((Tcl_Obj *pathPtr, int mode));
typedef Tcl_Channel (Tcl_FSOpenFileChannelProc)
_ANSI_ARGS_((Tcl_Interp *interp, Tcl_Obj *pathPtr,
char *modeString, int permissions));
typedef int (Tcl_FSMatchInDirectoryProc) _ANSI_ARGS_((Tcl_Interp* interp,
Tcl_Obj *result, Tcl_Obj *pathPtr, char *pattern,
Tcl_GlobTypeData * types));
typedef Tcl_Obj* (Tcl_FSGetCwdProc) _ANSI_ARGS_((Tcl_Interp *interp));
typedef int (Tcl_FSChdirProc) _ANSI_ARGS_((Tcl_Obj *pathPtr));
typedef int (Tcl_FSLstatProc) _ANSI_ARGS_((Tcl_Obj *pathPtr,
struct stat *buf));
typedef int (Tcl_FSCreateDirectoryProc) _ANSI_ARGS_((Tcl_Obj *pathPtr));
typedef int (Tcl_FSDeleteFileProc) _ANSI_ARGS_((Tcl_Obj *pathPtr));
typedef int (Tcl_FSCopyDirectoryProc) _ANSI_ARGS_((Tcl_Obj *srcPathPtr,
Tcl_Obj *destPathPtr, Tcl_Obj **errorPtr));
typedef int (Tcl_FSCopyFileProc) _ANSI_ARGS_((Tcl_Obj *srcPathPtr,
Tcl_Obj *destPathPtr));
typedef int (Tcl_FSRemoveDirectoryProc) _ANSI_ARGS_((Tcl_Obj *pathPtr,
int recursive, Tcl_Obj **errorPtr));
typedef int (Tcl_FSRenameFileProc) _ANSI_ARGS_((Tcl_Obj *srcPathPtr,
Tcl_Obj *destPathPtr));
typedef void (Tcl_FSUnloadFileProc) _ANSI_ARGS_((ClientData clientData));
typedef int (Tcl_FSListVolumesProc) _ANSI_ARGS_((Tcl_Interp *interp));
/* We have to declare the utime structure here. */
struct utimbuf;
typedef int (Tcl_FSUtimeProc) _ANSI_ARGS_((Tcl_Obj *pathPtr,
struct utimbuf *tval));
typedef int (Tcl_FSNormalizePathProc) _ANSI_ARGS_((Tcl_Interp *interp,
Tcl_Obj *pathPtr, int nextCheckpoint));
typedef int (Tcl_FSFileAttrsGetProc) _ANSI_ARGS_((Tcl_Interp *interp,
int index, Tcl_Obj *pathPtr,
Tcl_Obj **objPtrRef));
typedef char** (Tcl_FSFileAttrStringsProc) _ANSI_ARGS_((Tcl_Obj *pathPtr,
Tcl_Obj** objPtrRef));
typedef int (Tcl_FSFileAttrsSetProc) _ANSI_ARGS_((Tcl_Interp *interp,
int index, Tcl_Obj *pathPtr,
Tcl_Obj *objPtr));
typedef Tcl_Obj* (Tcl_FSReadlinkProc) _ANSI_ARGS_((Tcl_Obj *pathPtr));
typedef int (Tcl_FSLoadFileProc) _ANSI_ARGS_((Tcl_Interp * interp,
Tcl_Obj *pathPtr, char * sym1, char * sym2,
Tcl_PackageInitProc ** proc1Ptr,
Tcl_PackageInitProc ** proc2Ptr,
ClientData * clientDataPtr));
typedef int (Tcl_FSPathInFilesystemProc) _ANSI_ARGS_((Tcl_Obj *pathPtr,
ClientData *clientDataPtr));
typedef Tcl_Obj* (Tcl_FSFilesystemPathTypeProc)
_ANSI_ARGS_((Tcl_Obj *pathPtr));
typedef Tcl_Obj* (Tcl_FSFilesystemSeparatorProc)
_ANSI_ARGS_((Tcl_Obj *pathPtr));
typedef void (Tcl_FSFreeInternalRepProc) _ANSI_ARGS_((ClientData clientData));
typedef ClientData (Tcl_FSDupInternalRepProc)
_ANSI_ARGS_((ClientData clientData));
typedef Tcl_Obj* (Tcl_FSInternalToNormalizedProc)
_ANSI_ARGS_((ClientData clientData));
typedef ClientData (Tcl_FSCreateInternalRepProc) _ANSI_ARGS_((Tcl_Obj *pathPtr));
typedef struct Tcl_FSVersion_ *Tcl_FSVersion;
/*
*----------------------------------------------------------------
* Data structures related to hooking into the filesystem
*----------------------------------------------------------------
*/
/*
* Filesystem version tag. This was introduced in 8.4.
*/
#define TCL_FILESYSTEM_VERSION_1 ((Tcl_FSVersion) 0x1)
/*
* struct Tcl_Filesystem:
*
* One such structure exists for each type (kind) of filesystem.
* It collects together in one place all the functions that are
* part of the specific filesystem. Tcl always accesses the
* filesystem through one of these structures.
*
* Not all entries need be non-NULL; any which are NULL are simply
* ignored. However, a complete filesystem should provide all of
* these functions. The explanations in the structure show
* the importance of each function.
*/
typedef struct Tcl_Filesystem {
CONST char *typeName; /* The name of the filesystem. */
int structureLength; /* Length of this structure, so future
* binary compatibility can be assured. */
Tcl_FSVersion version;
/* Version of the filesystem type. */
Tcl_FSPathInFilesystemProc *pathInFilesystemProc;
/* Function to check whether a path is in
* this filesystem. This is the most
* important filesystem procedure. */
Tcl_FSDupInternalRepProc *dupInternalRepProc;
/* Function to duplicate internal fs rep. May
* be NULL (but then fs is less efficient). */
Tcl_FSFreeInternalRepProc *freeInternalRepProc;
/* Function to free internal fs rep. Must
* be implemented, if internal representations
* need freeing, otherwise it can be NULL. */
Tcl_FSInternalToNormalizedProc *internalToNormalizedProc;
/* Function to convert internal representation
* to a normalized path. Only required if
* the fs creates pure path objects with no
* string/path representation. */
Tcl_FSCreateInternalRepProc *createInternalRepProc;
/* Function to create a filesystem-specific
* internal representation. May be NULL
* if paths have no internal representation,
* or if the Tcl_FSPathInFilesystemProc
* for this filesystem always immediately
* creates an internal representation for
* paths it accepts. */
Tcl_FSNormalizePathProc *normalizePathProc;
/* Function to normalize a path. Should
* be implemented for all filesystems
* which can have multiple string
* representations for the same path
* object. */
Tcl_FSFilesystemPathTypeProc *filesystemPathTypeProc;
/* Function to determine the type of a
* path in this filesystem. May be NULL. */
Tcl_FSFilesystemSeparatorProc *filesystemSeparatorProc;
/* Function to return the separator
* character(s) for this filesystem. Must
* be implemented. */
Tcl_FSStatProc *statProc;
/*
* Function to process a 'Tcl_FSStat()'
* call. Must be implemented for any
* reasonable filesystem.
*/
Tcl_FSAccessProc *accessProc;
/*
* Function to process a 'Tcl_FSAccess()'
* call. Must be implemented for any
* reasonable filesystem.
*/
Tcl_FSOpenFileChannelProc *openFileChannelProc;
/*
* Function to process a
* 'Tcl_FSOpenFileChannel()' call. Must be
* implemented for any reasonable
* filesystem.
*/
Tcl_FSMatchInDirectoryProc *matchInDirectoryProc;
/* Function to process a
* 'Tcl_FSMatchInDirectory()'. If not
* implemented, then glob and recursive
* copy functionality will be lacking in
* the filesystem. */
Tcl_FSUtimeProc *utimeProc;
/* Function to process a
* 'Tcl_FSUtime()' call. Required to
* allow setting (not reading) of times
* with 'file mtime', 'file atime' and
* the open-r/open-w/fcopy implementation
* of 'file copy'. */
Tcl_FSReadlinkProc *readlinkProc;
/* Function to process a
* 'Tcl_FSReadlink()' call. Should be
* implemented only if the filesystem supports
* links. */
Tcl_FSListVolumesProc *listVolumesProc;
/* Function to list any filesystem volumes
* added by this filesystem. Should be
* implemented only if the filesystem adds
* volumes at the head of the filesystem. */
Tcl_FSFileAttrStringsProc *fileAttrStringsProc;
/* Function to list all attributes strings
* which are valid for this filesystem.
* If not implemented the filesystem will
* not support the 'file attributes' command.
* This allows arbitrary additional information
* to be attached to files in the filesystem. */
Tcl_FSFileAttrsGetProc *fileAttrsGetProc;
/* Function to process a
* 'Tcl_FSFileAttrsGet()' call, used by
* 'file attributes'. */
Tcl_FSFileAttrsSetProc *fileAttrsSetProc;
/* Function to process a
* 'Tcl_FSFileAttrsSet()' call, used by
* 'file attributes'. */
Tcl_FSCreateDirectoryProc *createDirectoryProc;
/* Function to process a
* 'Tcl_FSCreateDirectory()' call. Should
* be implemented unless the FS is
* read-only. */
Tcl_FSRemoveDirectoryProc *removeDirectoryProc;
/* Function to process a
* 'Tcl_FSRemoveDirectory()' call. Should
* be implemented unless the FS is
* read-only. */
Tcl_FSDeleteFileProc *deleteFileProc;
/* Function to process a
* 'Tcl_FSDeleteFile()' call. Should
* be implemented unless the FS is
* read-only. */
Tcl_FSLstatProc *lstatProc;
/* Function to process a
* 'Tcl_FSLstat()' call. If not implemented,
* Tcl will attempt to use the 'statProc'
* defined above instead. */
Tcl_FSCopyFileProc *copyFileProc;
/* Function to process a
* 'Tcl_FSCopyFile()' call. If not
* implemented Tcl will fall back
* on open-r, open-w and fcopy as
* a copying mechanism. */
Tcl_FSRenameFileProc *renameFileProc;
/* Function to process a
* 'Tcl_FSRenameFile()' call. If not
* implemented, Tcl will fall back on
* a copy and delete mechanism. */
Tcl_FSCopyDirectoryProc *copyDirectoryProc;
/* Function to process a
* 'Tcl_FSCopyDirectory()' call. If
* not implemented, Tcl will fall back
* on a recursive create-dir, file copy
* mechanism. */
Tcl_FSLoadFileProc *loadFileProc;
/* Function to process a
* 'Tcl_FSLoadFile()' call. If not
* implemented, Tcl will fall back on
* a copy to native-temp followed by a
* Tcl_FSLoadFile on that temporary copy. */
Tcl_FSUnloadFileProc *unloadFileProc;
/* Function to unload a previously
* successfully loaded file. If load was
* implemented, then this should also be
* implemented, if there is any cleanup
* action required. */
Tcl_FSGetCwdProc *getCwdProc;
/*
* Function to process a 'Tcl_FSGetCwd()'
* call. Most filesystems need not
* implement this. It will usually only be
* called once, if 'getcwd' is called
* before 'chdir'. May be NULL.
*/
Tcl_FSChdirProc *chdirProc;
/*
* Function to process a 'Tcl_FSChdir()'
* call. If filesystems do not implement
* this, it will be emulated by a series of
* directory access checks. Otherwise,
* virtual filesystems which do implement
* it need only respond with a positive
* return result if the dirName is a valid
* directory in their filesystem. They
* need not remember the result, since that
* will be automatically remembered for use
* by GetCwd. Real filesystems should
* carry out the correct action (i.e. call
* the correct system 'chdir' api). If not
* implemented, then 'cd' and 'pwd' will
* fail inside the filesystem.
*/
} Tcl_Filesystem;
/*
* The following structure represents the Notifier functions that
* you can override with the Tcl_SetNotifier call.
*/
typedef struct Tcl_NotifierProcs {
Tcl_SetTimerProc *setTimerProc;
|
| ︙ | ︙ |
Changes to generic/tclCmdAH.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* * tclCmdAH.c -- * * This file contains the top-level command routines for most of * the Tcl built-in commands whose names begin with the letters * A to H. * * Copyright (c) 1987-1993 The Regents of the University of California. * Copyright (c) 1994-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | < < | < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | /* * tclCmdAH.c -- * * This file contains the top-level command routines for most of * the Tcl built-in commands whose names begin with the letters * A to H. * * Copyright (c) 1987-1993 The Regents of the University of California. * Copyright (c) 1994-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclCmdAH.c,v 1.13 2001/07/31 19:12:06 vincentdarley Exp $ */ #include "tclInt.h" #include "tclPort.h" #include <locale.h> /* * Prototypes for local procedures defined in this file: */ static int CheckAccess _ANSI_ARGS_((Tcl_Interp *interp, Tcl_Obj *objPtr, int mode)); static int GetStatBuf _ANSI_ARGS_((Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_FSStatProc *statProc, struct stat *statPtr)); static char * GetTypeFromMode _ANSI_ARGS_((int mode)); static int SplitPath _ANSI_ARGS_((Tcl_Interp *interp, Tcl_Obj *objPtr, int *argcPtr, char ***argvPtr)); static int StoreStatData _ANSI_ARGS_((Tcl_Interp *interp, char *varName, struct stat *statPtr)); /* *---------------------------------------------------------------------- * * Tcl_BreakObjCmd -- * * This procedure is invoked to process the "break" Tcl command. |
| ︙ | ︙ | |||
303 304 305 306 307 308 309 |
int
Tcl_CdObjCmd(dummy, interp, objc, objv)
ClientData dummy; /* Not used. */
Tcl_Interp *interp; /* Current interpreter. */
int objc; /* Number of arguments. */
Tcl_Obj *CONST objv[]; /* Argument objects. */
{
| | < | > | | | < | | < < | | | | | > > > > | | 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 |
int
Tcl_CdObjCmd(dummy, interp, objc, objv)
ClientData dummy; /* Not used. */
Tcl_Interp *interp; /* Current interpreter. */
int objc; /* Number of arguments. */
Tcl_Obj *CONST objv[]; /* Argument objects. */
{
Tcl_Obj *dir;
int result;
if (objc > 2) {
Tcl_WrongNumArgs(interp, 1, objv, "?dirName?");
return TCL_ERROR;
}
if (objc == 2) {
dir = objv[1];
} else {
dir = Tcl_NewStringObj("~",1);
Tcl_IncrRefCount(dir);
}
if (Tcl_FSConvertToPathType(interp, dir) != TCL_OK) {
result = TCL_ERROR;
} else {
result = Tcl_FSChdir(dir);
if (result != TCL_OK) {
Tcl_AppendResult(interp, "couldn't change working directory to \"",
Tcl_GetString(dir), "\": ", Tcl_PosixError(interp), (char *) NULL);
result = TCL_ERROR;
}
}
if (objc != 2) {
Tcl_DecrRefCount(dir);
}
return result;
}
/*
*----------------------------------------------------------------------
*
* Tcl_ConcatObjCmd --
*
|
| ︙ | ︙ | |||
761 762 763 764 765 766 767 | * * Tcl_FileObjCmd -- * * This procedure is invoked to process the "file" Tcl command. * See the user documentation for details on what it does. * PLEASE NOTE THAT THIS FAILS WITH FILENAMES AND PATHS WITH * EMBEDDED NULLS, WHICH COULD THEORETICALLY HAPPEN ON A MAC. | > > | | 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 | * * Tcl_FileObjCmd -- * * This procedure is invoked to process the "file" Tcl command. * See the user documentation for details on what it does. * PLEASE NOTE THAT THIS FAILS WITH FILENAMES AND PATHS WITH * EMBEDDED NULLS, WHICH COULD THEORETICALLY HAPPEN ON A MAC. * With the object-based Tcl_FS APIs, the above NOTE may no * longer be true. In any case this assertion should be tested. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *---------------------------------------------------------------------- |
| ︙ | ︙ | |||
791 792 793 794 795 796 797 |
*/
static char *fileOptions[] = {
"atime", "attributes", "channels", "copy",
"delete",
"dirname", "executable", "exists", "extension",
"isdirectory", "isfile", "join", "lstat",
| | > | > | > | > < | < | | | < < < < | < < < < < < | < < | | 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 |
*/
static char *fileOptions[] = {
"atime", "attributes", "channels", "copy",
"delete",
"dirname", "executable", "exists", "extension",
"isdirectory", "isfile", "join", "lstat",
"mtime", "mkdir", "nativename",
"normalize", "owned",
"pathtype", "readable", "readlink", "rename",
"rootname", "separator", "size", "split",
"stat", "system",
"tail", "type", "volumes", "writable",
(char *) NULL
};
enum options {
FILE_ATIME, FILE_ATTRIBUTES, FILE_CHANNELS, FILE_COPY,
FILE_DELETE,
FILE_DIRNAME, FILE_EXECUTABLE, FILE_EXISTS, FILE_EXTENSION,
FILE_ISDIRECTORY, FILE_ISFILE, FILE_JOIN, FILE_LSTAT,
FILE_MTIME, FILE_MKDIR, FILE_NATIVENAME,
FILE_NORMALIZE, FILE_OWNED,
FILE_PATHTYPE, FILE_READABLE, FILE_READLINK, FILE_RENAME,
FILE_ROOTNAME, FILE_SEPARATOR, FILE_SIZE, FILE_SPLIT,
FILE_STAT, FILE_SYSTEM,
FILE_TAIL, FILE_TYPE, FILE_VOLUMES, FILE_WRITABLE
};
if (objc < 2) {
Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
return TCL_ERROR;
}
if (Tcl_GetIndexFromObj(interp, objv[1], fileOptions, "option", 0,
&index) != TCL_OK) {
return TCL_ERROR;
}
resultPtr = Tcl_GetObjResult(interp);
switch ((enum options) index) {
case FILE_ATIME: {
struct stat buf;
struct utimbuf tval;
if ((objc < 3) || (objc > 4)) {
Tcl_WrongNumArgs(interp, 2, objv, "name ?time?");
return TCL_ERROR;
}
if (GetStatBuf(interp, objv[2], Tcl_FSStat, &buf) != TCL_OK) {
return TCL_ERROR;
}
if (objc == 4) {
if (Tcl_GetLongFromObj(interp, objv[3],
(long*)(&buf.st_atime)) != TCL_OK) {
return TCL_ERROR;
}
tval.actime = buf.st_atime;
tval.modtime = buf.st_mtime;
if (Tcl_FSUtime(objv[2], &tval) != 0) {
Tcl_AppendStringsToObj(resultPtr,
"could not set access time for file \"",
Tcl_GetString(objv[2]), "\": ",
Tcl_PosixError(interp), (char *) NULL);
return TCL_ERROR;
}
/*
* Do another stat to ensure that the we return the
* new recognized atime - hopefully the same as the
* one we sent in. However, fs's like FAT don't
* even know what atime is.
*/
if (GetStatBuf(interp, objv[2], Tcl_FSStat, &buf) != TCL_OK) {
return TCL_ERROR;
}
}
Tcl_SetLongObj(resultPtr, (long) buf.st_atime);
return TCL_OK;
}
case FILE_ATTRIBUTES: {
return TclFileAttrsCmd(interp, objc, objv);
}
case FILE_CHANNELS: {
if ((objc < 2) || (objc > 3)) {
Tcl_WrongNumArgs(interp, 2, objv, "?pattern?");
return TCL_ERROR;
}
return Tcl_GetChannelNamesEx(interp,
((objc == 2) ? NULL : Tcl_GetString(objv[2])));
}
case FILE_COPY: {
return TclFileCopyCmd(interp, objc, objv);
}
case FILE_DELETE: {
return TclFileDeleteCmd(interp, objc, objv);
}
case FILE_DIRNAME: {
int argc;
char ** argv;
if (objc != 3) {
goto only3Args;
}
if (SplitPath(interp, objv[2], &argc, &argv) != TCL_OK) {
return TCL_ERROR;
}
|
| ︙ | ︙ | |||
955 956 957 958 959 960 961 |
int value;
struct stat buf;
if (objc != 3) {
goto only3Args;
}
value = 0;
| | | < | | < < | < < < | < | < | | | < < < < | < < > > > > > > > > > > > > | | 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 |
int value;
struct stat buf;
if (objc != 3) {
goto only3Args;
}
value = 0;
if (GetStatBuf(NULL, objv[2], Tcl_FSStat, &buf) == TCL_OK) {
value = S_ISDIR(buf.st_mode);
}
Tcl_SetBooleanObj(resultPtr, value);
return TCL_OK;
}
case FILE_ISFILE: {
int value;
struct stat buf;
if (objc != 3) {
goto only3Args;
}
value = 0;
if (GetStatBuf(NULL, objv[2], Tcl_FSStat, &buf) == TCL_OK) {
value = S_ISREG(buf.st_mode);
}
Tcl_SetBooleanObj(resultPtr, value);
return TCL_OK;
}
case FILE_JOIN: {
Tcl_Obj *resObj;
if (objc < 3) {
Tcl_WrongNumArgs(interp, 2, objv, "name ?name ...?");
return TCL_ERROR;
}
resObj = Tcl_FSJoinToPath(NULL, objc - 2, objv + 2);
Tcl_SetObjResult(interp, resObj);
return TCL_OK;
}
case FILE_LSTAT: {
char *varName;
struct stat buf;
if (objc != 4) {
Tcl_WrongNumArgs(interp, 2, objv, "name varName");
return TCL_ERROR;
}
if (GetStatBuf(interp, objv[2], Tcl_FSLstat, &buf) != TCL_OK) {
return TCL_ERROR;
}
varName = Tcl_GetString(objv[3]);
return StoreStatData(interp, varName, &buf);
}
case FILE_MTIME: {
struct stat buf;
struct utimbuf tval;
if ((objc < 3) || (objc > 4)) {
Tcl_WrongNumArgs(interp, 2, objv, "name ?time?");
return TCL_ERROR;
}
if (GetStatBuf(interp, objv[2], Tcl_FSStat, &buf) != TCL_OK) {
return TCL_ERROR;
}
if (objc == 4) {
if (Tcl_GetLongFromObj(interp, objv[3],
(long*)(&buf.st_mtime)) != TCL_OK) {
return TCL_ERROR;
}
tval.actime = buf.st_atime;
tval.modtime = buf.st_mtime;
if (Tcl_FSUtime(objv[2], &tval) != 0) {
Tcl_AppendStringsToObj(resultPtr,
"could not set modification time for file \"",
Tcl_GetString(objv[2]), "\": ",
Tcl_PosixError(interp), (char *) NULL);
return TCL_ERROR;
}
/*
* Do another stat to ensure that the we return the
* new recognized atime - hopefully the same as the
* one we sent in. However, fs's like FAT don't
* even know what atime is.
*/
if (GetStatBuf(interp, objv[2], Tcl_FSStat, &buf) != TCL_OK) {
return TCL_ERROR;
}
}
Tcl_SetLongObj(resultPtr, (long) buf.st_mtime);
return TCL_OK;
}
case FILE_MKDIR: {
if (objc < 3) {
Tcl_WrongNumArgs(interp, 2, objv, "name ?name ...?");
return TCL_ERROR;
}
return TclFileMakeDirsCmd(interp, objc, objv);
}
case FILE_NATIVENAME: {
char *fileName;
Tcl_DString ds;
if (objc != 3) {
goto only3Args;
}
fileName = Tcl_GetString(objv[2]);
fileName = Tcl_TranslateFileName(interp, fileName, &ds);
if (fileName == NULL) {
return TCL_ERROR;
}
Tcl_SetStringObj(resultPtr, fileName, Tcl_DStringLength(&ds));
Tcl_DStringFree(&ds);
return TCL_OK;
}
case FILE_NORMALIZE: {
Tcl_Obj *fileName;
if (objc != 3) {
Tcl_WrongNumArgs(interp, 2, objv, "filename");
return TCL_ERROR;
}
fileName = Tcl_FSGetNormalizedPath(interp, objv[2]);
Tcl_SetObjResult(interp, fileName);
return TCL_OK;
}
case FILE_OWNED: {
int value;
struct stat buf;
if (objc != 3) {
goto only3Args;
}
value = 0;
if (GetStatBuf(NULL, objv[2], Tcl_FSStat, &buf) == TCL_OK) {
/*
* For Windows and Macintosh, there are no user ids
* associated with a file, so we always return 1.
*/
#if (defined(__WIN32__) || defined(MAC_TCL))
value = 1;
|
| ︙ | ︙ | |||
1125 1126 1127 1128 1129 1130 1131 |
case FILE_READABLE: {
if (objc != 3) {
goto only3Args;
}
return CheckAccess(interp, objv[2], R_OK);
}
case FILE_READLINK: {
| | < | < < < < < < < < < < < | < < < < < | > < < < < | < < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | < < < < < | < < < < < < | > > > > > > > > > > > > > > > | 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 |
case FILE_READABLE: {
if (objc != 3) {
goto only3Args;
}
return CheckAccess(interp, objv[2], R_OK);
}
case FILE_READLINK: {
Tcl_Obj *contents;
if (objc != 3) {
goto only3Args;
}
if (Tcl_FSConvertToPathType(interp, objv[2]) != TCL_OK) {
return TCL_ERROR;
}
contents = Tcl_FSReadlink(objv[2]);
if (contents == NULL) {
Tcl_AppendResult(interp, "could not readlink \"",
Tcl_GetString(objv[2]), "\": ",
Tcl_PosixError(interp), (char *) NULL);
return TCL_ERROR;
}
Tcl_SetObjResult(interp, contents);
Tcl_DecrRefCount(contents);
return TCL_OK;
}
case FILE_RENAME: {
return TclFileRenameCmd(interp, objc, objv);
}
case FILE_ROOTNAME: {
int length;
char *fileName, *extension;
if (objc != 3) {
goto only3Args;
}
fileName = Tcl_GetStringFromObj(objv[2], &length);
extension = TclGetExtension(fileName);
if (extension == NULL) {
Tcl_SetObjResult(interp, objv[2]);
} else {
Tcl_SetStringObj(resultPtr, fileName,
(int) (length - strlen(extension)));
}
return TCL_OK;
}
case FILE_SEPARATOR: {
if ((objc < 2) || (objc > 3)) {
Tcl_WrongNumArgs(interp, 2, objv, "?name?");
return TCL_ERROR;
}
if (objc == 2) {
char *separator = NULL; /* lint */
switch (tclPlatform) {
case TCL_PLATFORM_UNIX:
separator = "/";
break;
case TCL_PLATFORM_WINDOWS:
separator = "\\";
break;
case TCL_PLATFORM_MAC:
separator = ":";
break;
}
Tcl_SetObjResult(interp, Tcl_NewStringObj(separator,1));
} else {
Tcl_Obj *separatorObj = Tcl_FSPathSeparator(objv[2]);
if (separatorObj != NULL) {
Tcl_SetObjResult(interp, separatorObj);
} else {
Tcl_SetObjResult(interp,
Tcl_NewStringObj("Unrecognised path",-1));
return TCL_ERROR;
}
}
return TCL_OK;
}
case FILE_SIZE: {
struct stat buf;
if (objc != 3) {
goto only3Args;
}
if (GetStatBuf(interp, objv[2], Tcl_FSStat, &buf) != TCL_OK) {
return TCL_ERROR;
}
Tcl_SetLongObj(resultPtr, (long) buf.st_size);
return TCL_OK;
}
case FILE_SPLIT: {
if (objc != 3) {
goto only3Args;
}
Tcl_SetObjResult(interp, Tcl_FSSplitPath(objv[2], NULL));
return TCL_OK;
}
case FILE_STAT: {
char *varName;
struct stat buf;
if (objc != 4) {
Tcl_WrongNumArgs(interp, 1, objv, "stat name varName");
return TCL_ERROR;
}
if (GetStatBuf(interp, objv[2], Tcl_FSStat, &buf) != TCL_OK) {
return TCL_ERROR;
}
varName = Tcl_GetString(objv[3]);
return StoreStatData(interp, varName, &buf);
}
case FILE_SYSTEM: {
Tcl_Obj* fsInfo;
if (objc != 3) {
goto only3Args;
}
fsInfo = Tcl_FSFileSystemInfo(objv[2]);
if (fsInfo != NULL) {
Tcl_SetObjResult(interp, fsInfo);
return TCL_OK;
} else {
Tcl_SetObjResult(interp,
Tcl_NewStringObj("Unrecognised path",-1));
return TCL_ERROR;
}
}
case FILE_TAIL: {
int argc;
char **argv;
if (objc != 3) {
goto only3Args;
|
| ︙ | ︙ | |||
1264 1265 1266 1267 1268 1269 1270 |
}
case FILE_TYPE: {
struct stat buf;
if (objc != 3) {
goto only3Args;
}
| | | | 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 |
}
case FILE_TYPE: {
struct stat buf;
if (objc != 3) {
goto only3Args;
}
if (GetStatBuf(interp, objv[2], Tcl_FSLstat, &buf) != TCL_OK) {
return TCL_ERROR;
}
Tcl_SetStringObj(resultPtr,
GetTypeFromMode((unsigned short) buf.st_mode), -1);
return TCL_OK;
}
case FILE_VOLUMES: {
if (objc != 2) {
Tcl_WrongNumArgs(interp, 2, objv, NULL);
return TCL_ERROR;
}
return Tcl_FSListVolumes(interp);
}
case FILE_WRITABLE: {
if (objc != 3) {
goto only3Args;
}
return CheckAccess(interp, objv[2], W_OK);
}
|
| ︙ | ︙ | |||
1375 1376 1377 1378 1379 1380 1381 |
Tcl_Interp *interp; /* Interp for status return. Must not be
* NULL. */
Tcl_Obj *objPtr; /* Name of file to check. */
int mode; /* Attribute to check; passed as argument to
* access(). */
{
int value;
| < < | < < | < | 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 |
Tcl_Interp *interp; /* Interp for status return. Must not be
* NULL. */
Tcl_Obj *objPtr; /* Name of file to check. */
int mode; /* Attribute to check; passed as argument to
* access(). */
{
int value;
if (Tcl_FSConvertToPathType(interp, objPtr) != TCL_OK) {
value = 0;
} else {
value = (Tcl_FSAccess(objPtr, mode) == 0);
}
Tcl_SetBooleanObj(Tcl_GetObjResult(interp), value);
return TCL_OK;
}
/*
|
| ︙ | ︙ | |||
1415 1416 1417 1418 1419 1420 1421 |
*---------------------------------------------------------------------------
*/
static int
GetStatBuf(interp, objPtr, statProc, statPtr)
Tcl_Interp *interp; /* Interp for error return. May be NULL. */
Tcl_Obj *objPtr; /* Path name to examine. */
| | < < | < < | < | 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 |
*---------------------------------------------------------------------------
*/
static int
GetStatBuf(interp, objPtr, statProc, statPtr)
Tcl_Interp *interp; /* Interp for error return. May be NULL. */
Tcl_Obj *objPtr; /* Path name to examine. */
Tcl_FSStatProc *statProc; /* Either stat() or lstat() depending on
* desired behavior. */
struct stat *statPtr; /* Filled with info about file obtained by
* calling (*statProc)(). */
{
int status;
if (Tcl_FSConvertToPathType(interp, objPtr) != TCL_OK) {
return TCL_ERROR;
}
status = (*statProc)(objPtr, statPtr);
if (status < 0) {
if (interp != NULL) {
Tcl_AppendResult(interp, "could not read \"",
Tcl_GetString(objPtr), "\": ",
Tcl_PosixError(interp), (char *) NULL);
}
|
| ︙ | ︙ | |||
2341 2342 2343 2344 2345 2346 2347 |
fmtError:
if(dst != staticBuf) {
ckfree(dst);
}
Tcl_DecrRefCount(resultPtr);
return TCL_ERROR;
}
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 2331 2332 2333 2334 2335 2336 2337 |
fmtError:
if(dst != staticBuf) {
ckfree(dst);
}
Tcl_DecrRefCount(resultPtr);
return TCL_ERROR;
}
|
Changes to generic/tclCmdIL.c.
| ︙ | ︙ | |||
10 11 12 13 14 15 16 | * Copyright (c) 1993-1997 Lucent Technologies. * Copyright (c) 1994-1997 Sun Microsystems, Inc. * Copyright (c) 1998-1999 by Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | * Copyright (c) 1993-1997 Lucent Technologies. * Copyright (c) 1994-1997 Sun Microsystems, Inc. * Copyright (c) 1998-1999 by Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclCmdIL.c,v 1.33 2001/07/31 19:12:06 vincentdarley Exp $ */ #include "tclInt.h" #include "tclPort.h" #include "tclCompile.h" #include "tclRegexp.h" |
| ︙ | ︙ | |||
1659 1660 1661 1662 1663 1664 1665 |
Interp *iPtr = (Interp *) interp;
if ((objc != 2) && (objc != 3)) {
Tcl_WrongNumArgs(interp, 2, objv, "?filename?");
return TCL_ERROR;
}
if (objc == 3) {
| < < < | | | | | 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 |
Interp *iPtr = (Interp *) interp;
if ((objc != 2) && (objc != 3)) {
Tcl_WrongNumArgs(interp, 2, objv, "?filename?");
return TCL_ERROR;
}
if (objc == 3) {
if (iPtr->scriptFile != NULL) {
Tcl_DecrRefCount(iPtr->scriptFile);
}
iPtr->scriptFile = objv[2];
Tcl_IncrRefCount(iPtr->scriptFile);
}
if (iPtr->scriptFile != NULL) {
Tcl_SetObjResult(interp, iPtr->scriptFile);
}
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
|
| ︙ | ︙ |
Changes to generic/tclCmdMZ.c.
| ︙ | ︙ | |||
9 10 11 12 13 14 15 | * Copyright (c) 1987-1993 The Regents of the University of California. * Copyright (c) 1994-1997 Sun Microsystems, Inc. * Copyright (c) 1998-2000 Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | * Copyright (c) 1987-1993 The Regents of the University of California. * Copyright (c) 1994-1997 Sun Microsystems, Inc. * Copyright (c) 1998-2000 Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclCmdMZ.c,v 1.42 2001/07/31 19:12:06 vincentdarley Exp $ */ #include "tclInt.h" #include "tclPort.h" #include "tclCompile.h" #include "tclRegexp.h" |
| ︙ | ︙ | |||
98 99 100 101 102 103 104 |
int
Tcl_PwdObjCmd(dummy, interp, objc, objv)
ClientData dummy; /* Not used. */
Tcl_Interp *interp; /* Current interpreter. */
int objc; /* Number of arguments. */
Tcl_Obj *CONST objv[]; /* Argument objects. */
{
| | | > | > | 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
int
Tcl_PwdObjCmd(dummy, interp, objc, objv)
ClientData dummy; /* Not used. */
Tcl_Interp *interp; /* Current interpreter. */
int objc; /* Number of arguments. */
Tcl_Obj *CONST objv[]; /* Argument objects. */
{
Tcl_Obj *retVal;
if (objc != 1) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
return TCL_ERROR;
}
retVal = Tcl_FSGetCwd(interp);
if (retVal == NULL) {
return TCL_ERROR;
}
Tcl_SetObjResult(interp, retVal);
Tcl_DecrRefCount(retVal);
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
* Tcl_RegexpObjCmd --
|
| ︙ | ︙ | |||
859 860 861 862 863 864 865 |
int
Tcl_SourceObjCmd(dummy, interp, objc, objv)
ClientData dummy; /* Not used. */
Tcl_Interp *interp; /* Current interpreter. */
int objc; /* Number of arguments. */
Tcl_Obj *CONST objv[]; /* Argument objects. */
{
| < < < < | < | 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 |
int
Tcl_SourceObjCmd(dummy, interp, objc, objv)
ClientData dummy; /* Not used. */
Tcl_Interp *interp; /* Current interpreter. */
int objc; /* Number of arguments. */
Tcl_Obj *CONST objv[]; /* Argument objects. */
{
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, "fileName");
return TCL_ERROR;
}
return Tcl_FSEvalFile(interp, objv[1]);
}
/*
*----------------------------------------------------------------------
*
* Tcl_SplitObjCmd --
*
|
| ︙ | ︙ |
Changes to generic/tclDate.c.
1 2 3 4 5 6 7 8 9 10 11 12 | /* * tclDate.c -- * * This file is generated from a yacc grammar defined in * the file tclGetDate.y. It should not be edited directly. * * Copyright (c) 1992-1995 Karl Lehenbauer and Mark Diekhans. * Copyright (c) 1995-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | /* * tclDate.c -- * * This file is generated from a yacc grammar defined in * the file tclGetDate.y. It should not be edited directly. * * Copyright (c) 1992-1995 Karl Lehenbauer and Mark Diekhans. * Copyright (c) 1995-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclDate.c,v 1.19 2001/07/31 19:12:06 vincentdarley Exp $ */ #include "tclInt.h" #include "tclPort.h" #if defined(MAC_TCL) && !defined(TCL_MAC_USE_MSL_EPOCH) # define EPOCH 1904 # define START_OF_TIME 1904 # define END_OF_TIME 2039 #else # define EPOCH 1970 # define START_OF_TIME 1902 # define END_OF_TIME 2037 |
| ︙ | ︙ |
Changes to generic/tclDecls.h.
1 2 3 4 5 6 7 8 9 10 | /* * tclDecls.h -- * * Declarations of functions in the platform independent public Tcl API. * * Copyright (c) 1998-1999 by Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | /* * tclDecls.h -- * * Declarations of functions in the platform independent public Tcl API. * * Copyright (c) 1998-1999 by Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclDecls.h,v 1.53 2001/07/31 19:12:06 vincentdarley Exp $ */ #ifndef _TCLDECLS #define _TCLDECLS /* * WARNING: This file is automatically generated by the tools/genStubs.tcl |
| ︙ | ︙ | |||
1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 |
ClientData * clientDataPtr));
/* 436 */
EXTERN Tcl_Obj * Tcl_ListMathFuncs _ANSI_ARGS_((Tcl_Interp * interp,
CONST char * pattern));
/* 437 */
EXTERN Tcl_Obj * Tcl_SubstObj _ANSI_ARGS_((Tcl_Interp * interp,
Tcl_Obj * objPtr, int flags));
typedef struct TclStubHooks {
struct TclPlatStubs *tclPlatStubs;
struct TclIntStubs *tclIntStubs;
struct TclIntPlatStubs *tclIntPlatStubs;
} TclStubHooks;
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 |
ClientData * clientDataPtr));
/* 436 */
EXTERN Tcl_Obj * Tcl_ListMathFuncs _ANSI_ARGS_((Tcl_Interp * interp,
CONST char * pattern));
/* 437 */
EXTERN Tcl_Obj * Tcl_SubstObj _ANSI_ARGS_((Tcl_Interp * interp,
Tcl_Obj * objPtr, int flags));
/* 438 */
EXTERN int Tcl_DetachChannel _ANSI_ARGS_((Tcl_Interp* interp,
Tcl_Channel channel));
/* 439 */
EXTERN int Tcl_IsStandardChannel _ANSI_ARGS_((
Tcl_Channel channel));
/* 440 */
EXTERN int Tcl_FSCopyFile _ANSI_ARGS_((Tcl_Obj * srcPathPtr,
Tcl_Obj * destPathPtr));
/* 441 */
EXTERN int Tcl_FSCopyDirectory _ANSI_ARGS_((
Tcl_Obj * srcPathPtr, Tcl_Obj * destPathPtr,
Tcl_Obj ** errorPtr));
/* 442 */
EXTERN int Tcl_FSCreateDirectory _ANSI_ARGS_((Tcl_Obj * pathPtr));
/* 443 */
EXTERN int Tcl_FSDeleteFile _ANSI_ARGS_((Tcl_Obj * pathPtr));
/* 444 */
EXTERN int Tcl_FSLoadFile _ANSI_ARGS_((Tcl_Interp * interp,
Tcl_Obj * pathPtr, char * sym1, char * sym2,
Tcl_PackageInitProc ** proc1Ptr,
Tcl_PackageInitProc ** proc2Ptr,
ClientData * clientDataPtr,
Tcl_FSUnloadFileProc ** unloadProcPtr));
/* 445 */
EXTERN int Tcl_FSMatchInDirectory _ANSI_ARGS_((
Tcl_Interp * interp, Tcl_Obj * result,
Tcl_Obj * pathPtr, char * pattern,
Tcl_GlobTypeData * types));
/* 446 */
EXTERN Tcl_Obj* Tcl_FSReadlink _ANSI_ARGS_((Tcl_Obj * pathPtr));
/* 447 */
EXTERN int Tcl_FSRemoveDirectory _ANSI_ARGS_((Tcl_Obj * pathPtr,
int recursive, Tcl_Obj ** errorPtr));
/* 448 */
EXTERN int Tcl_FSRenameFile _ANSI_ARGS_((Tcl_Obj * srcPathPtr,
Tcl_Obj * destPathPtr));
/* 449 */
EXTERN int Tcl_FSLstat _ANSI_ARGS_((Tcl_Obj * pathPtr,
struct stat * buf));
/* 450 */
EXTERN int Tcl_FSUtime _ANSI_ARGS_((Tcl_Obj * pathPtr,
struct utimbuf * tval));
/* 451 */
EXTERN int Tcl_FSFileAttrsGet _ANSI_ARGS_((Tcl_Interp * interp,
int index, Tcl_Obj * pathPtr,
Tcl_Obj ** objPtrRef));
/* 452 */
EXTERN int Tcl_FSFileAttrsSet _ANSI_ARGS_((Tcl_Interp * interp,
int index, Tcl_Obj * pathPtr,
Tcl_Obj * objPtr));
/* 453 */
EXTERN char** Tcl_FSFileAttrStrings _ANSI_ARGS_((Tcl_Obj * pathPtr,
Tcl_Obj ** objPtrRef));
/* 454 */
EXTERN int Tcl_FSStat _ANSI_ARGS_((Tcl_Obj * pathPtr,
struct stat * buf));
/* 455 */
EXTERN int Tcl_FSAccess _ANSI_ARGS_((Tcl_Obj * pathPtr,
int mode));
/* 456 */
EXTERN Tcl_Channel Tcl_FSOpenFileChannel _ANSI_ARGS_((
Tcl_Interp * interp, Tcl_Obj * pathPtr,
char * modeString, int permissions));
/* 457 */
EXTERN Tcl_Obj* Tcl_FSGetCwd _ANSI_ARGS_((Tcl_Interp * interp));
/* 458 */
EXTERN int Tcl_FSChdir _ANSI_ARGS_((Tcl_Obj * pathPtr));
/* 459 */
EXTERN int Tcl_FSConvertToPathType _ANSI_ARGS_((
Tcl_Interp * interp, Tcl_Obj * pathPtr));
/* 460 */
EXTERN Tcl_Obj* Tcl_FSJoinPath _ANSI_ARGS_((Tcl_Obj * listObj,
int elements));
/* 461 */
EXTERN Tcl_Obj* Tcl_FSSplitPath _ANSI_ARGS_((Tcl_Obj* pathPtr,
int * lenPtr));
/* 462 */
EXTERN int Tcl_FSEqualPaths _ANSI_ARGS_((Tcl_Obj* firstPtr,
Tcl_Obj* secondPtr));
/* 463 */
EXTERN Tcl_Obj* Tcl_FSGetNormalizedPath _ANSI_ARGS_((
Tcl_Interp * interp, Tcl_Obj* pathObjPtr));
/* 464 */
EXTERN Tcl_Obj* Tcl_FSJoinToPath _ANSI_ARGS_((Tcl_Obj * basePtr,
int objc, Tcl_Obj *CONST objv[]));
/* 465 */
EXTERN ClientData Tcl_FSGetInternalRep _ANSI_ARGS_((
Tcl_Obj* pathObjPtr, Tcl_Filesystem * fsPtr));
/* 466 */
EXTERN char* Tcl_FSGetTranslatedPath _ANSI_ARGS_((
Tcl_Interp * interp, Tcl_Obj* pathPtr));
/* 467 */
EXTERN int Tcl_FSEvalFile _ANSI_ARGS_((Tcl_Interp * interp,
Tcl_Obj * fileName));
/* 468 */
EXTERN Tcl_Obj* Tcl_FSNewNativePath _ANSI_ARGS_((
Tcl_Obj* fromFilesystem,
ClientData clientData));
/* 469 */
EXTERN char* Tcl_FSGetNativePath _ANSI_ARGS_((Tcl_Obj* pathObjPtr));
/* 470 */
EXTERN Tcl_Obj* Tcl_FSFileSystemInfo _ANSI_ARGS_((
Tcl_Obj* pathObjPtr));
/* 471 */
EXTERN Tcl_Obj* Tcl_FSPathSeparator _ANSI_ARGS_((Tcl_Obj* pathObjPtr));
/* 472 */
EXTERN int Tcl_FSListVolumes _ANSI_ARGS_((Tcl_Interp * interp));
/* 473 */
EXTERN int Tcl_FSRegister _ANSI_ARGS_((ClientData clientData,
Tcl_Filesystem * fsPtr));
/* 474 */
EXTERN int Tcl_FSUnregister _ANSI_ARGS_((Tcl_Filesystem * fsPtr));
/* 475 */
EXTERN ClientData Tcl_FSData _ANSI_ARGS_((Tcl_Filesystem * fsPtr));
typedef struct TclStubHooks {
struct TclPlatStubs *tclPlatStubs;
struct TclIntStubs *tclIntStubs;
struct TclIntPlatStubs *tclIntPlatStubs;
} TclStubHooks;
|
| ︙ | ︙ | |||
1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 |
char * (*tcl_AttemptDbCkrealloc) _ANSI_ARGS_((char * ptr, unsigned int size, char * file, int line)); /* 431 */
int (*tcl_AttemptSetObjLength) _ANSI_ARGS_((Tcl_Obj * objPtr, int length)); /* 432 */
Tcl_ThreadId (*tcl_GetChannelThread) _ANSI_ARGS_((Tcl_Channel channel)); /* 433 */
Tcl_UniChar * (*tcl_GetUnicodeFromObj) _ANSI_ARGS_((Tcl_Obj * objPtr, int * lengthPtr)); /* 434 */
int (*tcl_GetMathFuncInfo) _ANSI_ARGS_((Tcl_Interp * interp, CONST char * name, int * numArgsPtr, Tcl_ValueType ** argTypesPtr, Tcl_MathProc ** procPtr, ClientData * clientDataPtr)); /* 435 */
Tcl_Obj * (*tcl_ListMathFuncs) _ANSI_ARGS_((Tcl_Interp * interp, CONST char * pattern)); /* 436 */
Tcl_Obj * (*tcl_SubstObj) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * objPtr, int flags)); /* 437 */
} TclStubs;
#ifdef __cplusplus
extern "C" {
#endif
extern TclStubs *tclStubsPtr;
#ifdef __cplusplus
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 |
char * (*tcl_AttemptDbCkrealloc) _ANSI_ARGS_((char * ptr, unsigned int size, char * file, int line)); /* 431 */
int (*tcl_AttemptSetObjLength) _ANSI_ARGS_((Tcl_Obj * objPtr, int length)); /* 432 */
Tcl_ThreadId (*tcl_GetChannelThread) _ANSI_ARGS_((Tcl_Channel channel)); /* 433 */
Tcl_UniChar * (*tcl_GetUnicodeFromObj) _ANSI_ARGS_((Tcl_Obj * objPtr, int * lengthPtr)); /* 434 */
int (*tcl_GetMathFuncInfo) _ANSI_ARGS_((Tcl_Interp * interp, CONST char * name, int * numArgsPtr, Tcl_ValueType ** argTypesPtr, Tcl_MathProc ** procPtr, ClientData * clientDataPtr)); /* 435 */
Tcl_Obj * (*tcl_ListMathFuncs) _ANSI_ARGS_((Tcl_Interp * interp, CONST char * pattern)); /* 436 */
Tcl_Obj * (*tcl_SubstObj) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * objPtr, int flags)); /* 437 */
int (*tcl_DetachChannel) _ANSI_ARGS_((Tcl_Interp* interp, Tcl_Channel channel)); /* 438 */
int (*tcl_IsStandardChannel) _ANSI_ARGS_((Tcl_Channel channel)); /* 439 */
int (*tcl_FSCopyFile) _ANSI_ARGS_((Tcl_Obj * srcPathPtr, Tcl_Obj * destPathPtr)); /* 440 */
int (*tcl_FSCopyDirectory) _ANSI_ARGS_((Tcl_Obj * srcPathPtr, Tcl_Obj * destPathPtr, Tcl_Obj ** errorPtr)); /* 441 */
int (*tcl_FSCreateDirectory) _ANSI_ARGS_((Tcl_Obj * pathPtr)); /* 442 */
int (*tcl_FSDeleteFile) _ANSI_ARGS_((Tcl_Obj * pathPtr)); /* 443 */
int (*tcl_FSLoadFile) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * pathPtr, char * sym1, char * sym2, Tcl_PackageInitProc ** proc1Ptr, Tcl_PackageInitProc ** proc2Ptr, ClientData * clientDataPtr, Tcl_FSUnloadFileProc ** unloadProcPtr)); /* 444 */
int (*tcl_FSMatchInDirectory) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * result, Tcl_Obj * pathPtr, char * pattern, Tcl_GlobTypeData * types)); /* 445 */
Tcl_Obj* (*tcl_FSReadlink) _ANSI_ARGS_((Tcl_Obj * pathPtr)); /* 446 */
int (*tcl_FSRemoveDirectory) _ANSI_ARGS_((Tcl_Obj * pathPtr, int recursive, Tcl_Obj ** errorPtr)); /* 447 */
int (*tcl_FSRenameFile) _ANSI_ARGS_((Tcl_Obj * srcPathPtr, Tcl_Obj * destPathPtr)); /* 448 */
int (*tcl_FSLstat) _ANSI_ARGS_((Tcl_Obj * pathPtr, struct stat * buf)); /* 449 */
int (*tcl_FSUtime) _ANSI_ARGS_((Tcl_Obj * pathPtr, struct utimbuf * tval)); /* 450 */
int (*tcl_FSFileAttrsGet) _ANSI_ARGS_((Tcl_Interp * interp, int index, Tcl_Obj * pathPtr, Tcl_Obj ** objPtrRef)); /* 451 */
int (*tcl_FSFileAttrsSet) _ANSI_ARGS_((Tcl_Interp * interp, int index, Tcl_Obj * pathPtr, Tcl_Obj * objPtr)); /* 452 */
char** (*tcl_FSFileAttrStrings) _ANSI_ARGS_((Tcl_Obj * pathPtr, Tcl_Obj ** objPtrRef)); /* 453 */
int (*tcl_FSStat) _ANSI_ARGS_((Tcl_Obj * pathPtr, struct stat * buf)); /* 454 */
int (*tcl_FSAccess) _ANSI_ARGS_((Tcl_Obj * pathPtr, int mode)); /* 455 */
Tcl_Channel (*tcl_FSOpenFileChannel) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * pathPtr, char * modeString, int permissions)); /* 456 */
Tcl_Obj* (*tcl_FSGetCwd) _ANSI_ARGS_((Tcl_Interp * interp)); /* 457 */
int (*tcl_FSChdir) _ANSI_ARGS_((Tcl_Obj * pathPtr)); /* 458 */
int (*tcl_FSConvertToPathType) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * pathPtr)); /* 459 */
Tcl_Obj* (*tcl_FSJoinPath) _ANSI_ARGS_((Tcl_Obj * listObj, int elements)); /* 460 */
Tcl_Obj* (*tcl_FSSplitPath) _ANSI_ARGS_((Tcl_Obj* pathPtr, int * lenPtr)); /* 461 */
int (*tcl_FSEqualPaths) _ANSI_ARGS_((Tcl_Obj* firstPtr, Tcl_Obj* secondPtr)); /* 462 */
Tcl_Obj* (*tcl_FSGetNormalizedPath) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj* pathObjPtr)); /* 463 */
Tcl_Obj* (*tcl_FSJoinToPath) _ANSI_ARGS_((Tcl_Obj * basePtr, int objc, Tcl_Obj *CONST objv[])); /* 464 */
ClientData (*tcl_FSGetInternalRep) _ANSI_ARGS_((Tcl_Obj* pathObjPtr, Tcl_Filesystem * fsPtr)); /* 465 */
char* (*tcl_FSGetTranslatedPath) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj* pathPtr)); /* 466 */
int (*tcl_FSEvalFile) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * fileName)); /* 467 */
Tcl_Obj* (*tcl_FSNewNativePath) _ANSI_ARGS_((Tcl_Obj* fromFilesystem, ClientData clientData)); /* 468 */
char* (*tcl_FSGetNativePath) _ANSI_ARGS_((Tcl_Obj* pathObjPtr)); /* 469 */
Tcl_Obj* (*tcl_FSFileSystemInfo) _ANSI_ARGS_((Tcl_Obj* pathObjPtr)); /* 470 */
Tcl_Obj* (*tcl_FSPathSeparator) _ANSI_ARGS_((Tcl_Obj* pathObjPtr)); /* 471 */
int (*tcl_FSListVolumes) _ANSI_ARGS_((Tcl_Interp * interp)); /* 472 */
int (*tcl_FSRegister) _ANSI_ARGS_((ClientData clientData, Tcl_Filesystem * fsPtr)); /* 473 */
int (*tcl_FSUnregister) _ANSI_ARGS_((Tcl_Filesystem * fsPtr)); /* 474 */
ClientData (*tcl_FSData) _ANSI_ARGS_((Tcl_Filesystem * fsPtr)); /* 475 */
} TclStubs;
#ifdef __cplusplus
extern "C" {
#endif
extern TclStubs *tclStubsPtr;
#ifdef __cplusplus
|
| ︙ | ︙ | |||
3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 | #define Tcl_ListMathFuncs \ (tclStubsPtr->tcl_ListMathFuncs) /* 436 */ #endif #ifndef Tcl_SubstObj #define Tcl_SubstObj \ (tclStubsPtr->tcl_SubstObj) /* 437 */ #endif #endif /* defined(USE_TCL_STUBS) && !defined(USE_TCL_STUB_PROCS) */ /* !END!: Do not edit above this line. */ #endif /* _TCLDECLS */ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 | #define Tcl_ListMathFuncs \ (tclStubsPtr->tcl_ListMathFuncs) /* 436 */ #endif #ifndef Tcl_SubstObj #define Tcl_SubstObj \ (tclStubsPtr->tcl_SubstObj) /* 437 */ #endif #ifndef Tcl_DetachChannel #define Tcl_DetachChannel \ (tclStubsPtr->tcl_DetachChannel) /* 438 */ #endif #ifndef Tcl_IsStandardChannel #define Tcl_IsStandardChannel \ (tclStubsPtr->tcl_IsStandardChannel) /* 439 */ #endif #ifndef Tcl_FSCopyFile #define Tcl_FSCopyFile \ (tclStubsPtr->tcl_FSCopyFile) /* 440 */ #endif #ifndef Tcl_FSCopyDirectory #define Tcl_FSCopyDirectory \ (tclStubsPtr->tcl_FSCopyDirectory) /* 441 */ #endif #ifndef Tcl_FSCreateDirectory #define Tcl_FSCreateDirectory \ (tclStubsPtr->tcl_FSCreateDirectory) /* 442 */ #endif #ifndef Tcl_FSDeleteFile #define Tcl_FSDeleteFile \ (tclStubsPtr->tcl_FSDeleteFile) /* 443 */ #endif #ifndef Tcl_FSLoadFile #define Tcl_FSLoadFile \ (tclStubsPtr->tcl_FSLoadFile) /* 444 */ #endif #ifndef Tcl_FSMatchInDirectory #define Tcl_FSMatchInDirectory \ (tclStubsPtr->tcl_FSMatchInDirectory) /* 445 */ #endif #ifndef Tcl_FSReadlink #define Tcl_FSReadlink \ (tclStubsPtr->tcl_FSReadlink) /* 446 */ #endif #ifndef Tcl_FSRemoveDirectory #define Tcl_FSRemoveDirectory \ (tclStubsPtr->tcl_FSRemoveDirectory) /* 447 */ #endif #ifndef Tcl_FSRenameFile #define Tcl_FSRenameFile \ (tclStubsPtr->tcl_FSRenameFile) /* 448 */ #endif #ifndef Tcl_FSLstat #define Tcl_FSLstat \ (tclStubsPtr->tcl_FSLstat) /* 449 */ #endif #ifndef Tcl_FSUtime #define Tcl_FSUtime \ (tclStubsPtr->tcl_FSUtime) /* 450 */ #endif #ifndef Tcl_FSFileAttrsGet #define Tcl_FSFileAttrsGet \ (tclStubsPtr->tcl_FSFileAttrsGet) /* 451 */ #endif #ifndef Tcl_FSFileAttrsSet #define Tcl_FSFileAttrsSet \ (tclStubsPtr->tcl_FSFileAttrsSet) /* 452 */ #endif #ifndef Tcl_FSFileAttrStrings #define Tcl_FSFileAttrStrings \ (tclStubsPtr->tcl_FSFileAttrStrings) /* 453 */ #endif #ifndef Tcl_FSStat #define Tcl_FSStat \ (tclStubsPtr->tcl_FSStat) /* 454 */ #endif #ifndef Tcl_FSAccess #define Tcl_FSAccess \ (tclStubsPtr->tcl_FSAccess) /* 455 */ #endif #ifndef Tcl_FSOpenFileChannel #define Tcl_FSOpenFileChannel \ (tclStubsPtr->tcl_FSOpenFileChannel) /* 456 */ #endif #ifndef Tcl_FSGetCwd #define Tcl_FSGetCwd \ (tclStubsPtr->tcl_FSGetCwd) /* 457 */ #endif #ifndef Tcl_FSChdir #define Tcl_FSChdir \ (tclStubsPtr->tcl_FSChdir) /* 458 */ #endif #ifndef Tcl_FSConvertToPathType #define Tcl_FSConvertToPathType \ (tclStubsPtr->tcl_FSConvertToPathType) /* 459 */ #endif #ifndef Tcl_FSJoinPath #define Tcl_FSJoinPath \ (tclStubsPtr->tcl_FSJoinPath) /* 460 */ #endif #ifndef Tcl_FSSplitPath #define Tcl_FSSplitPath \ (tclStubsPtr->tcl_FSSplitPath) /* 461 */ #endif #ifndef Tcl_FSEqualPaths #define Tcl_FSEqualPaths \ (tclStubsPtr->tcl_FSEqualPaths) /* 462 */ #endif #ifndef Tcl_FSGetNormalizedPath #define Tcl_FSGetNormalizedPath \ (tclStubsPtr->tcl_FSGetNormalizedPath) /* 463 */ #endif #ifndef Tcl_FSJoinToPath #define Tcl_FSJoinToPath \ (tclStubsPtr->tcl_FSJoinToPath) /* 464 */ #endif #ifndef Tcl_FSGetInternalRep #define Tcl_FSGetInternalRep \ (tclStubsPtr->tcl_FSGetInternalRep) /* 465 */ #endif #ifndef Tcl_FSGetTranslatedPath #define Tcl_FSGetTranslatedPath \ (tclStubsPtr->tcl_FSGetTranslatedPath) /* 466 */ #endif #ifndef Tcl_FSEvalFile #define Tcl_FSEvalFile \ (tclStubsPtr->tcl_FSEvalFile) /* 467 */ #endif #ifndef Tcl_FSNewNativePath #define Tcl_FSNewNativePath \ (tclStubsPtr->tcl_FSNewNativePath) /* 468 */ #endif #ifndef Tcl_FSGetNativePath #define Tcl_FSGetNativePath \ (tclStubsPtr->tcl_FSGetNativePath) /* 469 */ #endif #ifndef Tcl_FSFileSystemInfo #define Tcl_FSFileSystemInfo \ (tclStubsPtr->tcl_FSFileSystemInfo) /* 470 */ #endif #ifndef Tcl_FSPathSeparator #define Tcl_FSPathSeparator \ (tclStubsPtr->tcl_FSPathSeparator) /* 471 */ #endif #ifndef Tcl_FSListVolumes #define Tcl_FSListVolumes \ (tclStubsPtr->tcl_FSListVolumes) /* 472 */ #endif #ifndef Tcl_FSRegister #define Tcl_FSRegister \ (tclStubsPtr->tcl_FSRegister) /* 473 */ #endif #ifndef Tcl_FSUnregister #define Tcl_FSUnregister \ (tclStubsPtr->tcl_FSUnregister) /* 474 */ #endif #ifndef Tcl_FSData #define Tcl_FSData \ (tclStubsPtr->tcl_FSData) /* 475 */ #endif #endif /* defined(USE_TCL_STUBS) && !defined(USE_TCL_STUB_PROCS) */ /* !END!: Do not edit above this line. */ #endif /* _TCLDECLS */ |
Changes to generic/tclEncoding.c.
1 2 3 4 5 6 7 8 9 10 | /* * tclEncoding.c -- * * Contains the implementation of the encoding conversion package. * * Copyright (c) 1996-1998 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | /* * tclEncoding.c -- * * Contains the implementation of the encoding conversion package. * * Copyright (c) 1996-1998 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclEncoding.c,v 1.7 2001/07/31 19:12:06 vincentdarley Exp $ */ #include "tclInt.h" #include "tclPort.h" typedef size_t (LengthProc)_ANSI_ARGS_((CONST char *src)); |
| ︙ | ︙ | |||
559 560 561 562 563 564 565 |
}
Tcl_MutexUnlock(&encodingMutex);
pathPtr = TclGetLibraryPath();
if (pathPtr != NULL) {
int i, objc;
Tcl_Obj **objv;
| < > > | < < < < | | > > > > | > < > > | > | > | > > > > | | | 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 |
}
Tcl_MutexUnlock(&encodingMutex);
pathPtr = TclGetLibraryPath();
if (pathPtr != NULL) {
int i, objc;
Tcl_Obj **objv;
char globArgString[10];
Tcl_Obj* encodingObj = Tcl_NewStringObj("encoding",-1);
Tcl_IncrRefCount(encodingObj);
objc = 0;
Tcl_ListObjGetElements(NULL, pathPtr, &objc, &objv);
for (i = 0; i < objc; i++) {
Tcl_Obj *searchIn;
/*
* Construct the path from the element of pathPtr,
* joined with 'encoding'.
*/
searchIn = Tcl_FSJoinToPath(objv[i],1,&encodingObj);
Tcl_IncrRefCount(searchIn);
Tcl_ResetResult(interp);
/*
* TclGlob() changes the contents of globArgString, which causes
* a segfault if we pass in a pointer to non-writeable memory.
* TclGlob() puts its results directly into interp.
*/
strcpy(globArgString, "*.enc");
/*
* The GLOBMODE_TAILS flag returns just the tail of each file
* which is the encoding name with a .enc extension
*/
if ((TclGlob(interp, globArgString, searchIn,
TCL_GLOBMODE_TAILS, NULL) == TCL_OK)) {
int objc2 = 0;
Tcl_Obj **objv2;
int j;
Tcl_ListObjGetElements(NULL, Tcl_GetObjResult(interp), &objc2,
&objv2);
for (j = 0; j < objc2; j++) {
int length;
char *string;
string = Tcl_GetStringFromObj(objv2[j], &length);
length -= 4;
if (length > 0) {
string[length] = '\0';
Tcl_CreateHashEntry(&table, string, &dummy);
string[length] = '.';
}
}
}
Tcl_DecrRefCount(searchIn);
}
Tcl_DecrRefCount(encodingObj);
}
/*
* Clear any values placed in the result by globbing.
*/
Tcl_ResetResult(interp);
|
| ︙ | ︙ | |||
1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 |
CONST char *name;
{
char *argv[3];
Tcl_DString pathString;
char *path;
Tcl_Channel chan;
argv[0] = (char *) dir;
argv[1] = "encoding";
argv[2] = (char *) name;
Tcl_DStringInit(&pathString);
Tcl_JoinPath(3, argv, &pathString);
path = Tcl_DStringAppend(&pathString, ".enc", -1);
| > > > > | > > | 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 |
CONST char *name;
{
char *argv[3];
Tcl_DString pathString;
char *path;
Tcl_Channel chan;
Tcl_Obj *pathPtr;
argv[0] = (char *) dir;
argv[1] = "encoding";
argv[2] = (char *) name;
Tcl_DStringInit(&pathString);
Tcl_JoinPath(3, argv, &pathString);
path = Tcl_DStringAppend(&pathString, ".enc", -1);
pathPtr = Tcl_NewStringObj(path,-1);
Tcl_IncrRefCount(pathPtr);
chan = Tcl_FSOpenFileChannel(NULL, pathPtr, "r", 0);
Tcl_DecrRefCount(pathPtr);
Tcl_DStringFree(&pathString);
return chan;
}
/*
*-------------------------------------------------------------------------
|
| ︙ | ︙ |
Changes to generic/tclFCmd.c.
1 2 3 4 5 6 7 8 9 10 11 | /* * tclFCmd.c * * This file implements the generic portion of file manipulation * subcommands of the "file" command. * * Copyright (c) 1996-1998 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | /* * tclFCmd.c * * This file implements the generic portion of file manipulation * subcommands of the "file" command. * * Copyright (c) 1996-1998 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclFCmd.c,v 1.7 2001/07/31 19:12:06 vincentdarley Exp $ */ #include "tclInt.h" #include "tclPort.h" /* * Declarations for local procedures defined in this file: */ static int CopyRenameOneFile _ANSI_ARGS_((Tcl_Interp *interp, Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr, int copyFlag, int force)); static Tcl_Obj * FileBasename _ANSI_ARGS_((Tcl_Interp *interp, Tcl_Obj *pathPtr)); static int FileCopyRename _ANSI_ARGS_((Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], int copyFlag)); static int FileForceOption _ANSI_ARGS_((Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], int *forcePtr)); /* *--------------------------------------------------------------------------- * * TclFileRenameCmd * * This procedure implements the "rename" subcommand of the "file" |
| ︙ | ︙ | |||
45 46 47 48 49 50 51 | * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ int | | | | | | 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
* Side effects:
* See the user documentation.
*
*---------------------------------------------------------------------------
*/
int
TclFileRenameCmd(interp, objc, objv)
Tcl_Interp *interp; /* Interp for error reporting. */
int objc; /* Number of arguments. */
Tcl_Obj *CONST objv[]; /* Argument strings passed to Tcl_FileCmd. */
{
return FileCopyRename(interp, objc, objv, 0);
}
/*
*---------------------------------------------------------------------------
*
* TclFileCopyCmd
*
|
| ︙ | ︙ | |||
73 74 75 76 77 78 79 | * Side effects: * See the user documentation. * *--------------------------------------------------------------------------- */ int | | | | | | | | < | | | | > | < | > | | | | > | | < | | | | | | | > | > > | | < < | < | 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
* Side effects:
* See the user documentation.
*
*---------------------------------------------------------------------------
*/
int
TclFileCopyCmd(interp, objc, objv)
Tcl_Interp *interp; /* Used for error reporting */
int objc; /* Number of arguments. */
Tcl_Obj *CONST objv[]; /* Argument strings passed to Tcl_FileCmd. */
{
return FileCopyRename(interp, objc, objv, 1);
}
/*
*---------------------------------------------------------------------------
*
* FileCopyRename --
*
* Performs the work of TclFileRenameCmd and TclFileCopyCmd.
* See comments for those procedures.
*
* Results:
* See above.
*
* Side effects:
* See above.
*
*---------------------------------------------------------------------------
*/
static int
FileCopyRename(interp, objc, objv, copyFlag)
Tcl_Interp *interp; /* Used for error reporting. */
int objc; /* Number of arguments. */
Tcl_Obj *CONST objv[]; /* Argument strings passed to Tcl_FileCmd. */
int copyFlag; /* If non-zero, copy source(s). Otherwise,
* rename them. */
{
int i, result, force;
struct stat statBuf;
Tcl_Obj *target;
i = FileForceOption(interp, objc - 2, objv + 2, &force);
if (i < 0) {
return TCL_ERROR;
}
i += 2;
if ((objc - i) < 2) {
Tcl_AppendResult(interp, "wrong # args: should be \"",
Tcl_GetString(objv[0]), " ", Tcl_GetString(objv[1]),
" ?options? source ?source ...? target\"",
(char *) NULL);
return TCL_ERROR;
}
/*
* If target doesn't exist or isn't a directory, try the copy/rename.
* More than 2 arguments is only valid if the target is an existing
* directory.
*/
target = objv[objc - 1];
if (Tcl_FSConvertToPathType(interp, target) != TCL_OK) {
return TCL_ERROR;
}
result = TCL_OK;
/*
* Call Tcl_FSStat() so that if target is a symlink that points to a
* directory we will put the sources in that directory instead of
* overwriting the symlink.
*/
if ((Tcl_FSStat(target, &statBuf) != 0) || !S_ISDIR(statBuf.st_mode)) {
if ((objc - i) > 2) {
errno = ENOTDIR;
Tcl_PosixError(interp);
Tcl_AppendResult(interp, "error ",
((copyFlag) ? "copying" : "renaming"), ": target \"",
Tcl_GetString(target), "\" is not a directory",
(char *) NULL);
result = TCL_ERROR;
} else {
/*
* Even though already have target == translated(objv[i+1]),
* pass the original argument down, so if there's an error, the
* error message will reflect the original arguments.
*/
result = CopyRenameOneFile(interp, objv[i], objv[i + 1], copyFlag,
force);
}
return result;
}
/*
* Move each source file into target directory. Extract the basename
* from each source, and append it to the end of the target path.
*/
for ( ; i < objc - 1; i++) {
Tcl_Obj *jargv[2];
Tcl_Obj *source, *newFileName;
Tcl_Obj *temp;
source = FileBasename(interp, objv[i]);
if (source == NULL) {
result = TCL_ERROR;
break;
}
jargv[0] = objv[objc - 1];
jargv[1] = source;
temp = Tcl_NewListObj(2, jargv);
newFileName = Tcl_FSJoinPath(temp, -1);
Tcl_IncrRefCount(newFileName);
Tcl_DecrRefCount(temp);
result = CopyRenameOneFile(interp, objv[i], newFileName, copyFlag,
force);
Tcl_DecrRefCount(newFileName);
if (result == TCL_ERROR) {
break;
}
}
return result;
}
/*
*---------------------------------------------------------------------------
*
* TclFileMakeDirsCmd
|
| ︙ | ︙ | |||
215 216 217 218 219 220 221 | * * Side effects: * See the user documentation. * *---------------------------------------------------------------------- */ int | | | | < | | > | < < < | < | | | | | | | | | | > > | < > | < | > > > | < < | | | 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 |
*
* Side effects:
* See the user documentation.
*
*----------------------------------------------------------------------
*/
int
TclFileMakeDirsCmd(interp, objc, objv)
Tcl_Interp *interp; /* Used for error reporting. */
int objc; /* Number of arguments */
Tcl_Obj *CONST objv[]; /* Argument strings passed to Tcl_FileCmd. */
{
Tcl_Obj *errfile;
int result, i, j, pobjc;
Tcl_Obj *split = NULL;
Tcl_Obj *target = NULL;
struct stat statBuf;
errfile = NULL;
result = TCL_OK;
for (i = 2; i < objc; i++) {
if (Tcl_FSConvertToPathType(interp, objv[i]) != TCL_OK) {
result = TCL_ERROR;
break;
}
split = Tcl_FSSplitPath(objv[i],&pobjc);
if (pobjc == 0) {
errno = ENOENT;
errfile = objv[i];
break;
}
for (j = 0; j < pobjc; j++) {
target = Tcl_FSJoinPath(split, j + 1);
Tcl_IncrRefCount(target);
/*
* Call Tcl_Stat() so that if target is a symlink that points
* to a directory we will create subdirectories in that
* directory.
*/
if (Tcl_FSStat(target, &statBuf) == 0) {
if (!S_ISDIR(statBuf.st_mode)) {
errno = EEXIST;
errfile = target;
goto done;
}
} else if ((errno != ENOENT)
|| (Tcl_FSCreateDirectory(target) != TCL_OK)) {
errfile = target;
goto done;
}
/* Forget about this sub-path */
Tcl_DecrRefCount(target);
target = NULL;
}
Tcl_DecrRefCount(split);
split = NULL;
}
done:
if (errfile != NULL) {
Tcl_AppendResult(interp, "can't create directory \"",
Tcl_GetString(errfile), "\": ", Tcl_PosixError(interp),
(char *) NULL);
result = TCL_ERROR;
}
if (split != NULL) {
Tcl_DecrRefCount(split);
}
if (target != NULL) {
Tcl_DecrRefCount(target);
}
return result;
}
/*
*----------------------------------------------------------------------
*
|
| ︙ | ︙ | |||
305 306 307 308 309 310 311 | * Side effects: * See the user documentation. * *---------------------------------------------------------------------- */ int | | | | < | | | | > | < < | < | < < | | > | | > | > | | | > > > > > | | > > > > | > < < | 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 |
* Side effects:
* See the user documentation.
*
*----------------------------------------------------------------------
*/
int
TclFileDeleteCmd(interp, objc, objv)
Tcl_Interp *interp; /* Used for error reporting */
int objc; /* Number of arguments */
Tcl_Obj *CONST objv[]; /* Argument strings passed to Tcl_FileCmd. */
{
int i, force, result;
Tcl_Obj *errfile;
i = FileForceOption(interp, objc - 2, objv + 2, &force);
if (i < 0) {
return TCL_ERROR;
}
i += 2;
if ((objc - i) < 1) {
Tcl_AppendResult(interp, "wrong # args: should be \"",
Tcl_GetString(objv[0]), " ", Tcl_GetString(objv[1]),
" ?options? file ?file ...?\"", (char *) NULL);
return TCL_ERROR;
}
errfile = NULL;
result = TCL_OK;
for ( ; i < objc; i++) {
struct stat statBuf;
errfile = objv[i];
if (Tcl_FSConvertToPathType(interp, objv[i]) != TCL_OK) {
result = TCL_ERROR;
goto done;
}
/*
* Call lstat() to get info so can delete symbolic link itself.
*/
if (Tcl_FSLstat(objv[i], &statBuf) != 0) {
/*
* Trying to delete a file that does not exist is not
* considered an error, just a no-op
*/
if (errno != ENOENT) {
result = TCL_ERROR;
}
} else if (S_ISDIR(statBuf.st_mode)) {
Tcl_Obj *errorBuffer = NULL;
result = Tcl_FSRemoveDirectory(objv[i], force, &errorBuffer);
if (result != TCL_OK) {
if ((force == 0) && (errno == EEXIST)) {
Tcl_AppendResult(interp, "error deleting \"",
Tcl_GetString(objv[i]),
"\": directory not empty", (char *) NULL);
Tcl_PosixError(interp);
goto done;
}
/*
* If possible, use the untranslated name for the file.
*/
errfile = errorBuffer;
/* FS supposed to check between translated objv and errfile */
if (Tcl_FSEqualPaths(objv[i], errfile)) {
errfile = objv[i];
}
}
} else {
result = Tcl_FSDeleteFile(objv[i]);
}
if (result == TCL_ERROR) {
break;
}
}
if (result != TCL_OK) {
if (errfile == NULL) {
/*
* We try to accomodate poor error results from our
* Tcl_FS calls
*/
Tcl_AppendResult(interp, "error deleting unknown file: ",
Tcl_PosixError(interp), (char *) NULL);
} else {
Tcl_AppendResult(interp, "error deleting \"",
Tcl_GetString(errfile), "\": ",
Tcl_PosixError(interp), (char *) NULL);
}
}
done:
return result;
}
/*
*---------------------------------------------------------------------------
*
* CopyRenameOneFile
|
| ︙ | ︙ | |||
414 415 416 417 418 419 420 |
*
*----------------------------------------------------------------------
*/
static int
CopyRenameOneFile(interp, source, target, copyFlag, force)
Tcl_Interp *interp; /* Used for error reporting. */
| | | < | < | | < < > < | | | 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 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 |
*
*----------------------------------------------------------------------
*/
static int
CopyRenameOneFile(interp, source, target, copyFlag, force)
Tcl_Interp *interp; /* Used for error reporting. */
Tcl_Obj *source; /* Pathname of file to copy. May need to
* be translated. */
Tcl_Obj *target; /* Pathname of file to create/overwrite.
* May need to be translated. */
int copyFlag; /* If non-zero, copy files. Otherwise,
* rename them. */
int force; /* If non-zero, overwrite target file if it
* exists. Otherwise, error if target already
* exists. */
{
int result;
Tcl_Obj *errfile, *errorBuffer;
struct stat sourceStatBuf, targetStatBuf;
if (Tcl_FSConvertToPathType(interp, source) != TCL_OK) {
return TCL_ERROR;
}
if (Tcl_FSConvertToPathType(interp, target) != TCL_OK) {
return TCL_ERROR;
}
errfile = NULL;
errorBuffer = NULL;
result = TCL_ERROR;
/*
* We want to copy/rename links and not the files they point to, so we
* use lstat(). If target is a link, we also want to replace the
* link and not the file it points to, so we also use lstat() on the
* target.
*/
if (Tcl_FSLstat(source, &sourceStatBuf) != 0) {
errfile = source;
goto done;
}
if (Tcl_FSLstat(target, &targetStatBuf) != 0) {
if (errno != ENOENT) {
errfile = target;
goto done;
}
} else {
if (force == 0) {
errno = EEXIST;
|
| ︙ | ︙ | |||
491 492 493 494 495 496 497 |
* existing implementations of copy and rename on all platforms
* also prevent this.
*/
if (S_ISDIR(sourceStatBuf.st_mode)
&& !S_ISDIR(targetStatBuf.st_mode)) {
errno = EISDIR;
| | > | | > | | | > | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > | | | | | | > | | < > | > > > > > > > | > > > > > > > > > > > > > > > > > | > > | > > > > > > > > > > > > > > | < | | | > | | | > | > | | < > | 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 |
* existing implementations of copy and rename on all platforms
* also prevent this.
*/
if (S_ISDIR(sourceStatBuf.st_mode)
&& !S_ISDIR(targetStatBuf.st_mode)) {
errno = EISDIR;
Tcl_AppendResult(interp, "can't overwrite file \"",
Tcl_GetString(target), "\" with directory \"",
Tcl_GetString(source), "\"", (char *) NULL);
goto done;
}
if (!S_ISDIR(sourceStatBuf.st_mode)
&& S_ISDIR(targetStatBuf.st_mode)) {
errno = EISDIR;
Tcl_AppendResult(interp, "can't overwrite directory \"",
Tcl_GetString(target), "\" with file \"",
Tcl_GetString(source), "\"", (char *) NULL);
goto done;
}
}
if (copyFlag == 0) {
result = Tcl_FSRenameFile(source, target);
if (result == TCL_OK) {
goto done;
}
if (errno == EINVAL) {
Tcl_AppendResult(interp, "error renaming \"",
Tcl_GetString(source), "\" to \"",
Tcl_GetString(target), "\": trying to rename a volume or ",
"move a directory into itself", (char *) NULL);
goto done;
} else if (errno != EXDEV) {
errfile = target;
goto done;
}
/*
* The rename failed because the move was across file systems.
* Fall through to copy file and then remove original. Note that
* the low-level TclpRenameFile is allowed to implement
* cross-filesystem moves itself.
*/
}
if (S_ISDIR(sourceStatBuf.st_mode)) {
result = Tcl_FSCopyDirectory(source, target, &errorBuffer);
if (result != TCL_OK) {
if (errno == EXDEV) {
/*
* The copy failed because we're trying to do a
* cross-filesystem copy. We do this through our Tcl
* library.
*/
Tcl_SavedResult savedResult;
Tcl_Obj *copyCommand = Tcl_NewListObj(0,NULL);
Tcl_IncrRefCount(copyCommand);
Tcl_ListObjAppendElement(interp, copyCommand,
Tcl_NewStringObj("::tcl::CopyDirectory",-1));
if (copyFlag) {
Tcl_ListObjAppendElement(interp, copyCommand,
Tcl_NewStringObj("copying",-1));
} else {
Tcl_ListObjAppendElement(interp, copyCommand,
Tcl_NewStringObj("renaming",-1));
}
Tcl_ListObjAppendElement(interp, copyCommand, source);
Tcl_ListObjAppendElement(interp, copyCommand, target);
Tcl_SaveResult(interp, &savedResult);
result = Tcl_EvalObjEx(interp, copyCommand,
TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
Tcl_DecrRefCount(copyCommand);
if (result != TCL_OK) {
/*
* There was an error in the Tcl-level copy.
* We will pass on the Tcl error message and
* can ensure this by setting errfile to NULL
*/
Tcl_DiscardResult(&savedResult);
errfile = NULL;
} else {
/* The copy was successful */
Tcl_RestoreResult(interp, &savedResult);
}
} else {
errfile = errorBuffer;
if (Tcl_FSEqualPaths(errfile, source)) {
errfile = source;
} else if (Tcl_FSEqualPaths(errfile, target)) {
errfile = target;
}
}
}
} else {
result = Tcl_FSCopyFile(source, target);
if ((result != TCL_OK) && (errno == EXDEV)) {
/*
* Well, there really shouldn't be a problem with source,
* because up there we checked to see if it was ok to copy it.
*
* Either there is a problem with target, or we're trying
* to do a cross-filesystem copy. We open the target for
* writing to decide between those two cases.
*/
int prot = 0666;
Tcl_Channel out = Tcl_FSOpenFileChannel(interp, target, "w", prot);
if (out == NULL) {
/* There was a problem with the target */
errfile = target;
} else {
/* It looks like we can copy it over */
Tcl_Channel in = Tcl_FSOpenFileChannel(interp, source,
"r", prot);
if (in == NULL) {
/* This is very strange, we checked this above */
Tcl_Close(interp, out);
errfile = source;
} else {
struct utimbuf tval;
/*
* Copy it synchronously. We might wish to add an
* asynchronous option to support vfs's which are
* slow (e.g. network sockets).
*/
Tcl_SetChannelOption(interp, in, "-translation", "binary");
Tcl_SetChannelOption(interp, out, "-translation", "binary");
if (TclCopyChannel(interp, in, out, -1, NULL) == TCL_OK) {
result = TCL_OK;
}
/*
* If the copy failed, assume that copy channel left
* a good error message.
*/
Tcl_Close(interp, in);
Tcl_Close(interp, out);
/* Set modification date of copied file */
tval.actime = sourceStatBuf.st_atime;
tval.modtime = sourceStatBuf.st_mtime;
Tcl_FSUtime(source, &tval);
}
}
}
}
if ((copyFlag == 0) && (result == TCL_OK)) {
if (S_ISDIR(sourceStatBuf.st_mode)) {
result = Tcl_FSRemoveDirectory(source, 1, &errorBuffer);
if (result != TCL_OK) {
if (Tcl_FSEqualPaths(errfile, source) == 0) {
errfile = source;
}
}
} else {
result = Tcl_FSDeleteFile(source);
if (result != TCL_OK) {
errfile = source;
}
}
if (result != TCL_OK) {
Tcl_AppendResult(interp, "can't unlink \"",
Tcl_GetString(errfile), "\": ",
Tcl_PosixError(interp), (char *) NULL);
errfile = NULL;
}
}
done:
if (errfile != NULL) {
Tcl_AppendResult(interp,
((copyFlag) ? "error copying \"" : "error renaming \""),
Tcl_GetString(source), (char *) NULL);
if (errfile != source) {
Tcl_AppendResult(interp, "\" to \"", Tcl_GetString(target),
(char *) NULL);
if (errfile != target) {
Tcl_AppendResult(interp, "\": \"", Tcl_GetString(errfile),
(char *) NULL);
}
}
Tcl_AppendResult(interp, "\": ", Tcl_PosixError(interp),
(char *) NULL);
}
if (errorBuffer != NULL) {
Tcl_DecrRefCount(errorBuffer);
}
return result;
}
/*
*---------------------------------------------------------------------------
*
* FileForceOption --
|
| ︙ | ︙ | |||
612 613 614 615 616 617 618 | * Side effects: * None. * *--------------------------------------------------------------------------- */ static int | | | | | | | | | | 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 |
* Side effects:
* None.
*
*---------------------------------------------------------------------------
*/
static int
FileForceOption(interp, objc, objv, forcePtr)
Tcl_Interp *interp; /* Interp, for error return. */
int objc; /* Number of arguments. */
Tcl_Obj *CONST objv[]; /* Argument strings. First command line
* option, if it exists, begins at 0. */
int *forcePtr; /* If the "-force" was specified, *forcePtr
* is filled with 1, otherwise with 0. */
{
int force, i;
force = 0;
for (i = 0; i < objc; i++) {
if (Tcl_GetString(objv[i])[0] != '-') {
break;
}
if (strcmp(Tcl_GetString(objv[i]), "-force") == 0) {
force = 1;
} else if (strcmp(Tcl_GetString(objv[i]), "--") == 0) {
i++;
break;
} else {
Tcl_AppendResult(interp, "bad option \"", Tcl_GetString(objv[i]),
"\": should be -force or --", (char *)NULL);
return -1;
}
}
*forcePtr = force;
return i;
}
|
| ︙ | ︙ | |||
663 664 665 666 667 668 669 | * * Side effects: * None. * *--------------------------------------------------------------------------- */ | | | | < < | | > | > | < < | < < | < > > | < < | | > > > > | < > > | > > > > | | | | | | | | | 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 |
*
* Side effects:
* None.
*
*---------------------------------------------------------------------------
*/
static Tcl_Obj *
FileBasename(interp, pathPtr)
Tcl_Interp *interp; /* Interp, for error return. */
Tcl_Obj *pathPtr; /* Path whose basename to extract. */
{
int objc;
Tcl_Obj *split;
Tcl_Obj *resPtr = NULL;
split = Tcl_FSSplitPath(pathPtr, &objc);
if (objc != 0) {
if ((objc == 1) && (*Tcl_GetString(pathPtr) == '~')) {
if (Tcl_FSConvertToPathType(interp, pathPtr) != TCL_OK) {
Tcl_DecrRefCount(split);
return NULL;
}
Tcl_DecrRefCount(split);
split = Tcl_FSSplitPath(pathPtr, &objc);
}
/*
* Return the last component, unless it is the only component, and it
* is the root of an absolute path.
*/
if (objc > 0) {
if (objc > 1) {
Tcl_ListObjIndex(NULL, split, objc-1, &resPtr);
} else {
Tcl_Obj *temp;
Tcl_ListObjIndex(NULL, split, 0, &temp);
if (Tcl_GetPathType(Tcl_GetString(temp)) == TCL_PATH_RELATIVE) {
Tcl_ListObjIndex(NULL, split, objc-1, &resPtr);
}
}
}
}
if (resPtr == NULL) {
resPtr = Tcl_NewStringObj("",0);
}
Tcl_IncrRefCount(resPtr);
Tcl_DecrRefCount(split);
return resPtr;
}
/*
*----------------------------------------------------------------------
*
* TclFileAttrsCmd --
*
* Sets or gets the platform-specific attributes of a file. The
* objc-objv points to the file name with the rest of the command
* line following. This routine uses platform-specific tables of
* option strings and callbacks. The callback to get the
* attributes take three parameters:
* Tcl_Interp *interp; The interp to report errors with.
* Since this is an object-based API,
* the object form of the result should
* be used.
* CONST char *fileName; This is extracted using
* Tcl_TranslateFileName.
* TclObj **attrObjPtrPtr; A new object to hold the attribute
* is allocated and put here.
* The first two parameters of the callback used to write out the
* attributes are the same. The third parameter is:
* CONST *attrObjPtr; A pointer to the object that has
|
| ︙ | ︙ | |||
747 748 749 750 751 752 753 |
int
TclFileAttrsCmd(interp, objc, objv)
Tcl_Interp *interp; /* The interpreter for error reporting. */
int objc; /* Number of command line arguments. */
Tcl_Obj *CONST objv[]; /* The command line objects. */
{
| < > > | > | | | < > > > > > > | > > > > > > > > > > > > > | | | | > | | | | | > > > > > > > | | | > > > > > > > | | | > > > > > > > > > > | 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 |
int
TclFileAttrsCmd(interp, objc, objv)
Tcl_Interp *interp; /* The interpreter for error reporting. */
int objc; /* Number of command line arguments. */
Tcl_Obj *CONST objv[]; /* The command line objects. */
{
int result;
char ** attributeStrings;
Tcl_Obj* objStrings = NULL;
int numObjStrings = -1;
Tcl_Obj *filePtr;
if (objc < 3) {
Tcl_WrongNumArgs(interp, 2, objv,
"name ?option? ?value? ?option value ...?");
return TCL_ERROR;
}
filePtr = objv[2];
if (Tcl_FSConvertToPathType(interp, filePtr) != TCL_OK) {
return TCL_ERROR;
}
objc -= 3;
objv += 3;
result = TCL_ERROR;
attributeStrings = Tcl_FSFileAttrStrings(filePtr, &objStrings);
if (attributeStrings == NULL) {
int index;
Tcl_Obj *objPtr;
if (objStrings == NULL) {
goto end;
}
/* We own the object now */
Tcl_IncrRefCount(objStrings);
/* Use objStrings as a list object */
if (Tcl_ListObjLength(interp, objStrings, &numObjStrings) != TCL_OK) {
goto end;
}
attributeStrings = (char**)ckalloc((1+numObjStrings)*sizeof(char*));
for (index = 0; index < numObjStrings; index++) {
Tcl_ListObjIndex(interp, objStrings, index, &objPtr);
attributeStrings[index] = Tcl_GetString(objPtr);
}
attributeStrings[index] = NULL;
}
if (objc == 0) {
/*
* Get all attributes.
*/
int index;
Tcl_Obj *listPtr;
listPtr = Tcl_NewListObj(0, NULL);
for (index = 0; attributeStrings[index] != NULL; index++) {
Tcl_Obj *objPtr = Tcl_NewStringObj(attributeStrings[index], -1);
Tcl_ListObjAppendElement(interp, listPtr, objPtr);
/* We now forget about objPtr, it is in the list */
objPtr = NULL;
if (Tcl_FSFileAttrsGet(interp, index, filePtr,
&objPtr) != TCL_OK) {
Tcl_DecrRefCount(listPtr);
goto end;
}
Tcl_ListObjAppendElement(interp, listPtr, objPtr);
}
Tcl_SetObjResult(interp, listPtr);
} else if (objc == 1) {
/*
* Get one attribute.
*/
int index;
Tcl_Obj *objPtr = NULL;
if (numObjStrings == 0) {
Tcl_AppendResult(interp, "bad option \"",
Tcl_GetString(objv[0]), "\", there are no file attributes"
" in this filesystem.", (char *) NULL);
goto end;
}
if (Tcl_GetIndexFromObj(interp, objv[0], attributeStrings,
"option", 0, &index) != TCL_OK) {
goto end;
}
if (Tcl_FSFileAttrsGet(interp, index, filePtr,
&objPtr) != TCL_OK) {
goto end;
}
Tcl_SetObjResult(interp, objPtr);
} else {
/*
* Set option/value pairs.
*/
int i, index;
if (numObjStrings == 0) {
Tcl_AppendResult(interp, "bad option \"",
Tcl_GetString(objv[0]), "\", there are no file attributes"
" in this filesystem.", (char *) NULL);
goto end;
}
for (i = 0; i < objc ; i += 2) {
if (Tcl_GetIndexFromObj(interp, objv[i], attributeStrings,
"option", 0, &index) != TCL_OK) {
goto end;
}
if (i + 1 == objc) {
Tcl_AppendResult(interp, "value for \"",
Tcl_GetString(objv[i]), "\" missing",
(char *) NULL);
goto end;
}
if (Tcl_FSFileAttrsSet(interp, index, filePtr,
objv[i + 1]) != TCL_OK) {
goto end;
}
}
}
result = TCL_OK;
end:
if (numObjStrings != -1) {
/* Free up the array we allocated */
ckfree((char*)attributeStrings);
/*
* We don't need this object that was passed to us
* any more.
*/
if (objStrings != NULL) {
Tcl_DecrRefCount(objStrings);
}
}
return result;
}
|
Changes to generic/tclFileName.c.
1 2 3 4 5 6 7 8 9 10 11 12 | /* * tclFileName.c -- * * This file contains routines for converting file names betwen * native and network form. * * Copyright (c) 1995-1998 Sun Microsystems, Inc. * Copyright (c) 1998-1999 by Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | /* * tclFileName.c -- * * This file contains routines for converting file names betwen * native and network form. * * Copyright (c) 1995-1998 Sun Microsystems, Inc. * Copyright (c) 1998-1999 by Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclFileName.c,v 1.15 2001/07/31 19:12:06 vincentdarley Exp $ */ #include "tclInt.h" #include "tclPort.h" #include "tclRegexp.h" /* |
| ︙ | ︙ | |||
48 49 50 51 52 53 54 | /* * The following variable is set in the TclPlatformInit call to one * of: TCL_PLATFORM_UNIX, TCL_PLATFORM_MAC, or TCL_PLATFORM_WINDOWS. */ TclPlatformType tclPlatform = TCL_PLATFORM_UNIX; | < < < < < < < < < | > | 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | /* * The following variable is set in the TclPlatformInit call to one * of: TCL_PLATFORM_UNIX, TCL_PLATFORM_MAC, or TCL_PLATFORM_WINDOWS. */ TclPlatformType tclPlatform = TCL_PLATFORM_UNIX; /* * Prototypes for local procedures defined in this file: */ static char * DoTildeSubst _ANSI_ARGS_((Tcl_Interp *interp, CONST char *user, Tcl_DString *resultPtr)); static CONST char * ExtractWinRoot _ANSI_ARGS_((CONST char *path, Tcl_DString *resultPtr, int offset, Tcl_PathType *typePtr)); static void FileNameCleanup _ANSI_ARGS_((ClientData clientData)); static void FileNameInit _ANSI_ARGS_((void)); static int SkipToChar _ANSI_ARGS_((char **stringPtr, char *match)); static char * SplitMacPath _ANSI_ARGS_((CONST char *path, Tcl_DString *bufPtr)); static char * SplitWinPath _ANSI_ARGS_((CONST char *path, |
| ︙ | ︙ | |||
308 309 310 311 312 313 314 315 316 317 318 319 320 321 |
(VOID)ExtractWinRoot(path, &ds, 0, &type);
Tcl_DStringFree(&ds);
}
break;
}
return type;
}
/*
*----------------------------------------------------------------------
*
* Tcl_SplitPath --
*
* Split a path into a list of path components. The first element
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 |
(VOID)ExtractWinRoot(path, &ds, 0, &type);
Tcl_DStringFree(&ds);
}
break;
}
return type;
}
/*
*---------------------------------------------------------------------------
*
* Tcl_FSSplitPath --
*
* This function takes the given Tcl_Obj, which should be a valid
* path, and returns a Tcl List object containing each segment
* of that path as an element.
*
* Note this function currently calls the older Tcl_SplitPath
* routine, which therefore requires more memory allocation and
* deallocation than necessary. We could easily rewrite this for
* greater efficiency.
*
* Results:
* Returns list object with refCount of zero. If the passed in
* lenPtr is non-NULL, we use it to return the number of elements
* in the returned list.
*
* Side effects:
* None.
*
*---------------------------------------------------------------------------
*/
Tcl_Obj*
Tcl_FSSplitPath(Tcl_Obj* pathPtr, int *lenPtr) {
int argc, i;
char** argv;
Tcl_Obj* res;
Tcl_SplitPath(Tcl_GetString(pathPtr),&argc,&argv);
if (lenPtr != NULL) {
*lenPtr = argc;
}
res = Tcl_NewListObj(0,NULL);
for (i=0;i<argc;i++) {
Tcl_ListObjAppendElement(NULL, res, Tcl_NewStringObj(argv[i],-1));
}
ckfree((char*)argv);
return res;
}
/*
*----------------------------------------------------------------------
*
* Tcl_SplitPath --
*
* Split a path into a list of path components. The first element
|
| ︙ | ︙ | |||
733 734 735 736 737 738 739 740 741 742 743 744 745 746 |
if (*p++ == '\0') {
break;
}
}
}
return Tcl_DStringValue(bufPtr);
}
/*
*----------------------------------------------------------------------
*
* Tcl_JoinPath --
*
* Combine a list of paths in a platform specific manner.
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 |
if (*p++ == '\0') {
break;
}
}
}
return Tcl_DStringValue(bufPtr);
}
/*
*---------------------------------------------------------------------------
*
* Tcl_FSJoinToPath --
*
* This function takes the given object, which should usually be a
* valid path or NULL, and joins onto it the array of paths
* segments given.
*
* Results:
* Returns object with refCount of zero
*
* Side effects:
* None.
*
*---------------------------------------------------------------------------
*/
Tcl_Obj*
Tcl_FSJoinToPath(basePtr, objc, objv)
Tcl_Obj *basePtr;
int objc;
Tcl_Obj *CONST objv[];
{
int i;
Tcl_Obj *lobj, *ret;
if (basePtr == NULL) {
lobj = Tcl_NewListObj(0,NULL);
} else {
lobj = Tcl_NewListObj(1,&basePtr);
}
for (i = 0; i<objc;i++) {
Tcl_ListObjAppendElement(NULL, lobj, objv[i]);
}
ret = Tcl_FSJoinPath(lobj,-1);
Tcl_DecrRefCount(lobj);
return ret;
}
/*
*---------------------------------------------------------------------------
*
* Tcl_FSJoinPath --
*
* This function takes the given Tcl_Obj, which should be a valid
* list, and returns the path object given by considering the
* first 'elements' elements as valid path segments. If elements < 0,
* we use the entire list.
*
* Note this function currently calls the older Tcl_JoinPath
* routine, which therefore requires more memory allocation and
* deallocation than necessary. We could easily rewrite this for
* greater efficiency.
*
* Results:
* Returns object with refCount of zero.
*
* Side effects:
* None.
*
*---------------------------------------------------------------------------
*/
Tcl_Obj*
Tcl_FSJoinPath(listObj, elements)
Tcl_Obj *listObj;
int elements;
{
char ** argv;
int count;
Tcl_DString ds;
Tcl_Obj *res;
if (elements < 0) {
if (Tcl_ListObjLength(NULL, listObj, &elements) != TCL_OK) {
return NULL;
}
} else {
/* Just make sure it is a valid list */
int listTest;
if (Tcl_ListObjLength(NULL, listObj, &listTest) != TCL_OK) {
return NULL;
}
/*
* It doesn't actually matter if 'elements' is greater
* than the actual number of elements.
*/
}
argv = (char **)ckalloc(elements*sizeof(char*));
for (count = 0; count < elements; count++) {
Tcl_Obj* elt;
Tcl_ListObjIndex(NULL, listObj,count,&elt);
argv[count] = Tcl_GetString(elt);
}
Tcl_DStringInit(&ds);
res = Tcl_NewStringObj(Tcl_JoinPath(elements, argv, &ds),-1);
Tcl_DStringFree(&ds);
ckfree((char*)argv);
return res;
}
/*
*----------------------------------------------------------------------
*
* Tcl_JoinPath --
*
* Combine a list of paths in a platform specific manner.
|
| ︙ | ︙ | |||
1004 1005 1006 1007 1008 1009 1010 |
char *name; /* File name, which may begin with "~" (to
* indicate current user's home directory) or
* "~<user>" (to indicate any user's home
* directory). */
Tcl_DString *bufferPtr; /* Uninitialized or free DString filled
* with name after tilde substitution. */
{
| < < < | 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 |
char *name; /* File name, which may begin with "~" (to
* indicate current user's home directory) or
* "~<user>" (to indicate any user's home
* directory). */
Tcl_DString *bufferPtr; /* Uninitialized or free DString filled
* with name after tilde substitution. */
{
/*
* Handle tilde substitutions, if needed.
*/
if (name[0] == '~') {
int argc, length;
char **argv;
Tcl_DString temp;
Tcl_SplitPath(name, &argc, (char ***) &argv);
|
| ︙ | ︙ | |||
1035 1036 1037 1038 1039 1040 1041 |
argv[0] = DoTildeSubst(interp, argv[0]+1, &temp);
if (argv[0] == NULL) {
Tcl_DStringFree(&temp);
ckfree((char *)argv);
return NULL;
}
Tcl_DStringInit(bufferPtr);
| | | < > | 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 |
argv[0] = DoTildeSubst(interp, argv[0]+1, &temp);
if (argv[0] == NULL) {
Tcl_DStringFree(&temp);
ckfree((char *)argv);
return NULL;
}
Tcl_DStringInit(bufferPtr);
Tcl_JoinPath(argc, argv, bufferPtr);
Tcl_DStringFree(&temp);
ckfree((char*)argv);
} else {
Tcl_DStringInit(bufferPtr);
Tcl_JoinPath(1, &name, bufferPtr);
}
/*
* Convert forward slashes to backslashes in Windows paths because
* some system interfaces don't accept forward slashes.
*/
if (tclPlatform == TCL_PLATFORM_WINDOWS) {
register char *p;
for (p = Tcl_DStringValue(bufferPtr); *p != '\0'; p++) {
if (*p == '/') {
*p = '\\';
}
}
}
return Tcl_DStringValue(bufferPtr);
|
| ︙ | ︙ | |||
1210 1211 1212 1213 1214 1215 1216 |
int
Tcl_GlobObjCmd(dummy, interp, objc, objv)
ClientData dummy; /* Not used. */
Tcl_Interp *interp; /* Current interpreter. */
int objc; /* Number of arguments. */
Tcl_Obj *CONST objv[]; /* Argument objects. */
{
| | | > | | > | > | < | 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 |
int
Tcl_GlobObjCmd(dummy, interp, objc, objv)
ClientData dummy; /* Not used. */
Tcl_Interp *interp; /* Current interpreter. */
int objc; /* Number of arguments. */
Tcl_Obj *CONST objv[]; /* Argument objects. */
{
int index, i, globFlags, length, join, dir, result;
char *string, *separators;
Tcl_Obj *typePtr, *resultPtr, *look;
Tcl_Obj *pathOrDir = NULL;
Tcl_DString prefix;
static char *options[] = {
"-directory", "-join", "-nocomplain", "-path", "-tails",
"-types", "--", NULL
};
enum options {
GLOB_DIR, GLOB_JOIN, GLOB_NOCOMPLAIN, GLOB_PATH, GLOB_TAILS,
GLOB_TYPE, GLOB_LAST
};
enum pathDirOptions {PATH_NONE = -1 , PATH_GENERAL = 0, PATH_DIR = 1};
Tcl_GlobTypeData *globTypes = NULL;
globFlags = 0;
join = 0;
dir = PATH_NONE;
typePtr = NULL;
resultPtr = Tcl_GetObjResult(interp);
for (i = 1; i < objc; i++) {
if (Tcl_GetIndexFromObj(interp, objv[i], options, "option", 0, &index)
!= TCL_OK) {
string = Tcl_GetStringFromObj(objv[i], &length);
if (string[0] == '-') {
|
| ︙ | ︙ | |||
1250 1251 1252 1253 1254 1255 1256 |
*/
Tcl_ResetResult(interp);
break;
}
}
switch (index) {
case GLOB_NOCOMPLAIN: /* -nocomplain */
| | | | | > > > | | | 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 |
*/
Tcl_ResetResult(interp);
break;
}
}
switch (index) {
case GLOB_NOCOMPLAIN: /* -nocomplain */
globFlags |= TCL_GLOBMODE_NO_COMPLAIN;
break;
case GLOB_DIR: /* -dir */
if (i == (objc-1)) {
Tcl_AppendToObj(resultPtr,
"missing argument to \"-directory\"", -1);
return TCL_ERROR;
}
if (dir != PATH_NONE) {
Tcl_AppendToObj(resultPtr,
"\"-directory\" cannot be used with \"-path\"",
-1);
return TCL_ERROR;
}
dir = PATH_DIR;
globFlags |= TCL_GLOBMODE_DIR;
pathOrDir = objv[i+1];
i++;
break;
case GLOB_JOIN: /* -join */
join = 1;
break;
case GLOB_TAILS: /* -tails */
globFlags |= TCL_GLOBMODE_TAILS;
break;
case GLOB_PATH: /* -path */
if (i == (objc-1)) {
Tcl_AppendToObj(resultPtr,
"missing argument to \"-path\"", -1);
return TCL_ERROR;
}
if (dir != PATH_NONE) {
Tcl_AppendToObj(resultPtr,
"\"-path\" cannot be used with \"-directory\"",
-1);
return TCL_ERROR;
}
dir = PATH_GENERAL;
pathOrDir = objv[i+1];
i++;
break;
case GLOB_TYPE: /* -types */
if (i == (objc-1)) {
Tcl_AppendToObj(resultPtr,
"missing argument to \"-types\"", -1);
return TCL_ERROR;
|
| ︙ | ︙ | |||
1311 1312 1313 1314 1315 1316 1317 |
}
}
endOfForLoop:
if (objc - i < 1) {
Tcl_WrongNumArgs(interp, 1, objv, "?switches? name ?name ...?");
return TCL_ERROR;
}
| > > > > > | > > > | | | | < | | | < | | | | 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 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 |
}
}
endOfForLoop:
if (objc - i < 1) {
Tcl_WrongNumArgs(interp, 1, objv, "?switches? name ?name ...?");
return TCL_ERROR;
}
if ((globFlags & TCL_GLOBMODE_TAILS) && (pathOrDir == NULL)) {
Tcl_AppendToObj(resultPtr,
"\"-tails\" must be used with either \"-directory\" or \"-path\"",
-1);
return TCL_ERROR;
}
separators = NULL; /* lint. */
switch (tclPlatform) {
case TCL_PLATFORM_UNIX:
separators = "/";
break;
case TCL_PLATFORM_WINDOWS:
separators = "/\\:";
break;
case TCL_PLATFORM_MAC:
separators = ":";
break;
}
if (dir == PATH_GENERAL) {
int pathlength;
char *last;
char *first = Tcl_GetStringFromObj(pathOrDir,&pathlength);
/*
* Find the last path separator in the path
*/
last = first + pathlength;
for (; last != first; last--) {
if (strchr(separators, *(last-1)) != NULL) {
break;
}
}
if (last == first + pathlength) {
/* It's really a directory */
dir = PATH_DIR;
} else {
Tcl_DString pref;
char *search, *find;
Tcl_DStringInit(&pref);
if (last == first) {
/* The whole thing is a prefix */
Tcl_DStringAppend(&pref, first, -1);
pathOrDir = NULL;
} else {
/* Have to split off the end */
Tcl_DStringAppend(&pref, last, first+pathlength-last);
pathOrDir = Tcl_NewStringObj(first, last-first-1);
}
/* Need to quote 'prefix' */
Tcl_DStringInit(&prefix);
search = Tcl_DStringValue(&pref);
while ((find = (strpbrk(search, "\\[]*?{}"))) != NULL) {
Tcl_DStringAppend(&prefix, search, find-search);
Tcl_DStringAppend(&prefix, "\\", 1);
Tcl_DStringAppend(&prefix, find, 1);
search = find+1;
if (*search == '\0') {
break;
}
}
if (*search != '\0') {
Tcl_DStringAppend(&prefix, search, -1);
}
Tcl_DStringFree(&pref);
}
}
if (typePtr != NULL) {
/*
* The rest of the possible type arguments (except 'd') are
* platform specific. We don't complain when they are used
* on an incompatible platform.
*/
Tcl_ListObjLength(interp, typePtr, &length);
globTypes = (Tcl_GlobTypeData*) ckalloc(sizeof(Tcl_GlobTypeData));
globTypes->type = 0;
globTypes->perm = 0;
globTypes->macType = NULL;
globTypes->macCreator = NULL;
while(--length >= 0) {
int len;
char *str;
|
| ︙ | ︙ | |||
1472 1473 1474 1475 1476 1477 1478 | badTypesArg: Tcl_AppendToObj(resultPtr, "bad argument to \"-types\": ", -1); Tcl_AppendObjToObj(resultPtr, look); result = TCL_ERROR; goto endOfGlob; badMacTypesArg: Tcl_AppendToObj(resultPtr, | | > > > > > | 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 |
badTypesArg:
Tcl_AppendToObj(resultPtr, "bad argument to \"-types\": ", -1);
Tcl_AppendObjToObj(resultPtr, look);
result = TCL_ERROR;
goto endOfGlob;
badMacTypesArg:
Tcl_AppendToObj(resultPtr,
"only one MacOS type or creator argument"
" to \"-types\" allowed", -1);
result = TCL_ERROR;
goto endOfGlob;
}
}
}
if (pathOrDir != NULL) {
Tcl_IncrRefCount(pathOrDir);
}
/*
* Now we perform the actual glob below. This may involve joining
* together the pattern arguments, dealing with particular file types
* etc. We use a 'goto' to ensure we free any memory allocated along
* the way.
*/
objc -= i;
|
| ︙ | ︙ | |||
1539 1540 1541 1542 1543 1544 1545 |
globFlags, globTypes) != TCL_OK) {
result = TCL_ERROR;
goto endOfGlob;
}
}
}
}
| | | 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 |
globFlags, globTypes) != TCL_OK) {
result = TCL_ERROR;
goto endOfGlob;
}
}
}
}
if ((globFlags & TCL_GLOBMODE_NO_COMPLAIN) == 0) {
if (Tcl_ListObjLength(interp, Tcl_GetObjResult(interp),
&length) != TCL_OK) {
/* This should never happen. Maybe we should be more dramatic */
result = TCL_ERROR;
goto endOfGlob;
}
if (length == 0) {
|
| ︙ | ︙ | |||
1567 1568 1569 1570 1571 1572 1573 |
Tcl_AppendResult(interp, "\"", (char *) NULL);
result = TCL_ERROR;
}
}
endOfGlob:
if (join || (dir == PATH_GENERAL)) {
Tcl_DStringFree(&prefix);
| < < | > > | 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 |
Tcl_AppendResult(interp, "\"", (char *) NULL);
result = TCL_ERROR;
}
}
endOfGlob:
if (join || (dir == PATH_GENERAL)) {
Tcl_DStringFree(&prefix);
}
if (pathOrDir != NULL) {
Tcl_DecrRefCount(pathOrDir);
}
if (globTypes != NULL) {
if (globTypes->macType != NULL) {
Tcl_DecrRefCount(globTypes->macType);
}
if (globTypes->macCreator != NULL) {
Tcl_DecrRefCount(globTypes->macCreator);
|
| ︙ | ︙ | |||
1596 1597 1598 1599 1600 1601 1602 | * It sets the separator string based on the platform, performs * tilde substitution, and calls TclDoGlob. * * Results: * The return value is a standard Tcl result indicating whether * an error occurred in globbing. After a normal return the * result in interp (set by TclDoGlob) holds all of the file names | | | | | | | | | 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 |
* It sets the separator string based on the platform, performs
* tilde substitution, and calls TclDoGlob.
*
* Results:
* The return value is a standard Tcl result indicating whether
* an error occurred in globbing. After a normal return the
* result in interp (set by TclDoGlob) holds all of the file names
* given by the pattern and unquotedPrefix arguments. After an
* error the result in interp will hold an error message.
*
* Side effects:
* The 'pattern' is written to.
*
*----------------------------------------------------------------------
*/
/* ARGSUSED */
int
TclGlob(interp, pattern, unquotedPrefix, globFlags, types)
Tcl_Interp *interp; /* Interpreter for returning error message
* or appending list of matching file names. */
char *pattern; /* Glob pattern to match. Must not refer
* to a static string. */
Tcl_Obj *unquotedPrefix; /* Prefix to glob pattern, if non-null, which
* is considered literally. */
int globFlags; /* Stores or'ed combination of flags */
Tcl_GlobTypeData *types; /* Struct containing acceptable types.
* May be NULL. */
{
char *separators;
char *head, *tail, *start;
char c;
int result, prefixLen;
Tcl_DString buffer;
separators = NULL; /* lint. */
switch (tclPlatform) {
case TCL_PLATFORM_UNIX:
separators = "/";
break;
|
| ︙ | ︙ | |||
1643 1644 1645 1646 1647 1648 1649 |
separators = ":";
}
break;
}
Tcl_DStringInit(&buffer);
if (unquotedPrefix != NULL) {
| | | 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 |
separators = ":";
}
break;
}
Tcl_DStringInit(&buffer);
if (unquotedPrefix != NULL) {
start = Tcl_GetString(unquotedPrefix);
} else {
start = pattern;
}
/*
* Perform tilde substitution, if needed.
*/
|
| ︙ | ︙ | |||
1668 1669 1670 1671 1672 1673 1674 |
}
} else if (strchr(separators, *tail) != NULL) {
break;
}
}
/*
| | < < < < < < < < < < < < < < < < < < < < | | 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 |
}
} else if (strchr(separators, *tail) != NULL) {
break;
}
}
/*
* Determine the home directory for the specified user.
*/
c = *tail;
*tail = '\0';
head = DoTildeSubst(interp, start+1, &buffer);
*tail = c;
if (head == NULL) {
if (globFlags & TCL_GLOBMODE_NO_COMPLAIN) {
/*
* We should in fact pass down the nocomplain flag
* or save the interp result or use another mechanism
* so the interp result is not mangled on errors in that case.
* but that would a bigger change than reasonable for a patch
* release.
* (see fileName.test 15.2-15.4 for expected behaviour)
|
| ︙ | ︙ | |||
1721 1722 1723 1724 1725 1726 1727 |
if (unquotedPrefix != NULL) {
Tcl_DStringAppend(&buffer, tail, -1);
tail = pattern;
}
} else {
tail = pattern;
if (unquotedPrefix != NULL) {
| | > > > > | < > | | | | > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 |
if (unquotedPrefix != NULL) {
Tcl_DStringAppend(&buffer, tail, -1);
tail = pattern;
}
} else {
tail = pattern;
if (unquotedPrefix != NULL) {
Tcl_DStringAppend(&buffer,Tcl_GetString(unquotedPrefix),-1);
}
}
/*
* We want to remember the length of the current prefix,
* in case we are using TCL_GLOBMODE_TAILS. Also if we
* are using TCL_GLOBMODE_DIR, we must make sure the
* prefix ends in a directory separator.
*/
prefixLen = Tcl_DStringLength(&buffer);
if (prefixLen > 0) {
c = Tcl_DStringValue(&buffer)[prefixLen-1];
if (strchr(separators, c) == NULL) {
/*
* If the prefix is a directory, make sure it ends in a
* directory separator.
*/
if (globFlags & TCL_GLOBMODE_DIR) {
Tcl_DStringAppend(&buffer,separators,1);
}
prefixLen++;
}
}
result = TclDoGlob(interp, separators, &buffer, tail, types);
Tcl_DStringFree(&buffer);
if (result != TCL_OK) {
if (globFlags & TCL_GLOBMODE_NO_COMPLAIN) {
Tcl_ResetResult(interp);
return TCL_OK;
}
} else {
/*
* If we only want the tails, we must strip off the prefix now.
* It may seem more efficient to pass the tails flag down into
* TclDoGlob, Tcl_FSMatchInDirectory, but those functions are
* continually adjusting the prefix as the various pieces of
* the pattern are assimilated, so that would add a lot of
* complexity to the code. This way is a little slower (when
* the -tails flag is given), but much simpler to code.
*/
if (globFlags & TCL_GLOBMODE_TAILS) {
int objc, i;
Tcl_Obj **objv;
Tcl_Obj *tailResult;
Tcl_ListObjGetElements(NULL, Tcl_GetObjResult(interp),
&objc, &objv);
tailResult = Tcl_NewListObj(0,NULL);
for (i = 0; i< objc; i++) {
int len;
char *oldStr = Tcl_GetStringFromObj(objv[i],&len);
Tcl_Obj* str;
if (len == prefixLen) {
if ((pattern[0] == '\0')
|| (strchr(separators, pattern[0]) == NULL)) {
str = Tcl_NewStringObj(".",1);
} else {
str = Tcl_NewStringObj("/",1);
}
} else {
str = Tcl_NewStringObj(oldStr + prefixLen,
len - prefixLen);
}
Tcl_ListObjAppendElement(interp, tailResult, str);
}
Tcl_SetObjResult(interp, tailResult);
}
}
return result;
}
/*
*----------------------------------------------------------------------
*
|
| ︙ | ︙ | |||
1837 1838 1839 1840 1841 1842 1843 |
* (e.g. unmatched brace). */
char *separators; /* String containing separator characters
* that should be used to identify globbing
* boundaries. */
Tcl_DString *headPtr; /* Completely expanded prefix. */
char *tail; /* The unexpanded remainder of the path.
* Must not be a pointer to a static string. */
| | | | 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 |
* (e.g. unmatched brace). */
char *separators; /* String containing separator characters
* that should be used to identify globbing
* boundaries. */
Tcl_DString *headPtr; /* Completely expanded prefix. */
char *tail; /* The unexpanded remainder of the path.
* Must not be a pointer to a static string. */
Tcl_GlobTypeData *types; /* List object containing list of acceptable
* types. May be NULL. */
{
int baseLength, quoted, count;
int result = TCL_OK;
char *name, *p, *openBrace, *closeBrace, *firstSpecialChar, savedChar;
char lastChar = 0;
int length = Tcl_DStringLength(headPtr);
|
| ︙ | ︙ | |||
1995 1996 1997 1998 1999 2000 2001 | p++; element = p; SkipToChar(&p, ","); Tcl_DStringSetLength(headPtr, length); Tcl_DStringSetLength(&newName, baseLength); Tcl_DStringAppend(&newName, element, p-element); Tcl_DStringAppend(&newName, closeBrace+1, -1); | | | | 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 |
p++;
element = p;
SkipToChar(&p, ",");
Tcl_DStringSetLength(headPtr, length);
Tcl_DStringSetLength(&newName, baseLength);
Tcl_DStringAppend(&newName, element, p-element);
Tcl_DStringAppend(&newName, closeBrace+1, -1);
result = TclDoGlob(interp, separators, headPtr,
Tcl_DStringValue(&newName), types);
if (result != TCL_OK) {
break;
}
}
*closeBrace = '}';
Tcl_DStringFree(&newName);
return result;
|
| ︙ | ︙ | |||
2021 2022 2023 2024 2025 2026 2027 |
if (*p != '\0') {
/*
* Note that we are modifying the string in place. This won't work
* if the string is a static.
*/
| | | | | > > > | | | | > > > > > > | > > > | > > | > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > | > > > | | 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 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 |
if (*p != '\0') {
/*
* Note that we are modifying the string in place. This won't work
* if the string is a static.
*/
savedChar = *p;
*p = '\0';
firstSpecialChar = strpbrk(tail, "*[]?\\");
*p = savedChar;
} else {
firstSpecialChar = strpbrk(tail, "*[]?\\");
}
if (firstSpecialChar != NULL) {
int ret;
Tcl_Obj *head = Tcl_NewStringObj(Tcl_DStringValue(headPtr),-1);
Tcl_IncrRefCount(head);
/*
* Look for matching files in the given directory. The
* implementation of this function is platform specific. For
* each file that matches, it will add the match onto the
* resultPtr given.
*/
if (*p == '\0') {
ret = Tcl_FSMatchInDirectory(interp, Tcl_GetObjResult(interp),
head, tail, types);
} else {
Tcl_Obj* resultPtr;
/*
* We do the recursion ourselves. This makes implementing
* Tcl_FSMatchInDirectory for each filesystem much easier.
*/
Tcl_GlobTypeData dirOnly = { TCL_GLOB_TYPE_DIR, 0, NULL, NULL };
char save = *p;
*p = '\0';
resultPtr = Tcl_NewListObj(0, NULL);
ret = Tcl_FSMatchInDirectory(interp, resultPtr,
head, tail, &dirOnly);
*p = save;
if (ret == TCL_OK) {
int resLength;
ret = Tcl_ListObjLength(interp, resultPtr, &resLength);
if (ret == TCL_OK) {
int i;
for (i =0; i< resLength; i++) {
Tcl_Obj *elt;
Tcl_DString ds;
Tcl_ListObjIndex(interp, resultPtr, i, &elt);
Tcl_DStringInit(&ds);
Tcl_DStringAppend(&ds, Tcl_GetString(elt), -1);
if(tclPlatform == TCL_PLATFORM_MAC) {
Tcl_DStringAppend(&ds, ":",1);
} else {
Tcl_DStringAppend(&ds, "/",1);
}
ret = TclDoGlob(interp, separators, &ds, p+1, types);
Tcl_DStringFree(&ds);
if (ret != TCL_OK) {
break;
}
}
}
}
Tcl_DecrRefCount(resultPtr);
}
Tcl_DecrRefCount(head);
return ret;
}
Tcl_DStringAppend(headPtr, tail, p-tail);
if (*p != '\0') {
return TclDoGlob(interp, separators, headPtr, p, types);
}
/*
* There are no more wildcards in the pattern and no more unprocessed
* characters in the tail, so now we can construct the path and verify
* the existence of the file.
*/
switch (tclPlatform) {
case TCL_PLATFORM_MAC: {
if (strchr(Tcl_DStringValue(headPtr), ':') == NULL) {
Tcl_DStringAppend(headPtr, ":", 1);
}
name = Tcl_DStringValue(headPtr);
if (Tcl_Access(name, F_OK) == 0) {
if ((name[1] != '\0') && (strchr(name+1, ':') == NULL)) {
Tcl_ListObjAppendElement(interp, Tcl_GetObjResult(interp),
Tcl_NewStringObj(name + 1,-1));
} else {
Tcl_ListObjAppendElement(interp, Tcl_GetObjResult(interp),
Tcl_NewStringObj(name,-1));
}
}
break;
}
case TCL_PLATFORM_WINDOWS: {
int exists;
/*
* We need to convert slashes to backslashes before checking
* for the existence of the file. Once we are done, we need
* to convert the slashes back.
*
* This backslash/forward slash conversion may no longer
* be necessary, since we have dropped Win3.1 support.
*/
if (Tcl_DStringLength(headPtr) == 0) {
if (((*name == '\\') && (name[1] == '/' || name[1] == '\\'))
|| (*name == '/')) {
Tcl_DStringAppend(headPtr, "\\", 1);
} else {
Tcl_DStringAppend(headPtr, ".", 1);
}
} else {
for (p = Tcl_DStringValue(headPtr); *p != '\0'; p++) {
if (*p == '/') {
*p = '\\';
}
}
}
name = Tcl_DStringValue(headPtr);
exists = (Tcl_Access(name, F_OK) == 0);
for (p = name; *p != '\0'; p++) {
if (*p == '\\') {
*p = '/';
}
}
if (exists) {
|
| ︙ | ︙ | |||
2114 2115 2116 2117 2118 2119 2120 |
if ((*name == '\\' && name[1] == '/') || (*name == '/')) {
Tcl_DStringAppend(headPtr, "/", 1);
} else {
Tcl_DStringAppend(headPtr, ".", 1);
}
}
name = Tcl_DStringValue(headPtr);
| | | 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 |
if ((*name == '\\' && name[1] == '/') || (*name == '/')) {
Tcl_DStringAppend(headPtr, "/", 1);
} else {
Tcl_DStringAppend(headPtr, ".", 1);
}
}
name = Tcl_DStringValue(headPtr);
if (Tcl_Access(name, F_OK) == 0) {
Tcl_ListObjAppendElement(interp, Tcl_GetObjResult(interp),
Tcl_NewStringObj(name,-1));
}
break;
}
}
return TCL_OK;
}
|
Changes to generic/tclGetDate.y.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* * tclGetDate.y -- * * Contains yacc grammar for parsing date and time strings. * The output of this file should be the file tclDate.c which * is used directly in the Tcl sources. * * Copyright (c) 1992-1995 Karl Lehenbauer and Mark Diekhans. * Copyright (c) 1995-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
/*
* tclGetDate.y --
*
* Contains yacc grammar for parsing date and time strings.
* The output of this file should be the file tclDate.c which
* is used directly in the Tcl sources.
*
* Copyright (c) 1992-1995 Karl Lehenbauer and Mark Diekhans.
* Copyright (c) 1995-1997 Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* RCS: @(#) $Id: tclGetDate.y,v 1.17 2001/07/31 19:12:06 vincentdarley Exp $
*/
%{
/*
* tclDate.c --
*
* This file is generated from a yacc grammar defined in
|
| ︙ | ︙ | |||
29 30 31 32 33 34 35 | * * SCCSID */ #include "tclInt.h" #include "tclPort.h" | | | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | * * SCCSID */ #include "tclInt.h" #include "tclPort.h" #if defined(MAC_TCL) && !defined(TCL_MAC_USE_MSL_EPOCH) # define EPOCH 1904 # define START_OF_TIME 1904 # define END_OF_TIME 2039 #else # define EPOCH 1970 # define START_OF_TIME 1902 # define END_OF_TIME 2037 |
| ︙ | ︙ |
Changes to generic/tclIO.c.
1 2 3 4 5 6 7 8 9 10 11 12 | /* * tclIO.c -- * * This file provides the generic portions (those that are the same on * all platforms and for all channel types) of Tcl's IO facilities. * * Copyright (c) 1998-2000 Ajuba Solutions * Copyright (c) 1995-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | /* * tclIO.c -- * * This file provides the generic portions (those that are the same on * all platforms and for all channel types) of Tcl's IO facilities. * * Copyright (c) 1998-2000 Ajuba Solutions * Copyright (c) 1995-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclIO.c,v 1.33 2001/07/31 19:12:06 vincentdarley Exp $ */ #include "tclInt.h" #include "tclPort.h" #include "tclIO.h" #include <assert.h> |
| ︙ | ︙ | |||
100 101 102 103 104 105 106 107 108 109 110 111 112 113 | static void CreateScriptRecord _ANSI_ARGS_(( Tcl_Interp *interp, Channel *chanPtr, int mask, Tcl_Obj *scriptPtr)); static void DeleteChannelTable _ANSI_ARGS_(( ClientData clientData, Tcl_Interp *interp)); static void DeleteScriptRecord _ANSI_ARGS_((Tcl_Interp *interp, Channel *chanPtr, int mask)); static void DiscardInputQueued _ANSI_ARGS_((ChannelState *statePtr, int discardSavedBuffers)); static void DiscardOutputQueued _ANSI_ARGS_(( ChannelState *chanPtr)); static int DoRead _ANSI_ARGS_((Channel *chanPtr, char *srcPtr, int slen)); static int DoWrite _ANSI_ARGS_((Channel *chanPtr, char *src, | > > | 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | static void CreateScriptRecord _ANSI_ARGS_(( Tcl_Interp *interp, Channel *chanPtr, int mask, Tcl_Obj *scriptPtr)); static void DeleteChannelTable _ANSI_ARGS_(( ClientData clientData, Tcl_Interp *interp)); static void DeleteScriptRecord _ANSI_ARGS_((Tcl_Interp *interp, Channel *chanPtr, int mask)); static int DetachChannel _ANSI_ARGS_((Tcl_Interp *interp, Tcl_Channel chan)); static void DiscardInputQueued _ANSI_ARGS_((ChannelState *statePtr, int discardSavedBuffers)); static void DiscardOutputQueued _ANSI_ARGS_(( ChannelState *chanPtr)); static int DoRead _ANSI_ARGS_((Channel *chanPtr, char *srcPtr, int slen)); static int DoWrite _ANSI_ARGS_((Channel *chanPtr, char *src, |
| ︙ | ︙ | |||
683 684 685 686 687 688 689 690 691 692 693 694 695 696 |
}
}
}
/*
*----------------------------------------------------------------------
*
* Tcl_RegisterChannel --
*
* Adds an already-open channel to the channel table of an interpreter.
* If the interpreter passed as argument is NULL, it only increments
* the channel refCount.
*
* Results:
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 |
}
}
}
/*
*----------------------------------------------------------------------
*
* Tcl_IsStandardChannel --
*
* Test if the given channel is a standard channel. No attempt
* is made to check if the channel or the standard channels
* are initialized or otherwise valid.
*
* Results:
* Returns 1 if true, 0 if false.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
int
Tcl_IsStandardChannel(chan)
Tcl_Channel chan; /* Channel to check. */
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
if ((chan == tsdPtr->stdinChannel)
|| (chan == tsdPtr->stdoutChannel)
|| (chan == tsdPtr->stderrChannel)) {
return 1;
} else {
return 0;
}
}
/*
*----------------------------------------------------------------------
*
* Tcl_RegisterChannel --
*
* Adds an already-open channel to the channel table of an interpreter.
* If the interpreter passed as argument is NULL, it only increments
* the channel refCount.
*
* Results:
|
| ︙ | ︙ | |||
743 744 745 746 747 748 749 | /* *---------------------------------------------------------------------- * * Tcl_UnregisterChannel -- * * Deletes the hash entry for a channel associated with an interpreter. * If the interpreter given as argument is NULL, it only decrements the | | > > > > > | > > > < < < < < < < < < < | < < < | | < < < | < < < < | < < < < < < < | < < < < < | 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 |
/*
*----------------------------------------------------------------------
*
* Tcl_UnregisterChannel --
*
* Deletes the hash entry for a channel associated with an interpreter.
* If the interpreter given as argument is NULL, it only decrements the
* reference count. (This all happens in the Tcl_DetachChannel helper
* function).
*
* Finally, if the reference count of the channel drops to zero,
* it is deleted.
*
* Results:
* A standard Tcl result.
*
* Side effects:
* Calls Tcl_DetachChannel which deletes the hash entry for a channel
* associated with an interpreter.
*
* May delete the channel, which can have a variety of consequences,
* especially if we are forced to close the channel.
*
*----------------------------------------------------------------------
*/
int
Tcl_UnregisterChannel(interp, chan)
Tcl_Interp *interp; /* Interpreter in which channel is defined. */
Tcl_Channel chan; /* Channel to delete. */
{
ChannelState *statePtr; /* State of the real channel. */
if (DetachChannel(interp, chan) != TCL_OK) {
return TCL_OK;
}
statePtr = ((Channel *) chan)->state->bottomChanPtr->state;
/*
* Perform special handling for standard channels being closed. If the
* refCount is now 1 it means that the last reference to the standard
* channel is being explicitly closed, so bump the refCount down
* artificially to 0. This will ensure that the channel is actually
* closed, below. Also set the static pointer to NULL for the channel.
*/
|
| ︙ | ︙ | |||
825 826 827 828 829 830 831 |
*/
if ((statePtr->curOutPtr != NULL) &&
(statePtr->curOutPtr->nextAdded >
statePtr->curOutPtr->nextRemoved)) {
statePtr->flags |= BUFFER_READY;
}
| | > > | > > | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 |
*/
if ((statePtr->curOutPtr != NULL) &&
(statePtr->curOutPtr->nextAdded >
statePtr->curOutPtr->nextRemoved)) {
statePtr->flags |= BUFFER_READY;
}
Tcl_Preserve((ClientData)statePtr);
if (!(statePtr->flags & BG_FLUSH_SCHEDULED)) {
/* We don't want to re-enter Tcl_Close */
if (!(statePtr->flags & CHANNEL_CLOSED)) {
if (Tcl_Close(interp, chan) != TCL_OK) {
statePtr->flags |= CHANNEL_CLOSED;
Tcl_Release((ClientData)statePtr);
return TCL_ERROR;
}
}
}
statePtr->flags |= CHANNEL_CLOSED;
Tcl_Release((ClientData)statePtr);
}
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
* Tcl_DetachChannel --
*
* Deletes the hash entry for a channel associated with an interpreter.
* If the interpreter given as argument is NULL, it only decrements the
* reference count. Even if the ref count drops to zero, the
* channel is NOT closed or cleaned up. This allows a channel to
* be detached from an interpreter and left in the same state it
* was in when it was originally returned by 'Tcl_OpenFileChannel',
* for example.
*
* This function cannot be used on the standard channels, and
* will return TCL_ERROR if that is attempted.
*
* This function should only be necessary for special purposes
* in which you need to generate a pristine channel from one
* that has already been used. All ordinary purposes will almost
* always want to use Tcl_UnregisterChannel instead.
*
* Results:
* A standard Tcl result. If the channel is not currently registered
* with the given interpreter, TCL_ERROR is returned, otherwise
* TCL_OK. However no error messages are left in the interp's result.
*
* Side effects:
* Deletes the hash entry for a channel associated with an
* interpreter.
*
*----------------------------------------------------------------------
*/
int
Tcl_DetachChannel(interp, chan)
Tcl_Interp *interp; /* Interpreter in which channel is defined. */
Tcl_Channel chan; /* Channel to delete. */
{
if (Tcl_IsStandardChannel(chan)) {
return TCL_ERROR;
}
return DetachChannel(interp, chan);
}
/*
*----------------------------------------------------------------------
*
* DetachChannel --
*
* Deletes the hash entry for a channel associated with an interpreter.
* If the interpreter given as argument is NULL, it only decrements the
* reference count. Even if the ref count drops to zero, the
* channel is NOT closed or cleaned up. This allows a channel to
* be detached from an interpreter and left in the same state it
* was in when it was originally returned by 'Tcl_OpenFileChannel',
* for example.
*
* Results:
* A standard Tcl result. If the channel is not currently registered
* with the given interpreter, TCL_ERROR is returned, otherwise
* TCL_OK. However no error messages are left in the interp's result.
*
* Side effects:
* Deletes the hash entry for a channel associated with an
* interpreter.
*
*----------------------------------------------------------------------
*/
int
DetachChannel(interp, chan)
Tcl_Interp *interp; /* Interpreter in which channel is defined. */
Tcl_Channel chan; /* Channel to delete. */
{
Tcl_HashTable *hTblPtr; /* Hash table of channels. */
Tcl_HashEntry *hPtr; /* Search variable. */
Channel *chanPtr; /* The real IO channel. */
ChannelState *statePtr; /* State of the real channel. */
/*
* Always (un)register bottom-most channel in the stack. This makes
* management of the channel list easier because no manipulation is
* necessary during (un)stack operation.
*/
chanPtr = ((Channel *) chan)->state->bottomChanPtr;
statePtr = chanPtr->state;
if (interp != (Tcl_Interp *) NULL) {
hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL);
if (hTblPtr == (Tcl_HashTable *) NULL) {
return TCL_ERROR;
}
hPtr = Tcl_FindHashEntry(hTblPtr, statePtr->channelName);
if (hPtr == (Tcl_HashEntry *) NULL) {
return TCL_ERROR;
}
if ((Channel *) Tcl_GetHashValue(hPtr) != chanPtr) {
return TCL_ERROR;
}
Tcl_DeleteHashEntry(hPtr);
/*
* Remove channel handlers that refer to this interpreter, so that they
* will not be present if the actual close is delayed and more events
* happen on the channel. This may occur if the channel is shared
* between several interpreters, or if the channel has async
* flushing active.
*/
CleanupChannelHandlers(interp, chanPtr);
}
statePtr->refCount--;
return TCL_OK;
}
/*
*---------------------------------------------------------------------------
*
* Tcl_GetChannel --
*
* Finds an existing Tcl_Channel structure by name in a given
|
| ︙ | ︙ |
Changes to generic/tclIOCmd.c.
1 2 3 4 5 6 7 8 9 10 | /* * tclIOCmd.c -- * * Contains the definitions of most of the Tcl commands relating to IO. * * Copyright (c) 1995-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | /* * tclIOCmd.c -- * * Contains the definitions of most of the Tcl commands relating to IO. * * Copyright (c) 1995-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclIOCmd.c,v 1.8 2001/07/31 19:12:06 vincentdarley Exp $ */ #include "tclInt.h" #include "tclPort.h" /* * Callback structure for accept callback in a TCP server. |
| ︙ | ︙ | |||
949 950 951 952 953 954 955 |
}
/*
* Open the file or create a process pipeline.
*/
if (!pipeline) {
| | | 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 |
}
/*
* Open the file or create a process pipeline.
*/
if (!pipeline) {
chan = Tcl_FSOpenFileChannel(interp, objv[1], modeString, prot);
} else {
#ifdef MAC_TCL
Tcl_AppendResult(interp,
"command pipelines not supported on Macintosh OS",
(char *)NULL);
return TCL_ERROR;
#else
|
| ︙ | ︙ |
Changes to generic/tclIOUtil.c.
1 2 3 | /* * tclIOUtil.c -- * | | > | > > > | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
/*
* tclIOUtil.c --
*
* This file contains the implementation of Tcl's generic
* filesystem code, which supports a pluggable filesystem
* architecture allowing both platform specific filesystems and
* 'virtual filesystems'. All filesystem access should go through
* the functions defined in this file. Most of this code was
* contributed by Vince Darley.
*
* Parts of this file are based on code contributed by Karl
* Lehenbauer, Mark Diekhans and Peter da Silva.
*
* Copyright (c) 1991-1994 The Regents of the University of California.
* Copyright (c) 1994-1997 Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* RCS: @(#) $Id: tclIOUtil.c,v 1.12 2001/07/31 19:12:06 vincentdarley Exp $
*/
#include "tclInt.h"
#include "tclPort.h"
/*
* Prototypes for procedures defined later in this file. The last
* of these could perhaps be exported in the future, if extensions
* require it.
*/
static void DupFsPathInternalRep _ANSI_ARGS_((Tcl_Obj *srcPtr,
Tcl_Obj *copyPtr));
static void FreeFsPathInternalRep _ANSI_ARGS_((Tcl_Obj *listPtr));
static int SetFsPathFromAny _ANSI_ARGS_((Tcl_Interp *interp,
Tcl_Obj *objPtr));
static Tcl_Obj* FSNormalizeAbsolutePath
_ANSI_ARGS_((Tcl_Interp* interp, char *path));
static int TclNormalizeToUniquePath
_ANSI_ARGS_((Tcl_Interp *interp, Tcl_Obj *pathPtr));
static int SetFsPathFromAbsoluteNormalized
_ANSI_ARGS_((Tcl_Interp *interp, Tcl_Obj *objPtr));
static int FindSplitPos _ANSI_ARGS_((char *path, char *separator));
static Tcl_Filesystem* Tcl_FSGetFileSystemForPath
_ANSI_ARGS_((Tcl_Obj* pathObjPtr));
/*
* Define the 'path' object type, which Tcl uses to represent
* file paths internally.
*/
Tcl_ObjType tclFsPathType = {
"path", /* name */
FreeFsPathInternalRep, /* freeIntRepProc */
DupFsPathInternalRep, /* dupIntRepProc */
NULL, /* updateStringProc */
SetFsPathFromAny /* setFromAnyProc */
};
/*
* These form part of the native filesystem support. They are needed
* here because we have a few native filesystem functions (which are
* the same for mac/win/unix) in this file. There is no need to place
* them in tclInt.h, because they are not (and should not be) used
* anywhere else.
*/
extern char * tclpFileAttrStrings[];
extern CONST TclFileAttrProcs tclpFileAttrProcs[];
/*
* The following functions are obsolete string based APIs, and should
* be removed in a future release.
*/
/* Obsolete */
int
TclStat(path, buf)
CONST char *path; /* Path of file to stat (in current CP). */
struct stat *buf; /* Filled with results of stat call. */
{
return Tcl_Stat(path,buf);
}
/* Obsolete */
int
TclAccess(path, mode)
CONST char *path; /* Path of file to access (in current CP). */
int mode; /* Permission setting. */
{
return Tcl_Access(path, mode);
}
/* Obsolete */
int
Tcl_Stat(path, buf)
CONST char *path; /* Path of file to stat (in current CP). */
struct stat *buf; /* Filled with results of stat call. */
{
int ret;
Tcl_Obj *pathPtr = Tcl_NewStringObj(path,-1);
Tcl_IncrRefCount(pathPtr);
ret = Tcl_FSStat(pathPtr,buf);
Tcl_DecrRefCount(pathPtr);
return ret;
}
/* Obsolete */
int
Tcl_Access(path, mode)
CONST char *path; /* Path of file to access (in current CP). */
int mode; /* Permission setting. */
{
int ret;
Tcl_Obj *pathPtr = Tcl_NewStringObj(path,-1);
Tcl_IncrRefCount(pathPtr);
ret = Tcl_FSAccess(pathPtr,mode);
Tcl_DecrRefCount(pathPtr);
return ret;
}
/* Obsolete */
Tcl_Channel
Tcl_OpenFileChannel(interp, path, modeString, permissions)
Tcl_Interp *interp; /* Interpreter for error reporting;
* can be NULL. */
char *path; /* Name of file to open. */
char *modeString; /* A list of POSIX open modes or
* a string such as "rw". */
int permissions; /* If the open involves creating a
* file, with what modes to create
* it? */
{
Tcl_Channel ret;
Tcl_Obj *pathPtr = Tcl_NewStringObj(path,-1);
Tcl_IncrRefCount(pathPtr);
ret = Tcl_FSOpenFileChannel(interp, pathPtr, modeString, permissions);
Tcl_DecrRefCount(pathPtr);
return ret;
}
/* Obsolete */
int
Tcl_Chdir(dirName)
CONST char *dirName;
{
int ret;
Tcl_Obj *pathPtr = Tcl_NewStringObj(dirName,-1);
Tcl_IncrRefCount(pathPtr);
ret = Tcl_FSChdir(pathPtr);
Tcl_DecrRefCount(pathPtr);
return ret;
}
/* Obsolete */
char *
Tcl_GetCwd(interp, cwdPtr)
Tcl_Interp *interp;
Tcl_DString *cwdPtr;
{
Tcl_Obj *cwd;
cwd = Tcl_FSGetCwd(interp);
if (cwd == NULL) {
return NULL;
} else {
Tcl_DStringInit(cwdPtr);
Tcl_DStringAppend(cwdPtr, Tcl_GetString(cwd), -1);
Tcl_DecrRefCount(cwd);
return Tcl_DStringValue(cwdPtr);
}
}
/* Obsolete */
int
Tcl_EvalFile(interp, fileName)
Tcl_Interp *interp; /* Interpreter in which to process file. */
char *fileName; /* Name of file to process. Tilde-substitution
* will be performed on this name. */
{
int ret;
Tcl_Obj *pathPtr = Tcl_NewStringObj(fileName,-1);
Tcl_IncrRefCount(pathPtr);
ret = Tcl_FSEvalFile(interp, pathPtr);
Tcl_DecrRefCount(pathPtr);
return ret;
}
/*
* The 3 hooks for Stat, Access and OpenFileChannel are obsolete. The
* complete, general hooked filesystem APIs should be used instead.
* This define decides whether to include the obsolete hooks and
* related code. If these are removed, we'll also want to remove them
* from stubs/tclInt. The only known users of these APIs are prowrap
* and mktclapp. New code/extensions should not use them, since they
* do not provide as full support as the full filesystem API.
*/
#define USE_OBSOLETE_FS_HOOKS
#ifdef USE_OBSOLETE_FS_HOOKS
/*
* The following typedef declarations allow for hooking into the chain
* of functions maintained for 'Tcl_Stat(...)', 'Tcl_Access(...)' &
* 'Tcl_OpenFileChannel(...)'. Basically for each hookable function
* a linked list is defined.
*/
|
| ︙ | ︙ | |||
41 42 43 44 45 46 47 |
* 'Tcl_OpenFileChannel()' call */
struct OpenFileChannelProc *nextPtr;
/* The next 'Tcl_OpenFileChannel()'
* function to call */
} OpenFileChannelProc;
/*
| | | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > | | > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > | > > > > > > > > | > > | > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 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 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 |
* 'Tcl_OpenFileChannel()' call */
struct OpenFileChannelProc *nextPtr;
/* The next 'Tcl_OpenFileChannel()'
* function to call */
} OpenFileChannelProc;
/*
* For each type of (obsolete) hookable function, a static node is
* declared to hold the function pointer for the "built-in" routine
* (e.g. 'TclpStat(...)') and the respective list is initialized as a
* pointer to that node.
*
* The "delete" functions (e.g. 'TclStatDeleteProc(...)') ensure that
* these statically declared list entry cannot be inadvertently removed.
*
* This method avoids the need to call any sort of "initialization"
* function.
*
* All three lists are protected by a global obsoleteFsHookMutex.
*/
static StatProc *statProcList = NULL;
static AccessProc *accessProcList = NULL;
static OpenFileChannelProc *openFileChannelProcList = NULL;
TCL_DECLARE_MUTEX(obsoleteFsHookMutex)
#endif /* USE_OBSOLETE_FS_HOOKS */
/*
* A filesystem record is used to keep track of each
* filesystem currently registered with the core,
* in a linked list.
*/
typedef struct FilesystemRecord {
ClientData clientData; /* Client specific data for the new
* filesystem (can be NULL) */
Tcl_Filesystem *fsPtr; /* Pointer to filesystem dispatch
* table. */
int refCount; /* How many Tcl_Obj's use this
* filesystem. */
struct FilesystemRecord *nextPtr;
/* The next filesystem registered
* to Tcl, or NULL if no more. */
} FilesystemRecord;
/*
* Declare the native filesystem support. These functions should
* be considered private to Tcl, and should really not be called
* directly by any code other than this file (i.e. neither by
* Tcl's core nor by extensions). Similarly, the old string-based
* Tclp... native filesystem functions should not be called.
*
* The correct API to use now is the Tcl_FS... set of functions,
* which ensure correct and complete virtual filesystem support.
*
* We cannot make all of these static, since some of them
* are implemented in the platform-specific directories.
*/
static Tcl_FSPathInFilesystemProc NativePathInFilesystem;
static Tcl_FSFilesystemPathTypeProc NativeFilesystemPathType;
static Tcl_FSFilesystemSeparatorProc NativeFilesystemSeparator;
static Tcl_FSFreeInternalRepProc NativeFreeInternalRep;
static Tcl_FSDupInternalRepProc NativeDupInternalRep;
static Tcl_FSCreateInternalRepProc NativeCreateNativeRep;
static Tcl_FSFileAttrStringsProc NativeFileAttrStrings;
static Tcl_FSFileAttrsGetProc NativeFileAttrsGet;
static Tcl_FSFileAttrsSetProc NativeFileAttrsSet;
static Tcl_FSLoadFileProc NativeLoadFile;
static Tcl_FSOpenFileChannelProc NativeOpenFileChannel;
static Tcl_FSUtimeProc NativeUtime;
/*
* The only reason these functions are not static is that they
* are either called by code in the native (win/unix/mac) directories
* or they are actually implemented in those directories. They
* should simply not be called by code outside Tcl's native
* filesystem core. i.e. they should be considered 'static' to
* Tcl's filesystem code (if we ever built the native filesystem
* support into a separate code library, this could actually be
* enforced).
*/
Tcl_FSInternalToNormalizedProc TclpNativeToNormalized;
Tcl_FSStatProc TclpObjStat;
Tcl_FSAccessProc TclpObjAccess;
Tcl_FSMatchInDirectoryProc TclpMatchInDirectory;
Tcl_FSGetCwdProc TclpObjGetCwd;
Tcl_FSChdirProc TclpObjChdir;
Tcl_FSLstatProc TclpObjLstat;
Tcl_FSCopyFileProc TclpObjCopyFile;
Tcl_FSDeleteFileProc TclpObjDeleteFile;
Tcl_FSRenameFileProc TclpObjRenameFile;
Tcl_FSCreateDirectoryProc TclpObjCreateDirectory;
Tcl_FSCopyDirectoryProc TclpObjCopyDirectory;
Tcl_FSRemoveDirectoryProc TclpObjRemoveDirectory;
Tcl_FSUnloadFileProc TclpUnloadFile;
Tcl_FSReadlinkProc TclpObjReadlink;
Tcl_FSListVolumesProc TclpListVolumes;
/* Define the native filesystem dispatch table */
static Tcl_Filesystem nativeFilesystem = {
"native",
sizeof(Tcl_Filesystem),
TCL_FILESYSTEM_VERSION_1,
&NativePathInFilesystem,
&NativeDupInternalRep,
&NativeFreeInternalRep,
&TclpNativeToNormalized,
&NativeCreateNativeRep,
&TclpObjNormalizePath,
&NativeFilesystemPathType,
&NativeFilesystemSeparator,
&TclpObjStat,
&TclpObjAccess,
&NativeOpenFileChannel,
&TclpMatchInDirectory,
&NativeUtime,
#ifndef S_IFLNK
NULL,
#else
&TclpObjReadlink,
#endif /* S_IFLNK */
&TclpListVolumes,
&NativeFileAttrStrings,
&NativeFileAttrsGet,
&NativeFileAttrsSet,
&TclpObjCreateDirectory,
&TclpObjRemoveDirectory,
&TclpObjDeleteFile,
&TclpObjLstat,
&TclpObjCopyFile,
&TclpObjRenameFile,
&TclpObjCopyDirectory,
&NativeLoadFile,
&TclpUnloadFile,
&TclpObjGetCwd,
&TclpObjChdir
};
/*
* Define the tail of the linked list. Note that for unconventional
* uses of Tcl without a native filesystem, we may in the future wish
* to modify the current approach of hard-coding the native filesystem
* in the lookup list 'filesystemList' below.
*/
static FilesystemRecord nativeFilesystemRecord = {
NULL,
&nativeFilesystem,
1,
NULL
};
/*
* The following few variables are protected by the
* filesystemMutex just below.
*/
/*
* This is incremented each time we modify the linked list of
* filesystems. Any time it changes, all cached filesystem
* representations are suspect and must be freed.
*/
int filesystemEpoch = 0;
/* Stores the linked list of filesystems.*/
static FilesystemRecord *filesystemList = &nativeFilesystemRecord;
/*
* The number of loops which are currently iterating over the linked
* list. If this is greater than zero, we can't modify the list.
*/
int filesystemIteratorsInProgress = 0;
/* Someone wants to modify the list of filesystems if this is set. */
int filesystemWantToModify = 0;
Tcl_Condition filesystemOkToModify = NULL;
TCL_DECLARE_MUTEX(filesystemMutex)
/*
* struct FsPath --
*
* Internal representation of a Tcl_Obj of "path" type. This
* can be used to represent relative or absolute paths, and has
* certain optimisations when used to represent paths which are
* already normalized and absolute.
*
* Note that 'normPathPtr' can be a circular reference to the
* container Tcl_Obj of this FsPath.
*/
typedef struct FsPath {
char *translatedPathPtr; /* Name without any ~user sequences.
* If this is NULL, then this is a
* pure normalized, absolute path
* object, in which the parent Tcl_Obj's
* string rep is already both translated
* and normalized. */
Tcl_Obj *normPathPtr; /* Normalized absolute path, without
* ., .. or ~user sequences. If the
* Tcl_Obj containing
* this FsPath is already normalized,
* this may be a circular reference back
* to the container. If that is NOT the
* case, we have a refCount on the object. */
Tcl_Obj *cwdPtr; /* If null, path is absolute, else
* this points to the cwd object used
* for this path. We have a refCount
* on the object. */
ClientData nativePathPtr; /* Native representation of this path,
* which is filesystem dependent. */
int filesystemEpoch; /* Used to ensure the path representation
* was generated during the correct
* filesystem epoch. The epoch changes
* when filesystem-mounts are changed. */
struct FilesystemRecord *fsRecPtr;
/* Pointer to the filesystem record
* entry to use for this path. */
} FsPath;
/*
* Used to implement Tcl_FSGetCwd in a file-system independent way.
* This is protected by the cwdMutex below.
*/
static Tcl_Obj* cwdPathPtr = NULL;
TCL_DECLARE_MUTEX(cwdMutex)
/*
* Declare fallback support function and
* information for Tcl_FSLoadFile
*/
static Tcl_FSUnloadFileProc FSUnloadTempFile;
/*
* One of these structures is used each time we successfully load a
* file from a file system by way of making a temporary copy of the
* file on the native filesystem. We need to store both the actual
* unloadProc/clientData combination which was used, and the original
* and modified filenames, so that we can correctly undo the entire
* operation when we want to unload the code.
*/
typedef struct FsDivertLoad {
ClientData clientData;
Tcl_FSUnloadFileProc *unloadProcPtr;
Tcl_Obj *divertedFile;
} FsDivertLoad;
/* Now move on to the basic filesystem implementation */
static int
FsCwdPointerEquals(objPtr)
Tcl_Obj* objPtr;
{
Tcl_MutexLock(&cwdMutex);
if (cwdPathPtr == objPtr) {
Tcl_MutexUnlock(&cwdMutex);
return 1;
} else {
Tcl_MutexUnlock(&cwdMutex);
return 0;
}
}
static FilesystemRecord*
FsGetIterator(void) {
Tcl_MutexLock(&filesystemMutex);
filesystemIteratorsInProgress++;
Tcl_MutexUnlock(&filesystemMutex);
/* Now we know the list of filesystems cannot be modified */
return filesystemList;
}
static void
FsReleaseIterator(void) {
Tcl_MutexLock(&filesystemMutex);
filesystemIteratorsInProgress--;
if (filesystemIteratorsInProgress == 0) {
/* Notify any waiting threads that things are ok now */
if (filesystemWantToModify > 0) {
Tcl_ConditionNotify(&filesystemOkToModify);
}
}
Tcl_MutexUnlock(&filesystemMutex);
}
/*
*----------------------------------------------------------------------
*
* Tcl_FSRegister --
*
* Insert the filesystem function table at the head of the list of
* functions which are used during calls to all file-system
* operations. The filesystem will be added even if it is
* already in the list. (You can use TclFilesystemData to
* check if it is in the list, provided the ClientData used was
* not NULL).
*
* Note that the filesystem handling is head-to-tail of the list.
* Each filesystem is asked in turn whether it can handle a
* particular request, _until_ one of them says 'yes'. At that
* point no further filesystems are asked.
*
* In particular this means if you want to add a diagnostic
* filesystem (which simply reports all fs activity), it must be
* at the head of the list: i.e. it must be the last registered.
*
* Results:
* Normally TCL_OK; TCL_ERROR if memory for a new node in the list
* could not be allocated.
*
* Side effects:
* Memory allocataed and modifies the link list for filesystems.
*
*----------------------------------------------------------------------
*/
int
Tcl_FSRegister(clientData, fsPtr)
ClientData clientData; /* Client specific data for this fs */
Tcl_Filesystem *fsPtr; /* The filesystem record for the new fs. */
{
FilesystemRecord *newFilesystemPtr;
if (fsPtr == NULL) {
return TCL_ERROR;
}
newFilesystemPtr = (FilesystemRecord *)
ckalloc(sizeof(FilesystemRecord));
newFilesystemPtr->clientData = clientData;
newFilesystemPtr->fsPtr = fsPtr;
/*
* Is this lock and wait strictly speaking necessary? Since any
* iterators out there will have grabbed a copy of the head of
* the list and be iterating away from that, if we add a new
* element to the head of the list, it can't possibly have any
* effect on any of their loops. In fact it could be better not
* to wait, since we are adjusting the filesystem epoch, any
* cached representations calculated by existing iterators are
* going to have to be thrown away anyway.
*
* However, since registering and unregistering filesystems is
* a very rare action, this is not a very important point.
*/
Tcl_MutexLock(&filesystemMutex);
filesystemWantToModify++;
Tcl_ConditionWait(&filesystemOkToModify, &filesystemMutex, NULL);
filesystemWantToModify--;
newFilesystemPtr->nextPtr = filesystemList;
filesystemList = newFilesystemPtr;
/*
* Increment the filesystem epoch counter, since existing paths
* might conceivably now belong to different filesystems.
*/
filesystemEpoch++;
Tcl_MutexUnlock(&filesystemMutex);
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
* Tcl_FSUnregister --
*
* Remove the passed filesystem from the list of filesystem
* function tables. It also ensures that the built-in
* (native) filesystem is not removable, although we may wish
* to change that decision in the future to allow a smaller
* Tcl core, in which the native filesystem is not used at
* all (we could, say, initialise Tcl completely over a network
* connection).
*
* Results:
* TCL_OK if the procedure pointer was successfully removed,
* TCL_ERROR otherwise.
*
* Side effects:
* Memory is deallocated and the respective list updated.
*
*----------------------------------------------------------------------
*/
int
Tcl_FSUnregister(fsPtr)
Tcl_Filesystem *fsPtr; /* The filesystem record to remove. */
{
int retVal = TCL_ERROR;
FilesystemRecord *tmpFsRecPtr;
FilesystemRecord *prevFsRecPtr = NULL;
Tcl_MutexLock(&filesystemMutex);
filesystemWantToModify++;
Tcl_ConditionWait(&filesystemOkToModify, &filesystemMutex, NULL);
filesystemWantToModify--;
tmpFsRecPtr = filesystemList;
/*
* Traverse the 'filesystemList' looking for the particular node
* whose 'fsPtr' member matches 'fsPtr' and remove that one from
* the list. Ensure that the "default" node cannot be removed.
*/
while ((retVal == TCL_ERROR) && (tmpFsRecPtr != &nativeFilesystemRecord)) {
if (tmpFsRecPtr->fsPtr == fsPtr) {
if (prevFsRecPtr == NULL) {
filesystemList = filesystemList->nextPtr;
} else {
prevFsRecPtr->nextPtr = tmpFsRecPtr->nextPtr;
}
/*
* Increment the filesystem epoch counter, since existing
* paths might conceivably now belong to different
* filesystems. This should also ensure that paths which
* have cached the filesystem which is about to be deleted
* do not reference that filesystem (which would of course
* lead to memory exceptions).
*/
filesystemEpoch++;
ckfree((char *)tmpFsRecPtr);
retVal = TCL_OK;
} else {
prevFsRecPtr = tmpFsRecPtr;
tmpFsRecPtr = tmpFsRecPtr->nextPtr;
}
}
Tcl_MutexUnlock(&filesystemMutex);
return (retVal);
}
/*
*----------------------------------------------------------------------
*
* Tcl_FSData --
*
* Retrieve the clientData field for the filesystem given,
* or NULL if that filesystem is not registered.
*
* Results:
* A clientData value, or NULL. Note that if the filesystem
* was registered with a NULL clientData field, this function
* will return that NULL value.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
ClientData
Tcl_FSData(fsPtr)
Tcl_Filesystem *fsPtr; /* The filesystem record to query. */
{
ClientData retVal = NULL;
FilesystemRecord *tmpFsRecPtr;
tmpFsRecPtr = FsGetIterator();
/*
* Traverse the 'filesystemList' looking for the particular node
* whose 'fsPtr' member matches 'fsPtr' and remove that one from
* the list. Ensure that the "default" node cannot be removed.
*/
while ((retVal == NULL) && (tmpFsRecPtr != NULL)) {
if (tmpFsRecPtr->fsPtr == fsPtr) {
retVal = tmpFsRecPtr->clientData;
}
tmpFsRecPtr = tmpFsRecPtr->nextPtr;
}
FsReleaseIterator();
return (retVal);
}
/*
*---------------------------------------------------------------------------
*
* FSNormalizeAbsolutePath --
*
* Description:
* Takes an absolute path specification and computes a 'normalized'
* path from it.
*
* A normalized path is one which has all '../', './' removed.
* Also it is one which is in the 'standard' format for the native
* platform. On MacOS, Unix, this means the path must be free of
* symbolic links/aliases, and on Windows it means we want the
* long form, with that long form's case-dependence (which gives
* us a unique, case-dependent path).
*
* The behaviour of this function if passed a non-absolute path
* is NOT defined.
*
* Results:
* The result is returned in a Tcl_Obj with a refCount of 1,
* which is therefore owned by the caller. It must be
* freed (with Tcl_DecrRefCount) by the caller when no longer needed.
*
* Side effects:
* None (beyond the memory allocation for the result).
*
* Special note:
* This code is based on code from Matt Newman and Jean-Claude
* Wippler, with additions from Vince Darley and is copyright
* those respective authors.
*
*---------------------------------------------------------------------------
*/
static Tcl_Obj*
FSNormalizeAbsolutePath(interp, path)
Tcl_Interp* interp; /* Interpreter to use */
char *path; /* Absolute path to normalize (UTF-8) */
{
char **sp = NULL, *np[BUFSIZ];
int splen = 0, nplen, i;
Tcl_Obj *retVal;
Tcl_SplitPath(path, &splen, &sp);
nplen = 0;
for (i = 0;i < splen;i++) {
if (strcmp(sp[i], ".") == 0)
continue;
if (strcmp(sp[i], "..") == 0) {
if (nplen > 1) nplen--;
} else {
np[nplen++] = sp[i];
}
}
if (nplen > 0) {
Tcl_DString dtemp;
Tcl_DStringInit(&dtemp);
Tcl_JoinPath(nplen, np, &dtemp);
/*
* Now we have an absolute path, with no '..', '.' sequences,
* but it still may not be in 'unique' form, depending on the
* platform. For instance, Unix is case-sensitive, so the
* path is ok. Windows is case-insensitive, and also has the
* weird 'longname/shortname' thing (e.g. C:/Program Files/ and
* C:/Progra~1/ are equivalent). MacOS is case-insensitive.
*
* Virtual file systems which may be registered may have
* other criteria for normalizing a path.
*/
retVal = Tcl_NewStringObj(Tcl_DStringValue(&dtemp),-1);
Tcl_DStringFree(&dtemp);
Tcl_IncrRefCount(retVal);
TclNormalizeToUniquePath(interp, retVal);
/*
* Since we know it is a normalized path, we can
* actually convert this object into an FsPath for
* greater efficiency
*/
SetFsPathFromAbsoluteNormalized(interp, retVal);
} else {
/* Init to an empty string */
retVal = Tcl_NewStringObj("",0);
Tcl_IncrRefCount(retVal);
}
ckfree((char*) sp);
/* This has a refCount of 1 for the caller */
return retVal;
}
/*
*---------------------------------------------------------------------------
*
* TclNormalizeToUniquePath --
*
* Description:
* Takes a path specification containing no ../, ./ sequences,
* and converts it into a unique path for the given platform.
* On MacOS, Unix, this means the path must be free of
* symbolic links/aliases, and on Windows it means we want the
* long form, with that long form's case-dependence (which gives
* us a unique, case-dependent path).
*
* Results:
* The result is returned in a Tcl_Obj with a refCount of 1,
* which is therefore owned by the caller. It must be
* freed (with Tcl_DecrRefCount) by the caller when no longer needed.
*
* Side effects:
* None (beyond the memory allocation for the result).
*
* Special note:
* This is only used by the above function. Also if the
* filesystem-specific normalizePathProcs can re-introduce
* ../, ./ sequences into the path, then this function will
* not return the correct result. This may be possible with
* symbolic links on unix/macos.
*
*---------------------------------------------------------------------------
*/
static int
TclNormalizeToUniquePath(interp, pathPtr)
Tcl_Interp *interp;
Tcl_Obj *pathPtr;
{
FilesystemRecord *fsRecPtr;
int retVal = 0;
/*
* Call each of the "normalise path" functions in succession. This is
* a special case, in which if we have a native filesystem handler,
* we call it first. This is because the root of Tcl's filesystem
* is always a native filesystem (i.e. '/' on unix is native).
*/
fsRecPtr = FsGetIterator();
while (fsRecPtr != NULL) {
if (fsRecPtr == &nativeFilesystemRecord) {
Tcl_FSNormalizePathProc *proc = fsRecPtr->fsPtr->normalizePathProc;
if (proc != NULL) {
retVal = (*proc)(interp, pathPtr, retVal);
}
break;
}
fsRecPtr = fsRecPtr->nextPtr;
}
FsReleaseIterator();
fsRecPtr = FsGetIterator();
while (fsRecPtr != NULL) {
/* Skip the native system next time through */
if (fsRecPtr != &nativeFilesystemRecord) {
Tcl_FSNormalizePathProc *proc = fsRecPtr->fsPtr->normalizePathProc;
if (proc != NULL) {
retVal = (*proc)(interp, pathPtr, retVal);
}
/*
* We could add an efficiency check like this:
*
* if (retVal == Tcl_DStringLength(pathPtr)) {break;}
*
* but there's not much benefit.
*/
}
fsRecPtr = fsRecPtr->nextPtr;
}
FsReleaseIterator();
return (retVal);
}
/*
*---------------------------------------------------------------------------
*
* TclGetOpenMode --
*
* Description:
|
| ︙ | ︙ | |||
251 252 253 254 255 256 257 |
}
return mode;
}
/*
*----------------------------------------------------------------------
*
| | | > > > | | | < | < | | | > | | > | > | | > > > > > > | > | < | 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 |
}
return mode;
}
/*
*----------------------------------------------------------------------
*
* Tcl_FSEvalFile --
*
* Read in a file and process the entire file as one gigantic
* Tcl command.
*
* Results:
* A standard Tcl result, which is either the result of executing
* the file or an error indicating why the file couldn't be read.
*
* Side effects:
* Depends on the commands in the file. During the evaluation
* of the contents of the file, iPtr->scriptFile is made to
* point to fileName (the old value is cached and replaced when
* this function returns).
*
*----------------------------------------------------------------------
*/
int
Tcl_FSEvalFile(interp, fileName)
Tcl_Interp *interp; /* Interpreter in which to process file. */
Tcl_Obj *fileName; /* Name of file to process. Tilde-substitution
* will be performed on this name. */
{
int result, length;
struct stat statBuf;
Tcl_Obj *oldScriptFile;
Interp *iPtr;
char *string;
Tcl_Channel chan;
Tcl_Obj *objPtr;
if (Tcl_FSGetTranslatedPath(interp, fileName) == NULL) {
return TCL_ERROR;
}
result = TCL_ERROR;
objPtr = Tcl_NewObj();
if (Tcl_FSStat(fileName, &statBuf) == -1) {
Tcl_SetErrno(errno);
Tcl_AppendResult(interp, "couldn't read file \"",
Tcl_GetString(fileName),
"\": ", Tcl_PosixError(interp), (char *) NULL);
goto end;
}
chan = Tcl_FSOpenFileChannel(interp, fileName, "r", 0644);
if (chan == (Tcl_Channel) NULL) {
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "couldn't read file \"",
Tcl_GetString(fileName),
"\": ", Tcl_PosixError(interp), (char *) NULL);
goto end;
}
/*
* The eofchar is \32 (^Z). This is the usual on Windows, but we
* effect this cross-platform to allow for scripted documents.
* [Bug: 2040]
*/
Tcl_SetChannelOption(interp, chan, "-eofchar", "\32");
if (Tcl_ReadChars(chan, objPtr, -1, 0) < 0) {
Tcl_Close(interp, chan);
Tcl_AppendResult(interp, "couldn't read file \"",
Tcl_GetString(fileName),
"\": ", Tcl_PosixError(interp), (char *) NULL);
goto end;
}
if (Tcl_Close(interp, chan) != TCL_OK) {
goto end;
}
iPtr = (Interp *) interp;
oldScriptFile = iPtr->scriptFile;
iPtr->scriptFile = fileName;
Tcl_IncrRefCount(iPtr->scriptFile);
string = Tcl_GetStringFromObj(objPtr, &length);
result = Tcl_EvalEx(interp, string, length, 0);
/*
* Now we have to be careful; the script may have changed the
* iPtr->scriptFile value, so we must reset it without
* assuming it still points to 'fileName'.
*/
if (iPtr->scriptFile != NULL) {
Tcl_DecrRefCount(iPtr->scriptFile);
}
iPtr->scriptFile = oldScriptFile;
if (result == TCL_RETURN) {
result = TclUpdateReturnInfo(iPtr);
} else if (result == TCL_ERROR) {
char msg[200 + TCL_INTEGER_SPACE];
/*
* Record information telling where the error occurred.
*/
sprintf(msg, "\n (file \"%.150s\" line %d)", Tcl_GetString(fileName),
interp->errorLine);
Tcl_AddErrorInfo(interp, msg);
}
end:
Tcl_DecrRefCount(objPtr);
return result;
}
/*
*----------------------------------------------------------------------
*
* Tcl_GetErrno --
|
| ︙ | ︙ | |||
431 432 433 434 435 436 437 |
Tcl_SetErrorCode(interp, "POSIX", id, msg, (char *) NULL);
return msg;
}
/*
*----------------------------------------------------------------------
*
| | > | | < | | > > > > > | | > > | > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | < | | > > > > > | | > > | > > > > > > > > > > | | | | < < | | > > > > > > > > | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 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 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 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 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 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 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 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 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 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 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 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 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 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 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 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 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 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 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 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 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 |
Tcl_SetErrorCode(interp, "POSIX", id, msg, (char *) NULL);
return msg;
}
/*
*----------------------------------------------------------------------
*
* Tcl_FSStat --
*
* This procedure replaces the library version of stat and lsat.
*
* The appropriate function for the filesystem to which pathPtr
* belongs will be called.
*
* Results:
* See stat documentation.
*
* Side effects:
* See stat documentation.
*
*----------------------------------------------------------------------
*/
int
Tcl_FSStat(pathPtr, buf)
Tcl_Obj *pathPtr; /* Path of file to stat (in current CP). */
struct stat *buf; /* Filled with results of stat call. */
{
#ifdef USE_OBSOLETE_FS_HOOKS
StatProc *statProcPtr;
int retVal = -1;
#endif /* USE_OBSOLETE_FS_HOOKS */
Tcl_Filesystem *fsPtr;
char *path = Tcl_FSGetTranslatedPath(NULL, pathPtr);
/*
* Call each of the "stat" function in succession. A non-return
* value of -1 indicates the particular function has succeeded.
*/
#ifdef USE_OBSOLETE_FS_HOOKS
Tcl_MutexLock(&obsoleteFsHookMutex);
statProcPtr = statProcList;
while ((retVal == -1) && (statProcPtr != NULL)) {
retVal = (*statProcPtr->proc)(path, buf);
statProcPtr = statProcPtr->nextPtr;
}
Tcl_MutexUnlock(&obsoleteFsHookMutex);
if (retVal != -1) {
return retVal;
}
#endif /* USE_OBSOLETE_FS_HOOKS */
fsPtr = Tcl_FSGetFileSystemForPath(pathPtr);
if (fsPtr != NULL) {
Tcl_FSStatProc *proc = fsPtr->statProc;
if (proc != NULL) {
return (*proc)(pathPtr, buf);
}
}
Tcl_SetErrno(ENOENT);
return -1;
}
/*
*----------------------------------------------------------------------
*
* Tcl_FSLstat --
*
* This procedure replaces the library version of lstat.
* The appropriate function for the filesystem to which pathPtr
* belongs will be called. If no 'lstat' function is listed,
* but a 'stat' function is, then Tcl will fall back on the
* stat function.
*
* Results:
* See lstat documentation.
*
* Side effects:
* See lstat documentation.
*
*----------------------------------------------------------------------
*/
int
Tcl_FSLstat(pathPtr, buf)
Tcl_Obj *pathPtr; /* Path of file to stat (in current CP). */
struct stat *buf; /* Filled with results of stat call. */
{
Tcl_Filesystem *fsPtr = Tcl_FSGetFileSystemForPath(pathPtr);
if (fsPtr != NULL) {
Tcl_FSLstatProc *proc = fsPtr->lstatProc;
if (proc != NULL) {
return (*proc)(pathPtr, buf);
} else {
Tcl_FSStatProc *sproc = fsPtr->statProc;
if (sproc != NULL) {
return (*sproc)(pathPtr, buf);
}
}
}
Tcl_SetErrno(ENOENT);
return -1;
}
/*
*----------------------------------------------------------------------
*
* Tcl_FSAccess --
*
* This procedure replaces the library version of access.
* The appropriate function for the filesystem to which pathPtr
* belongs will be called.
*
* Results:
* See access documentation.
*
* Side effects:
* See access documentation.
*
*----------------------------------------------------------------------
*/
int
Tcl_FSAccess(pathPtr, mode)
Tcl_Obj *pathPtr; /* Path of file to access (in current CP). */
int mode; /* Permission setting. */
{
#ifdef USE_OBSOLETE_FS_HOOKS
AccessProc *accessProcPtr;
int retVal = -1;
#endif /* USE_OBSOLETE_FS_HOOKS */
Tcl_Filesystem *fsPtr;
char *path = Tcl_FSGetTranslatedPath(NULL, pathPtr);
/*
* Call each of the "access" function in succession. A non-return
* value of -1 indicates the particular function has succeeded.
*/
#ifdef USE_OBSOLETE_FS_HOOKS
Tcl_MutexLock(&obsoleteFsHookMutex);
accessProcPtr = accessProcList;
while ((retVal == -1) && (accessProcPtr != NULL)) {
retVal = (*accessProcPtr->proc)(path, mode);
accessProcPtr = accessProcPtr->nextPtr;
}
Tcl_MutexUnlock(&obsoleteFsHookMutex);
if (retVal != -1) {
return retVal;
}
#endif /* USE_OBSOLETE_FS_HOOKS */
fsPtr = Tcl_FSGetFileSystemForPath(pathPtr);
if (fsPtr != NULL) {
Tcl_FSAccessProc *proc = fsPtr->accessProc;
if (proc != NULL) {
return (*proc)(pathPtr, mode);
}
}
Tcl_SetErrno(ENOENT);
return -1;
}
/*
*----------------------------------------------------------------------
*
* Tcl_FSOpenFileChannel --
*
* The appropriate function for the filesystem to which pathPtr
* belongs will be called.
*
* Results:
* The new channel or NULL, if the named file could not be opened.
*
* Side effects:
* May open the channel and may cause creation of a file on the
* file system.
*
*----------------------------------------------------------------------
*/
Tcl_Channel
Tcl_FSOpenFileChannel(interp, pathPtr, modeString, permissions)
Tcl_Interp *interp; /* Interpreter for error reporting;
* can be NULL. */
Tcl_Obj *pathPtr; /* Name of file to open. */
char *modeString; /* A list of POSIX open modes or
* a string such as "rw". */
int permissions; /* If the open involves creating a
* file, with what modes to create
* it? */
{
#ifdef USE_OBSOLETE_FS_HOOKS
OpenFileChannelProc *openFileChannelProcPtr;
Tcl_Channel retVal = NULL;
#endif /* USE_OBSOLETE_FS_HOOKS */
Tcl_Filesystem *fsPtr;
char *path = Tcl_FSGetTranslatedPath(interp, pathPtr);
if (path == NULL) {
return NULL;
}
/*
* Call each of the "Tcl_OpenFileChannel" function in succession.
* A non-NULL return value indicates the particular function has
* succeeded.
*/
#ifdef USE_OBSOLETE_FS_HOOKS
Tcl_MutexLock(&obsoleteFsHookMutex);
openFileChannelProcPtr = openFileChannelProcList;
while ((retVal == NULL) && (openFileChannelProcPtr != NULL)) {
retVal = (*openFileChannelProcPtr->proc)(interp, path,
modeString, permissions);
openFileChannelProcPtr = openFileChannelProcPtr->nextPtr;
}
Tcl_MutexUnlock(&obsoleteFsHookMutex);
if (retVal != NULL) {
return retVal;
}
#endif /* USE_OBSOLETE_FS_HOOKS */
fsPtr = Tcl_FSGetFileSystemForPath(pathPtr);
if (fsPtr != NULL) {
Tcl_FSOpenFileChannelProc *proc = fsPtr->openFileChannelProc;
if (proc != NULL) {
return (*proc)(interp, pathPtr, modeString, permissions);
}
}
return NULL;
}
/*
*----------------------------------------------------------------------
*
* Tcl_FSMatchInDirectory --
*
* This routine is used by the globbing code to search a directory
* for all files which match a given pattern. The appropriate
* function for the filesystem to which pathPtr belongs will be
* called. If pathPtr does not belong to any filesystem and if it
* is NULL or the empty string, then we assume the pattern is to
* be matched in the current working directory. To avoid each
* filesystem's Tcl_FSMatchInDirectoryProc having to deal with
* this issue, we create a pathPtr on the fly, and then remove it
* from the results returned. This makes filesystems easy to
* write, since they can assume the pathPtr passed to them
* is an ordinary path. In fact this means we could remove such
* special case handling from Tcl's native filesystems.
*
* Results:
*
* The return value is a standard Tcl result indicating whether an
* error occurred in globbing. Error messages are placed in
* interp, but good results are placed in the resultPtr given.
*
* Recursive searches, e.g.
*
* glob -dir $dir -join * pkgIndex.tcl
*
* which must recurse through each directory matching '*' are
* handled internally by Tcl, by passing specific flags in a
* modified 'types' parameter.
*
* Side effects:
* The interpreter may have an error message inserted into it.
*
*----------------------------------------------------------------------
*/
int
Tcl_FSMatchInDirectory(interp, result, pathPtr, pattern, types)
Tcl_Interp *interp; /* Interpreter to receive error messages. */
Tcl_Obj *result; /* List object to receive results. */
Tcl_Obj *pathPtr; /* Contains path to directory to search. */
char *pattern; /* Pattern to match against. */
Tcl_GlobTypeData *types; /* Object containing list of acceptable types.
* May be NULL. In particular the directory
* flag is very important. */
{
Tcl_Filesystem *fsPtr = Tcl_FSGetFileSystemForPath(pathPtr);
if (fsPtr != NULL) {
Tcl_FSMatchInDirectoryProc *proc = fsPtr->matchInDirectoryProc;
if (proc != NULL) {
return (*proc)(interp, result, pathPtr, pattern, types);
}
} else {
Tcl_Obj* cwd;
int ret;
if (pathPtr != NULL) {
int len;
Tcl_GetStringFromObj(pathPtr,&len);
if (len != 0) {
/*
* We have no idea how to match files in a directory
* which belongs to no known filesystem
*/
return -1;
}
}
/*
* We have a null string, this means we must use the 'cwd', and
* then manipulate the result. We must deal with this here,
* since if we don't, every single filesystem's implementation
* of Tcl_FSMatchInDirectory will have to deal with it for us.
*/
cwd = Tcl_FSGetCwd(NULL);
if (cwd == NULL) {
if (interp != NULL) {
Tcl_SetResult(interp, "glob couldn't determine"
"the current working directory", TCL_STATIC);
}
return TCL_ERROR;
}
fsPtr = Tcl_FSGetFileSystemForPath(cwd);
if (fsPtr != NULL) {
Tcl_FSMatchInDirectoryProc *proc = fsPtr->matchInDirectoryProc;
if (proc != NULL) {
int cwdLen;
Tcl_Obj *cwdDir;
Tcl_Obj* tmpResultPtr = Tcl_NewListObj(0, NULL);
/*
* We know the cwd is a normalised object which does
* not end in a directory delimiter.
*/
cwdDir = Tcl_DuplicateObj(cwd);
#ifdef MAC_TCL
Tcl_AppendToObj(cwdDir, ":", 1);
#else
Tcl_AppendToObj(cwdDir, "/", 1);
#endif
Tcl_GetStringFromObj(cwdDir, &cwdLen);
Tcl_IncrRefCount(cwdDir);
ret = (*proc)(interp, tmpResultPtr, cwdDir, pattern, types);
Tcl_DecrRefCount(cwdDir);
if (ret == TCL_OK) {
int resLength;
ret = Tcl_ListObjLength(interp, tmpResultPtr, &resLength);
if (ret == TCL_OK) {
int i;
for (i =0; i< resLength; i++) {
Tcl_Obj *elt, *cutElt;
char *eltStr;
int eltLen;
Tcl_ListObjIndex(interp, tmpResultPtr, i, &elt);
eltStr = Tcl_GetStringFromObj(elt,&eltLen);
cutElt = Tcl_NewStringObj(eltStr + cwdLen, eltLen - cwdLen);
Tcl_ListObjAppendElement(interp, result, cutElt);
}
}
}
Tcl_DecrRefCount(tmpResultPtr);
}
}
Tcl_DecrRefCount(cwd);
return ret;
}
return -1;
}
/*
*----------------------------------------------------------------------
*
* Tcl_FSGetCwd --
*
* This function replaces the library version of getcwd().
*
* Most VFS's will *not* implement a 'cwdProc'. Tcl now maintains
* its own record (in a Tcl_Obj) of the cwd, and an attempt
* is made to synchronise this with the cwd's containing filesystem,
* if that filesystem provides a cwdProc (e.g. the native filesystem).
*
* Note that if Tcl's cwd is not in the native filesystem, then of
* course Tcl's cwd and the native cwd are different: extensions
* should therefore ensure they only access the cwd through this
* function to avoid confusion.
*
* If a global cwdPathPtr already exists, it is returned, subject
* to a synchronisation attempt in that cwdPathPtr's fs.
* Otherwise, the chain of functions that have been "inserted"
* into the filesystem will be called in succession until either a
* value other than NULL is returned, or the entire list is
* visited.
*
* Results:
* The result is a pointer to a Tcl_Obj specifying the current
* directory, or NULL if the current directory could not be
* determined. If NULL is returned, an error message is left in the
* interp's result.
*
* The result already has its refCount incremented for the caller.
* When it is no longer needed, that refCount should be decremented.
* This is needed for thread-safety purposes, to allow multiple
* threads to access this and related functions, while ensuring the
* results are always valid.
*
* Of course it is probably a bad idea for multiple threads to
* be *setting* the cwd anyway, but we can at least try to
* help the case of multiple reads with occasional sets.
*
* Side effects:
* Various objects may be freed and allocated.
*
*----------------------------------------------------------------------
*/
Tcl_Obj*
Tcl_FSGetCwd(interp)
Tcl_Interp *interp;
{
Tcl_Obj *cwdToReturn;
if (FsCwdPointerEquals(NULL)) {
FilesystemRecord *fsRecPtr;
Tcl_Obj *retVal = NULL;
/*
* We've never been called before, try to find a cwd. Call
* each of the "Tcl_GetCwd" function in succession. A non-NULL
* return value indicates the particular function has
* succeeded.
*/
fsRecPtr = FsGetIterator();
while ((retVal == NULL) && (fsRecPtr != NULL)) {
Tcl_FSGetCwdProc *proc = fsRecPtr->fsPtr->getCwdProc;
if (proc != NULL) {
retVal = (*proc)(interp);
}
fsRecPtr = fsRecPtr->nextPtr;
}
FsReleaseIterator();
/*
* Now the 'cwd' may NOT be normalized, at least on some
* platforms. For the sake of efficiency, we want a completely
* normalized cwd at all times.
*
* Finally, if retVal is NULL, we do not have a cwd, which
* could be problematic.
*/
if (retVal != NULL) {
Tcl_Obj *norm = FSNormalizeAbsolutePath(interp,
Tcl_GetString(retVal));
if (norm != NULL) {
/*
* We found a cwd, which is now in our global storage.
* We must make a copy. Norm already has a refCount of
* 1.
*
* Threading issue: note that multiple threads at system
* startup could in principle call this procedure
* simultaneously. They will therefore each set the
* cwdPathPtr independently. That behaviour is a bit
* peculiar, but should be fine. Once we have a cwd,
* we'll always be in the 'else' branch below which
* is simpler.
*/
Tcl_MutexLock(&cwdMutex);
/* Just in case the pointer has been set by another
* thread between now and the test above */
if (cwdPathPtr != NULL) {
Tcl_DecrRefCount(cwdPathPtr);
}
cwdPathPtr = norm;
Tcl_MutexUnlock(&cwdMutex);
}
Tcl_DecrRefCount(retVal);
}
} else {
/*
* We already have a cwd cached, but we want to give the
* filesystem it is in a chance to check whether that cwd
* has changed, or is perhaps no longer accessible. This
* allows an error to be thrown if, say, the permissions on
* that directory have changed.
*/
Tcl_Filesystem *fsPtr = Tcl_FSGetFileSystemForPath(cwdPathPtr);
/*
* If the filesystem couldn't be found, or if no cwd function
* exists for this filesystem, then we simply assume the cached
* cwd is ok. If we do call a cwd, we must watch for errors
* (if the cwd returns NULL). This ensures that, say, on Unix
* if the permissions of the cwd change, 'pwd' does actually
* throw the correct error in Tcl. (This is tested for in the
* test suite on unix).
*/
if (fsPtr != NULL) {
Tcl_FSGetCwdProc *proc = fsPtr->getCwdProc;
if (proc != NULL) {
Tcl_Obj *retVal = (*proc)(interp);
if (retVal != NULL) {
Tcl_Obj *norm = FSNormalizeAbsolutePath(interp,
Tcl_GetString(retVal));
/*
* Check whether cwd has changed from the value
* previously stored in cwdPathPtr. Really 'norm'
* shouldn't be null, but we are careful.
*/
if (norm == NULL) {
/* Do nothing */
} else if (Tcl_FSEqualPaths(cwdPathPtr, norm)) {
/*
* If the paths were equal, we can be more
* efficient and retain the old path object
* which will probably already be shared. In
* this case we can simply free the normalized
* path we just calculated.
*/
Tcl_DecrRefCount(norm);
} else {
/* The cwd has in fact changed, so we must
* lock down the cwdMutex to modify. */
Tcl_MutexLock(&cwdMutex);
Tcl_DecrRefCount(cwdPathPtr);
cwdPathPtr = norm;
Tcl_MutexUnlock(&cwdMutex);
}
Tcl_DecrRefCount(retVal);
} else {
/* The 'cwd' function returned an error, so we
* reset the cwd after locking down the mutex. */
Tcl_MutexLock(&cwdMutex);
Tcl_DecrRefCount(cwdPathPtr);
cwdPathPtr = NULL;
Tcl_MutexUnlock(&cwdMutex);
}
}
}
}
/*
* The paths all eventually fall through to here. Note that
* we use a bunch of separate mutex locks throughout this
* code to help prevent deadlocks between threads. Really
* the only weirdness will arise if multiple threads are setting
* and reading the cwd, and that behaviour is always going to be
* a little suspect.
*/
Tcl_MutexLock(&cwdMutex);
cwdToReturn = cwdPathPtr;
if (cwdToReturn != NULL) {
Tcl_IncrRefCount(cwdToReturn);
}
Tcl_MutexUnlock(&cwdMutex);
return (cwdToReturn);
}
/*
*----------------------------------------------------------------------
*
* Tcl_FSUtime --
*
* This procedure replaces the library version of utime.
* The appropriate function for the filesystem to which pathPtr
* belongs will be called.
*
* Results:
* See utime documentation.
*
* Side effects:
* See utime documentation.
*
*----------------------------------------------------------------------
*/
int
Tcl_FSUtime (pathPtr, tval)
Tcl_Obj *pathPtr; /* File to change access/modification times */
struct utimbuf *tval; /* Structure containing access/modification
* times to use. Should not be modified. */
{
Tcl_Filesystem *fsPtr = Tcl_FSGetFileSystemForPath(pathPtr);
if (fsPtr != NULL) {
Tcl_FSUtimeProc *proc = fsPtr->utimeProc;
if (proc != NULL) {
return (*proc)(pathPtr, tval);
}
}
return -1;
}
/*
*----------------------------------------------------------------------
*
* NativeFileAttrStrings --
*
* This procedure implements the platform dependent 'file
* attributes' subcommand, for the native filesystem, for listing
* the set of possible attribute strings. This function is part
* of Tcl's native filesystem support, and is placed here because
* it is shared by Unix, MacOS and Windows code.
*
* Results:
* An array of strings
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
char**
NativeFileAttrStrings(pathPtr, objPtrRef)
Tcl_Obj *pathPtr;
Tcl_Obj** objPtrRef;
{
return tclpFileAttrStrings;
}
/*
*----------------------------------------------------------------------
*
* NativeFileAttrsGet --
*
* This procedure implements the platform dependent
* 'file attributes' subcommand, for the native
* filesystem, for 'get' operations. This function is part
* of Tcl's native filesystem support, and is placed here
* because it is shared by Unix, MacOS and Windows code.
*
* Results:
* Standard Tcl return code. The object placed in objPtrRef
* (if TCL_OK was returned) is likely to have a refCount of zero.
* Either way we must either store it somewhere (e.g. the Tcl
* result), or Incr/Decr its refCount to ensure it is properly
* freed.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
int
NativeFileAttrsGet(interp, index, fileName, objPtrRef)
Tcl_Interp *interp; /* The interpreter for error reporting. */
int index; /* index of the attribute command. */
Tcl_Obj *fileName; /* filename we are operating on. */
Tcl_Obj **objPtrRef; /* for output. */
{
return (*tclpFileAttrProcs[index].getProc)(interp, index,
Tcl_FSGetTranslatedPath(NULL, fileName),
objPtrRef);
}
/*
*----------------------------------------------------------------------
*
* NativeFileAttrsSet --
*
* This procedure implements the platform dependent
* 'file attributes' subcommand, for the native
* filesystem, for 'set' operations. This function is part
* of Tcl's native filesystem support, and is placed here
* because it is shared by Unix, MacOS and Windows code.
*
* Results:
* Standard Tcl return code.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
int
NativeFileAttrsSet(interp, index, fileName, objPtr)
Tcl_Interp *interp; /* The interpreter for error reporting. */
int index; /* index of the attribute command. */
Tcl_Obj *fileName; /* filename we are operating on. */
Tcl_Obj *objPtr; /* set to this value. */
{
return (*tclpFileAttrProcs[index].setProc)(interp, index,
Tcl_FSGetTranslatedPath(NULL, fileName),
objPtr);
}
/*
*----------------------------------------------------------------------
*
* Tcl_FSFileAttrStrings --
*
* This procedure implements part of the hookable 'file
* attributes' subcommand. The appropriate function for the
* filesystem to which pathPtr belongs will be called.
*
* Results:
* The called procedure may either return an array of strings,
* or may instead return NULL and place a Tcl list into the
* given objPtrRef. Tcl will take that list and first increment
* its refCount before using it. On completion of that use, Tcl
* will decrement its refCount. Hence if the list should be
* disposed of by Tcl when done, it should have a refCount of zero,
* and if the list should not be disposed of, the filesystem
* should ensure it retains a refCount on the object.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
char**
Tcl_FSFileAttrStrings(pathPtr, objPtrRef)
Tcl_Obj* pathPtr;
Tcl_Obj** objPtrRef;
{
Tcl_Filesystem *fsPtr = Tcl_FSGetFileSystemForPath(pathPtr);
if (fsPtr != NULL) {
Tcl_FSFileAttrStringsProc *proc = fsPtr->fileAttrStringsProc;
if (proc != NULL) {
return (*proc)(pathPtr, objPtrRef);
}
}
return NULL;
}
/*
*----------------------------------------------------------------------
*
* Tcl_FSFileAttrsGet --
*
* This procedure implements read access for the hookable 'file
* attributes' subcommand. The appropriate function for the
* filesystem to which pathPtr belongs will be called.
*
* Results:
* Standard Tcl return code. The object placed in objPtrRef
* (if TCL_OK was returned) is likely to have a refCount of zero.
* Either way we must either store it somewhere (e.g. the Tcl
* result), or Incr/Decr its refCount to ensure it is properly
* freed.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
int
Tcl_FSFileAttrsGet(interp, index, pathPtr, objPtrRef)
Tcl_Interp *interp; /* The interpreter for error reporting. */
int index; /* index of the attribute command. */
Tcl_Obj *pathPtr; /* filename we are operating on. */
Tcl_Obj **objPtrRef; /* for output. */
{
Tcl_Filesystem *fsPtr = Tcl_FSGetFileSystemForPath(pathPtr);
if (fsPtr != NULL) {
Tcl_FSFileAttrsGetProc *proc = fsPtr->fileAttrsGetProc;
if (proc != NULL) {
return (*proc)(interp, index, pathPtr, objPtrRef);
}
}
return -1;
}
/*
*----------------------------------------------------------------------
*
* Tcl_FSFileAttrsSet --
*
* This procedure implements write access for the hookable 'file
* attributes' subcommand. The appropriate function for the
* filesystem to which pathPtr belongs will be called.
*
* Results:
* Standard Tcl return code.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
int
Tcl_FSFileAttrsSet(interp, index, pathPtr, objPtr)
Tcl_Interp *interp; /* The interpreter for error reporting. */
int index; /* index of the attribute command. */
Tcl_Obj *pathPtr; /* filename we are operating on. */
Tcl_Obj *objPtr; /* Input value. */
{
Tcl_Filesystem *fsPtr = Tcl_FSGetFileSystemForPath(pathPtr);
if (fsPtr != NULL) {
Tcl_FSFileAttrsSetProc *proc = fsPtr->fileAttrsSetProc;
if (proc != NULL) {
return (*proc)(interp, index, pathPtr, objPtr);
}
}
return -1;
}
/*
*----------------------------------------------------------------------
*
* Tcl_FSChdir --
*
* This function replaces the library version of chdir().
*
* The path is normalized and then passed to the filesystem
* which claims it.
*
* Results:
* See chdir() documentation. If successful, we keep a
* record of the successful path in cwdPathPtr for subsequent
* calls to getcwd.
*
* Side effects:
* See chdir() documentation. The global cwdPathPtr may
* change value.
*
*----------------------------------------------------------------------
*/
int
Tcl_FSChdir(pathPtr)
Tcl_Obj *pathPtr;
{
Tcl_Filesystem *fsPtr;
int retVal = -1;
Tcl_Obj *normDirName;
normDirName = Tcl_FSGetNormalizedPath(NULL, pathPtr);
if (normDirName == NULL) {
return TCL_ERROR;
}
fsPtr = Tcl_FSGetFileSystemForPath(pathPtr);
if (fsPtr != NULL) {
Tcl_FSChdirProc *proc = fsPtr->chdirProc;
if (proc != NULL) {
retVal = (*proc)(pathPtr);
} else {
/* Fallback on stat-based implementation */
struct stat buf;
/* If the file can be stat'ed and is a directory and
* is readable, then we can chdir. */
if ((Tcl_FSStat(pathPtr, &buf) == 0)
&& (S_ISDIR(buf.st_mode))
&& (Tcl_FSAccess(pathPtr, R_OK) == 0)) {
/* We allow the chdir */
retVal = 0;
}
}
}
if (retVal != -1) {
/*
* The cwd changed, or an error was thrown. If an error was
* thrown, we can just continue (and that will report the error
* to the user). If there was no error we must assume that the
* cwd was actually changed to the normalized value we
* calculated above, and we must therefore cache that
* information.
*/
if (retVal == TCL_OK) {
/* Get a lock on the cwd while we modify it */
Tcl_MutexLock(&cwdMutex);
/* Free up the previous cwd we stored */
if (cwdPathPtr != NULL) {
Tcl_DecrRefCount(cwdPathPtr);
}
/* Now remember the current cwd */
cwdPathPtr = normDirName;
Tcl_IncrRefCount(cwdPathPtr);
Tcl_MutexUnlock(&cwdMutex);
}
}
return (retVal);
}
/*
*----------------------------------------------------------------------
*
* Tcl_FSLoadFile --
*
* Dynamically loads a binary code file into memory and returns
* the addresses of two procedures within that file, if they are
* defined. The appropriate function for the filesystem to which
* pathPtr belongs will be called.
*
* Results:
* A standard Tcl completion code. If an error occurs, an error
* message is left in the interp's result.
*
* Side effects:
* New code suddenly appears in memory. We remember which
* filesystem loaded the code, so that we can use that filesystem's
* unloadProc to unload the code when that occurs.
*
*----------------------------------------------------------------------
*/
int
Tcl_FSLoadFile(interp, pathPtr, sym1, sym2, proc1Ptr, proc2Ptr,
clientDataPtr, unloadProcPtr)
Tcl_Interp *interp; /* Used for error reporting. */
Tcl_Obj *pathPtr; /* Name of the file containing the desired
* code. */
char *sym1, *sym2; /* Names of two procedures to look up in
* the file's symbol table. */
Tcl_PackageInitProc **proc1Ptr, **proc2Ptr;
/* Where to return the addresses corresponding
* to sym1 and sym2. */
ClientData *clientDataPtr; /* Filled with token for dynamically loaded
* file which will be passed back to
* (*unloadProcPtr)() to unload the file. */
Tcl_FSUnloadFileProc **unloadProcPtr;
/* Filled with address of Tcl_FSUnloadFileProc
* function which should be used for
* this file. */
{
Tcl_Filesystem *fsPtr = Tcl_FSGetFileSystemForPath(pathPtr);
if (fsPtr != NULL) {
Tcl_FSLoadFileProc *proc = fsPtr->loadFileProc;
if (proc != NULL) {
int retVal = (*proc)(interp, pathPtr, sym1, sym2,
proc1Ptr, proc2Ptr, clientDataPtr);
if (retVal != -1) {
/*
* We handled it. Remember which unload file
* proc to use.
*/
(*unloadProcPtr) = fsPtr->unloadFileProc;
}
return retVal;
} else {
Tcl_Filesystem *copyFsPtr;
/* Get a temporary filename to use, first to
* copy the file into, and then to load. */
Tcl_Obj *copyToPtr = TclpTempFileName();
if (copyToPtr == NULL) {
return -1;
}
Tcl_IncrRefCount(copyToPtr);
copyFsPtr = Tcl_FSGetFileSystemForPath(copyToPtr);
if ((copyFsPtr == NULL) || (copyFsPtr == fsPtr)) {
/* We already know we can't use Tcl_FSLoadFile from
* this filesystem, and we must avoid a possible
* infinite loop. */
Tcl_DecrRefCount(copyToPtr);
return -1;
}
if (Tcl_FSCopyFile(pathPtr, copyToPtr) == 0) {
/*
* Do we need to set appropriate permissions
* on the file? This may be required on some
* systems. On Unix we could do loop over
* the file attributes, and set any that are
* called "-permissions" to 0777. Or directly:
*
* Tcl_Obj* perm = Tcl_NewStringObj("0777",-1);
* Tcl_IncrRefCount(perm);
* Tcl_FSFileAttrsSet(NULL, 2, copyToPtr, perm);
* Tcl_DecrRefCount(perm);
*
*/
ClientData newClientData = NULL;
Tcl_FSUnloadFileProc *newUnloadProcPtr = NULL;
FsDivertLoad *tvdlPtr;
int retVal;
retVal = Tcl_FSLoadFile(interp, copyToPtr, sym1, sym2, proc1Ptr,
proc2Ptr, &newClientData, &newUnloadProcPtr);
if (retVal == -1) {
/* The file didn't load successfully */
Tcl_FSDeleteFile(copyToPtr);
Tcl_DecrRefCount(copyToPtr);
return -1;
}
/*
* When we unload this file, we need to divert the
* unloading so we can unload and cleanup the
* temporary file correctly.
*/
tvdlPtr = (FsDivertLoad*) ckalloc(sizeof(FsDivertLoad));
/*
* Remember three pieces of information. This allows
* us to cleanup the diverted load completely, on
* platforms which allow proper unloading of code.
*/
tvdlPtr->clientData = newClientData;
tvdlPtr->unloadProcPtr = newUnloadProcPtr;
/* copyToPtr is already incremented for this reference */
tvdlPtr->divertedFile = copyToPtr;
copyToPtr = NULL;
(*clientDataPtr) = (ClientData) tvdlPtr;
(*unloadProcPtr) = &FSUnloadTempFile;
return retVal;
}
}
}
return -1;
}
/*
*---------------------------------------------------------------------------
*
* FSUnloadTempFile --
*
* This function is called when we loaded a library of code via
* an intermediate temporary file. This function ensures
* the library is correctly unloaded and the temporary file
* is correctly deleted.
*
* Results:
* None.
*
* Side effects:
* The effects of the 'unload' function called, and of course
* the temporary file will be deleted.
*
*---------------------------------------------------------------------------
*/
static void
FSUnloadTempFile(clientData)
ClientData clientData; /* ClientData returned by a previous call
* to Tcl_FSLoadFile(). The clientData is
* a token that represents the loaded
* file. */
{
FsDivertLoad *tvdlPtr = (FsDivertLoad*)clientData;
/*
* This test should never trigger, since we give
* the client data in the function above.
*/
if (tvdlPtr == NULL) { return; }
/* Call the real 'unloadfile' proc we actually used. */
if (tvdlPtr->unloadProcPtr != NULL) {
(*tvdlPtr->unloadProcPtr)(tvdlPtr->clientData);
}
/* Remove the temporary file we created. */
Tcl_FSDeleteFile(tvdlPtr->divertedFile);
/* And free up the allocations */
Tcl_DecrRefCount(tvdlPtr->divertedFile);
ckfree((char*)tvdlPtr);
}
/*
*---------------------------------------------------------------------------
*
* Tcl_FSReadlink --
*
* This function replaces the library version of readlink().
* The appropriate function for the filesystem to which pathPtr
* belongs will be called.
*
* Results:
* The result is a Tcl_Obj specifying the contents
* of the symbolic link given by 'path', or NULL if the symbolic
* link could not be read. The result is owned by the caller,
* which should call Tcl_DecrRefCount when the result is no longer
* needed.
*
* Side effects:
* See readlink() documentation.
*
*---------------------------------------------------------------------------
*/
Tcl_Obj *
Tcl_FSReadlink(pathPtr)
Tcl_Obj *pathPtr; /* Path of file to readlink (UTF-8). */
{
Tcl_Filesystem *fsPtr = Tcl_FSGetFileSystemForPath(pathPtr);
if (fsPtr != NULL) {
Tcl_FSReadlinkProc *proc = fsPtr->readlinkProc;
if (proc != NULL) {
return (*proc)(pathPtr);
}
}
/*
* If S_IFLNK isn't defined it means that the machine doesn't
* support symbolic links, so the file can't possibly be a
* symbolic link. Generate an EINVAL error, which is what
* happens on machines that do support symbolic links when
* you invoke readlink on a file that isn't a symbolic link.
*/
#ifndef S_IFLNK
errno = EINVAL;
#endif /* S_IFLNK */
return NULL;
}
/*
*---------------------------------------------------------------------------
*
* Tcl_FSListVolumes --
*
* Lists the currently mounted volumes.
* The chain of functions that have been "inserted" into the
* filesystem will be called in succession; each may add to
* the Tcl result, until all mounted file systems are listed.
*
* Results:
* A standard Tcl result. Will always be TCL_OK, since there is no way
* that this command can fail. Also, the interpreter's result is set to
* the list of volumes.
*
* Side effects:
* None
*
*---------------------------------------------------------------------------
*/
int
Tcl_FSListVolumes(interp)
Tcl_Interp *interp; /* Interpreter for returning volume list. */
{
FilesystemRecord *fsRecPtr;
/*
* Call each of the "listVolumes" function in succession.
* A non-NULL return value indicates the particular function has
* succeeded. We call all the functions registered, since we want
* a list of all drives from all filesystems.
*/
fsRecPtr = FsGetIterator();
while (fsRecPtr != NULL) {
Tcl_FSListVolumesProc *proc = fsRecPtr->fsPtr->listVolumesProc;
if (proc != NULL) {
/* Ignore return value */
(*proc)(interp);
}
fsRecPtr = fsRecPtr->nextPtr;
}
FsReleaseIterator();
return TCL_OK;
}
/*
*---------------------------------------------------------------------------
*
* Tcl_FSRenameFile --
*
* If the two paths given belong to the same filesystem, we call
* that filesystems rename function. Otherwise we simply
* return the posix error 'EXDEV', and -1.
*
* Results:
* Standard Tcl error code if a function was called.
*
* Side effects:
* A file may be renamed.
*
*---------------------------------------------------------------------------
*/
int
Tcl_FSRenameFile(srcPathPtr, destPathPtr)
Tcl_Obj* srcPathPtr; /* Pathname of file or dir to be renamed
* (UTF-8). */
Tcl_Obj *destPathPtr; /* New pathname of file or directory
* (UTF-8). */
{
int retVal = -1;
Tcl_Filesystem *fsPtr, *fsPtr2;
fsPtr = Tcl_FSGetFileSystemForPath(srcPathPtr);
fsPtr2 = Tcl_FSGetFileSystemForPath(destPathPtr);
if (fsPtr == fsPtr2 && fsPtr != NULL) {
Tcl_FSRenameFileProc *proc = fsPtr->renameFileProc;
if (proc != NULL) {
retVal = (*proc)(srcPathPtr, destPathPtr);
}
}
if (retVal == -1) {
Tcl_SetErrno(EXDEV);
}
return retVal;
}
/*
*---------------------------------------------------------------------------
*
* Tcl_FSCopyFile --
*
* If the two paths given belong to the same filesystem, we call
* that filesystem's copy function. Otherwise we simply
* return the posix error 'EXDEV', and -1.
*
* Results:
* Standard Tcl error code if a function was called.
*
* Side effects:
* A file may be copied.
*
*---------------------------------------------------------------------------
*/
int
Tcl_FSCopyFile(srcPathPtr, destPathPtr)
Tcl_Obj* srcPathPtr; /* Pathname of file to be copied (UTF-8). */
Tcl_Obj *destPathPtr; /* Pathname of file to copy to (UTF-8). */
{
int retVal = -1;
Tcl_Filesystem *fsPtr, *fsPtr2;
fsPtr = Tcl_FSGetFileSystemForPath(srcPathPtr);
fsPtr2 = Tcl_FSGetFileSystemForPath(destPathPtr);
if (fsPtr == fsPtr2 && fsPtr != NULL) {
Tcl_FSCopyFileProc *proc = fsPtr->copyFileProc;
if (proc != NULL) {
retVal = (*proc)(srcPathPtr, destPathPtr);
}
}
if (retVal == -1) {
Tcl_SetErrno(EXDEV);
}
return retVal;
}
/*
*---------------------------------------------------------------------------
*
* Tcl_FSDeleteFile --
*
* The appropriate function for the filesystem to which pathPtr
* belongs will be called.
*
* Results:
* Standard Tcl error code.
*
* Side effects:
* A file may be deleted.
*
*---------------------------------------------------------------------------
*/
int
Tcl_FSDeleteFile(pathPtr)
Tcl_Obj *pathPtr; /* Pathname of file to be removed (UTF-8). */
{
Tcl_Filesystem *fsPtr = Tcl_FSGetFileSystemForPath(pathPtr);
if (fsPtr != NULL) {
Tcl_FSDeleteFileProc *proc = fsPtr->deleteFileProc;
if (proc != NULL) {
return (*proc)(pathPtr);
}
}
return -1;
}
/*
*---------------------------------------------------------------------------
*
* Tcl_FSCreateDirectory --
*
* The appropriate function for the filesystem to which pathPtr
* belongs will be called.
*
* Results:
* Standard Tcl error code.
*
* Side effects:
* A directory may be created.
*
*---------------------------------------------------------------------------
*/
int
Tcl_FSCreateDirectory(pathPtr)
Tcl_Obj *pathPtr; /* Pathname of directory to create (UTF-8). */
{
Tcl_Filesystem *fsPtr = Tcl_FSGetFileSystemForPath(pathPtr);
if (fsPtr != NULL) {
Tcl_FSCreateDirectoryProc *proc = fsPtr->createDirectoryProc;
if (proc != NULL) {
return (*proc)(pathPtr);
}
}
return -1;
}
/*
*---------------------------------------------------------------------------
*
* Tcl_FSRenameFile --
*
* If the two paths given belong to the same filesystem, we call
* that filesystems copy-directory function. Otherwise we simply
* return the posix error 'EXDEV', and -1.
*
* Results:
* Standard Tcl error code if a function was called.
*
* Side effects:
* A directory may be copied.
*
*---------------------------------------------------------------------------
*/
int
Tcl_FSCopyDirectory(srcPathPtr, destPathPtr, errorPtr)
Tcl_Obj* srcPathPtr; /* Pathname of directory to be copied
* (UTF-8). */
Tcl_Obj *destPathPtr; /* Pathname of target directory (UTF-8). */
Tcl_Obj **errorPtr; /* If non-NULL, then will be set to a
* new object containing name of file
* causing error, with refCount 1. */
{
int retVal = -1;
Tcl_Filesystem *fsPtr, *fsPtr2;
fsPtr = Tcl_FSGetFileSystemForPath(srcPathPtr);
fsPtr2 = Tcl_FSGetFileSystemForPath(destPathPtr);
if (fsPtr == fsPtr2 && fsPtr != NULL) {
Tcl_FSCopyDirectoryProc *proc = fsPtr->copyDirectoryProc;
if (proc != NULL) {
retVal = (*proc)(srcPathPtr, destPathPtr, errorPtr);
}
}
if (retVal == -1) {
Tcl_SetErrno(EXDEV);
}
return retVal;
}
/*
*---------------------------------------------------------------------------
*
* Tcl_FSRemoveDirectory --
*
* The appropriate function for the filesystem to which pathPtr
* belongs will be called.
*
* Results:
* Standard Tcl error code.
*
* Side effects:
* A directory may be deleted.
*
*---------------------------------------------------------------------------
*/
int
Tcl_FSRemoveDirectory(pathPtr, recursive, errorPtr)
Tcl_Obj *pathPtr; /* Pathname of directory to be removed
* (UTF-8). */
int recursive; /* If non-zero, removes directories that
* are nonempty. Otherwise, will only remove
* empty directories. */
Tcl_Obj **errorPtr; /* If non-NULL, then will be set to a
* new object containing name of file
* causing error, with refCount 1. */
{
Tcl_Filesystem *fsPtr = Tcl_FSGetFileSystemForPath(pathPtr);
if (fsPtr != NULL) {
Tcl_FSRemoveDirectoryProc *proc = fsPtr->removeDirectoryProc;
if (proc != NULL) {
return (*proc)(pathPtr, recursive, errorPtr);
}
}
return -1;
}
/*
*---------------------------------------------------------------------------
*
* Tcl_FSConvertToPathType --
*
* This function tries to convert the given Tcl_Obj to a valid
* Tcl path type, taking account of the fact that the cwd may
* have changed even if this object is already supposedly of
* the correct type.
*
* The filename may begin with "~" (to indicate current user's
* home directory) or "~<user>" (to indicate any user's home
* directory).
*
* Results:
* Standard Tcl error code.
*
* Side effects:
* The old representation may be freed, and new memory allocated.
*
*---------------------------------------------------------------------------
*/
int
Tcl_FSConvertToPathType(interp, objPtr)
Tcl_Interp *interp; /* Interpreter in which to store error
* message (if necessary). */
Tcl_Obj *objPtr; /* Object to convert to a valid, current
* path type. */
{
/*
* While it is bad practice to examine an object's type directly,
* this is actually the best thing to do here. The reason is that
* if we are converting this object to FsPath type for the first
* time, we don't need to worry whether the 'cwd' has changed.
* On the other hand, if this object is already of FsPath type,
* and is a relative path, we do have to worry about the cwd.
* If the cwd has changed, we must recompute the path.
*/
if (objPtr->typePtr == &tclFsPathType) {
FsPath *fsPathPtr = (FsPath*) objPtr->internalRep.otherValuePtr;
if (fsPathPtr->cwdPtr == NULL) {
return TCL_OK;
} else {
if (FsCwdPointerEquals(fsPathPtr->cwdPtr)) {
return TCL_OK;
} else {
FreeFsPathInternalRep(objPtr);
objPtr->typePtr = NULL;
return Tcl_ConvertToType(interp, objPtr, &tclFsPathType);
}
}
} else {
return Tcl_ConvertToType(interp, objPtr, &tclFsPathType);
}
}
/*
* Helper function for SetFsPathFromAny. Returns position of first
* directory delimiter in the path.
*/
static int
FindSplitPos(path, separator)
char *path;
char *separator;
{
int count = 0;
switch (tclPlatform) {
case TCL_PLATFORM_UNIX:
case TCL_PLATFORM_MAC:
while (path[count] != 0) {
if (path[count] == *separator) {
return count;
}
count++;
}
break;
case TCL_PLATFORM_WINDOWS:
while (path[count] != 0) {
if (path[count] == *separator || path[count] == '\\') {
return count;
}
count++;
}
break;
}
return count;
}
/*
*---------------------------------------------------------------------------
*
* SetFsPathFromAbsoluteNormalized --
*
* Like SetFsPathFromAny, but assumes the given object is an
* absolute normalized path. Only for internal use.
*
* Results:
* Standard Tcl error code.
*
* Side effects:
* The old representation may be freed, and new memory allocated.
*
*---------------------------------------------------------------------------
*/
static int
SetFsPathFromAbsoluteNormalized(interp, objPtr)
Tcl_Interp *interp; /* Used for error reporting if not NULL. */
Tcl_Obj *objPtr; /* The object to convert. */
{
FsPath *fsPathPtr;
if (objPtr->typePtr == &tclFsPathType) {
return TCL_OK;
}
/* Free old representation */
if (objPtr->typePtr != NULL) {
if (objPtr->bytes == NULL) {
objPtr->typePtr->updateStringProc(objPtr);
}
if ((objPtr->typePtr->freeIntRepProc) != NULL) {
(*objPtr->typePtr->freeIntRepProc)(objPtr);
}
}
fsPathPtr = (FsPath*)ckalloc((unsigned)sizeof(FsPath));
/* It's a pure normalized absolute path */
fsPathPtr->translatedPathPtr = NULL;
fsPathPtr->normPathPtr = objPtr;
fsPathPtr->cwdPtr = NULL;
fsPathPtr->nativePathPtr = NULL;
fsPathPtr->fsRecPtr = NULL;
fsPathPtr->filesystemEpoch = -1;
objPtr->internalRep.otherValuePtr = fsPathPtr;
objPtr->typePtr = &tclFsPathType;
return TCL_OK;
}
/*
*---------------------------------------------------------------------------
*
* SetFsPathFromAny --
*
* This function tries to convert the given Tcl_Obj to a valid
* Tcl path type.
*
* The filename may begin with "~" (to indicate current user's
* home directory) or "~<user>" (to indicate any user's home
* directory).
*
* Results:
* Standard Tcl error code.
*
* Side effects:
* The old representation may be freed, and new memory allocated.
*
*---------------------------------------------------------------------------
*/
static int
SetFsPathFromAny(interp, objPtr)
Tcl_Interp *interp; /* Used for error reporting if not NULL. */
Tcl_Obj *objPtr; /* The object to convert. */
{
int len;
FsPath *fsPathPtr;
Tcl_DString buffer;
char *name;
if (objPtr->typePtr == &tclFsPathType) {
return TCL_OK;
}
/* Free old representation */
if (objPtr->typePtr != NULL) {
if (objPtr->bytes == NULL) {
objPtr->typePtr->updateStringProc(objPtr);
}
if ((objPtr->typePtr->freeIntRepProc) != NULL) {
(*objPtr->typePtr->freeIntRepProc)(objPtr);
}
}
/*
* First step is to translate the filename. This is similar to
* Tcl_TranslateFilename, but shouldn't convert everything to
* windows backslashes on that platform. The current
* implementation of this piece is a slightly optimised version
* of the various Tilde/Split/Join stuff to avoid multiple
* split/join operations.
*
* We remove any trailing directory separator.
*
* However, the split/join routines are quite complex, and
* one has to make sure not to break anything on Unix, Win
* or MacOS (fCmd.test, fileName.test and cmdAH.test exercise
* most of the code).
*/
name = Tcl_GetStringFromObj(objPtr,&len);
/*
* Handle tilde substitutions, if needed.
*/
if (name[0] == '~') {
char *expandedUser;
Tcl_DString temp;
int split;
char separator='/';
if (tclPlatform==TCL_PLATFORM_MAC) {
if (strchr(name, ':') != NULL) separator = ':';
}
split = FindSplitPos(name, &separator);
if (split != len) {
/* We have multiple pieces '~user/foo/bar...' */
name[split] = '\0';
}
/* Do some tilde substitution */
if (name[1] == '\0') {
/* We have just '~' */
char *dir;
Tcl_DString dirString;
if (split != len) { name[split] = separator; }
dir = TclGetEnv("HOME", &dirString);
if (dir == NULL) {
if (interp) {
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "couldn't find HOME environment ",
"variable to expand path", (char *) NULL);
}
return TCL_ERROR;
}
Tcl_DStringInit(&temp);
Tcl_JoinPath(1, &dir, &temp);
Tcl_DStringFree(&dirString);
} else {
/* We have a user name '~user' */
Tcl_DStringInit(&temp);
if (TclpGetUserHome(name+1, &temp) == NULL) {
if (interp) {
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "user \"", (name+1),
"\" doesn't exist", (char *) NULL);
}
Tcl_DStringFree(&temp);
if (split != len) { name[split] = separator; }
return TCL_ERROR;
}
if (split != len) { name[split] = separator; }
}
expandedUser = Tcl_DStringValue(&temp);
Tcl_DStringInit(&buffer);
if (split == len) {
/* We have the result we need in the wrong DString */
Tcl_DStringAppend(&buffer, expandedUser, Tcl_DStringLength(&temp));
} else {
/*
* Build a simple 2 element list and join it up with
* the tilde substitution in place
*/
char *argv[2];
argv[0] = expandedUser;
argv[1] = name+split+1;
Tcl_JoinPath(2, argv, &buffer);
}
Tcl_DStringFree(&temp);
} else {
Tcl_DStringInit(&buffer);
Tcl_JoinPath(1, &name, &buffer);
}
len = Tcl_DStringLength(&buffer);
/*
* Now we have a translated filename in 'buffer', of
* length 'len'. This will have forward slashes on
* Windows, and will not contain any ~user sequences.
*/
fsPathPtr = (FsPath*)ckalloc((unsigned)sizeof(FsPath));
fsPathPtr->translatedPathPtr = ckalloc((unsigned)(1+len));
strcpy(fsPathPtr->translatedPathPtr, Tcl_DStringValue(&buffer));
Tcl_DStringFree(&buffer);
fsPathPtr->normPathPtr = NULL;
fsPathPtr->cwdPtr = NULL;
fsPathPtr->nativePathPtr = NULL;
fsPathPtr->fsRecPtr = NULL;
fsPathPtr->filesystemEpoch = -1;
objPtr->internalRep.otherValuePtr = fsPathPtr;
objPtr->typePtr = &tclFsPathType;
return TCL_OK;
}
/*
*---------------------------------------------------------------------------
*
* Tcl_FSNewNativePath --
*
* This function performs the something like that reverse of the
* usual obj->path->nativerep conversions. If some code retrieves
* a path in native form (from, e.g. readlink or a native dialog),
* and that path is to be used at the Tcl level, then calling
* this function is an efficient way of creating the appropriate
* path object type.
*
* Results:
* NULL or a valid path object pointer, with refCount zero.
*
* Side effects:
* New memory may be allocated.
*
*---------------------------------------------------------------------------
*/
Tcl_Obj *
Tcl_FSNewNativePath(fromFilesystem, clientData)
Tcl_Obj* fromFilesystem;
ClientData clientData;
{
Tcl_Obj *objPtr;
FsPath *fsPathPtr, *fsFromPtr;
Tcl_FSInternalToNormalizedProc *proc;
if (Tcl_FSConvertToPathType(NULL, fromFilesystem) != TCL_OK) {
return NULL;
}
fsFromPtr = (FsPath*) fromFilesystem->internalRep.otherValuePtr;
proc = fsFromPtr->fsRecPtr->fsPtr->internalToNormalizedProc;
if (proc == NULL) {
return NULL;
}
objPtr = (*proc)(clientData);
if (objPtr == NULL) {
return NULL;
}
/*
* Free old representation; shouldn't normally be any,
* but best to be safe.
*/
if (objPtr->typePtr != NULL) {
if (objPtr->bytes == NULL) {
objPtr->typePtr->updateStringProc(objPtr);
}
if ((objPtr->typePtr->freeIntRepProc) != NULL) {
(*objPtr->typePtr->freeIntRepProc)(objPtr);
}
}
fsPathPtr = (FsPath*)ckalloc((unsigned)sizeof(FsPath));
fsPathPtr->translatedPathPtr = NULL;
/* Circular reference, by design */
fsPathPtr->normPathPtr = objPtr;
fsPathPtr->cwdPtr = NULL;
fsPathPtr->nativePathPtr = clientData;
fsPathPtr->fsRecPtr = fsFromPtr->fsRecPtr;
fsPathPtr->filesystemEpoch = fsFromPtr->filesystemEpoch;
objPtr->internalRep.otherValuePtr = fsPathPtr;
objPtr->typePtr = &tclFsPathType;
return objPtr;
}
static void
FreeFsPathInternalRep(pathObjPtr)
Tcl_Obj *pathObjPtr; /* Path object with internal rep to free. */
{
register FsPath* fsPathPtr =
(FsPath*) pathObjPtr->internalRep.otherValuePtr;
if (fsPathPtr->translatedPathPtr != NULL) {
ckfree((char *) fsPathPtr->translatedPathPtr);
}
if (fsPathPtr->normPathPtr != NULL) {
if (fsPathPtr->normPathPtr != pathObjPtr) {
Tcl_DecrRefCount(fsPathPtr->normPathPtr);
}
fsPathPtr->normPathPtr = NULL;
}
if (fsPathPtr->cwdPtr != NULL) {
Tcl_DecrRefCount(fsPathPtr->cwdPtr);
}
if (fsPathPtr->nativePathPtr != NULL) {
if (fsPathPtr->fsRecPtr != NULL) {
if (fsPathPtr->fsRecPtr->fsPtr->freeInternalRepProc != NULL) {
(*fsPathPtr->fsRecPtr->fsPtr
->freeInternalRepProc)(fsPathPtr->nativePathPtr);
fsPathPtr->nativePathPtr = NULL;
}
}
}
if (fsPathPtr->fsRecPtr != NULL) {
fsPathPtr->fsRecPtr->refCount--;
}
ckfree((char*) fsPathPtr);
}
static void
DupFsPathInternalRep(srcPtr, copyPtr)
Tcl_Obj *srcPtr; /* Path obj with internal rep to copy. */
Tcl_Obj *copyPtr; /* Path obj with internal rep to set. */
{
register FsPath* srcFsPathPtr =
(FsPath*) srcPtr->internalRep.otherValuePtr;
register FsPath* copyFsPathPtr =
(FsPath*) ckalloc((unsigned)sizeof(FsPath));
Tcl_FSDupInternalRepProc *dupProc;
copyPtr->internalRep.otherValuePtr = copyFsPathPtr;
if (srcFsPathPtr->translatedPathPtr != NULL) {
copyFsPathPtr->translatedPathPtr =
ckalloc(1+strlen(srcFsPathPtr->translatedPathPtr));
strcpy(copyFsPathPtr->translatedPathPtr,
srcFsPathPtr->translatedPathPtr);
} else {
copyFsPathPtr->translatedPathPtr = NULL;
}
if (srcFsPathPtr->normPathPtr != NULL) {
copyFsPathPtr->normPathPtr = srcFsPathPtr->normPathPtr;
if (copyFsPathPtr->normPathPtr != copyPtr) {
Tcl_IncrRefCount(copyFsPathPtr->normPathPtr);
}
} else {
copyFsPathPtr->normPathPtr = NULL;
}
if (srcFsPathPtr->cwdPtr != NULL) {
copyFsPathPtr->cwdPtr = srcFsPathPtr->cwdPtr;
Tcl_IncrRefCount(copyFsPathPtr->cwdPtr);
} else {
copyFsPathPtr->cwdPtr = NULL;
}
if (srcFsPathPtr->fsRecPtr != NULL
&& srcFsPathPtr->nativePathPtr != NULL) {
dupProc = srcFsPathPtr->fsRecPtr->fsPtr->dupInternalRepProc;
if (dupProc != NULL) {
copyFsPathPtr->nativePathPtr =
(*dupProc)(srcFsPathPtr->nativePathPtr);
} else {
copyFsPathPtr->nativePathPtr = NULL;
}
} else {
copyFsPathPtr->nativePathPtr = NULL;
}
copyFsPathPtr->fsRecPtr = srcFsPathPtr->fsRecPtr;
copyFsPathPtr->filesystemEpoch = srcFsPathPtr->filesystemEpoch;
if (copyFsPathPtr->fsRecPtr != NULL) {
copyFsPathPtr->fsRecPtr->refCount++;
}
copyPtr->typePtr = &tclFsPathType;
}
/*
*---------------------------------------------------------------------------
*
* Tcl_FSGetTranslatedPath --
*
* This function attempts to extract the translated path string
* from the given Tcl_Obj. If the translation succeeds (i.e. the
* object is a valid path), then it is returned. Otherwise NULL
* will be returned, and an error message may be left in the
* interpreter.
*
* Results:
* NULL or a valid string.
*
* Side effects:
* Only those of 'Tcl_FSConvertToPathType'
*
*---------------------------------------------------------------------------
*/
char*
Tcl_FSGetTranslatedPath(interp, pathPtr)
Tcl_Interp *interp;
Tcl_Obj* pathPtr;
{
register FsPath* srcFsPathPtr;
if (Tcl_FSConvertToPathType(interp, pathPtr) != TCL_OK) {
return NULL;
}
srcFsPathPtr = (FsPath*) pathPtr->internalRep.otherValuePtr;
if (srcFsPathPtr->translatedPathPtr == NULL) {
/*
* It is a pure absolute, normalized path object.
* This is something like being a 'pure list'. The
* object's string, translatedPath and normalizedPath
* are all identical.
*/
return Tcl_GetString(srcFsPathPtr->normPathPtr);
} else {
/* It is an ordinary path object */
return srcFsPathPtr->translatedPathPtr;
}
}
/*
*---------------------------------------------------------------------------
*
* Tcl_FSGetNormalizedPath --
*
* This important function attempts to extract from the given Tcl_Obj
* a unique normalised path representation, whose string value can
* be used as a unique identifier for the file.
*
* Results:
* NULL or a valid path object pointer.
*
* Side effects:
* New memory may be allocated. The Tcl 'errno' may be modified
* in the process of trying to examine various path possibilities.
*
*---------------------------------------------------------------------------
*/
Tcl_Obj*
Tcl_FSGetNormalizedPath(interp, pathObjPtr)
Tcl_Interp *interp;
Tcl_Obj* pathObjPtr;
{
register FsPath* srcFsPathPtr;
if (Tcl_FSConvertToPathType(interp, pathObjPtr) != TCL_OK) {
return NULL;
}
srcFsPathPtr = (FsPath*) pathObjPtr->internalRep.otherValuePtr;
if (srcFsPathPtr->normPathPtr == NULL) {
int relative = 0;
char *path = srcFsPathPtr->translatedPathPtr;
Tcl_DString atemp;
if ((path[0] != '\0') && (Tcl_GetPathType(path) == TCL_PATH_RELATIVE)) {
char * pair[2];
Tcl_Obj *cwd = Tcl_FSGetCwd(interp);
if (cwd == NULL) {
return NULL;
}
/*
* The efficiency of this piece of code could
* be improved, given the new object interfaces.
*/
pair[0] = Tcl_GetString(cwd);
pair[1] = path;
Tcl_DStringInit(&atemp);
Tcl_JoinPath(2, pair, &atemp);
path = Tcl_DStringValue(&atemp);
Tcl_DecrRefCount(cwd);
relative = 1;
}
/* Already has refCount incremented */
srcFsPathPtr->normPathPtr = FSNormalizeAbsolutePath(interp, path);
if (!strcmp(Tcl_GetString(srcFsPathPtr->normPathPtr),
Tcl_GetString(pathObjPtr))) {
/*
* The path was already normalized.
* Get rid of the duplicate.
*/
Tcl_DecrRefCount(srcFsPathPtr->normPathPtr);
/*
* We do *not* increment the refCount for
* this circular reference
*/
srcFsPathPtr->normPathPtr = pathObjPtr;
}
if (relative) {
Tcl_DStringFree(&atemp);
/* Get a quick, temporary lock on the cwd while we copy it */
Tcl_MutexLock(&cwdMutex);
srcFsPathPtr->cwdPtr = cwdPathPtr;
Tcl_IncrRefCount(srcFsPathPtr->cwdPtr);
Tcl_MutexUnlock(&cwdMutex);
}
}
return srcFsPathPtr->normPathPtr;
}
/*
*---------------------------------------------------------------------------
*
* Tcl_FSGetInternalRep --
*
* Extract the internal representation of a given path object,
* in the given filesystem. If the path object belongs to a
* different filesystem, we return NULL.
*
* If the internal representation is currently NULL, we attempt
* to generate it, by calling the filesystem's
* 'Tcl_FSCreateInternalRepProc'.
*
* Results:
* NULL or a valid internal representation.
*
* Side effects:
* An attempt may be made to convert the object.
*
*---------------------------------------------------------------------------
*/
ClientData
Tcl_FSGetInternalRep(pathObjPtr, fsPtr)
Tcl_Obj* pathObjPtr;
Tcl_Filesystem *fsPtr;
{
register FsPath* srcFsPathPtr;
if (Tcl_FSConvertToPathType(NULL, pathObjPtr) != TCL_OK) {
return NULL;
}
srcFsPathPtr = (FsPath*) pathObjPtr->internalRep.otherValuePtr;
/*
* We will only return the native representation for the caller's
* filesystem. Otherwise we will simply return NULL. This means
* that there must be a unique bi-directional mapping between paths
* and filesystems, and that this mapping will not allow 'remapped'
* files -- files which are in one filesystem but mapped into
* another. Another way of putting this is that 'stacked'
* filesystems are not allowed. We recognise that this is a
* potentially useful feature for the future.
*
* Even something simple like a 'pass through' filesystem which
* logs all activity and passes the calls onto the native system
* would be nice, but not easily achievable with the current
* implementation.
*/
if (srcFsPathPtr->fsRecPtr == NULL) {
/*
* This only usually happens in wrappers like TclpStat which
* create a string object and pass it to TclpObjStat. Code
* which calls the Tcl_FS.. functions should always have a
* filesystem already set. Whether this code path is legal or
* not depends on whether we decide to allow external code to
* call the native filesystem directly. It is at least safer
* to allow this sub-optimal routing.
*/
Tcl_FSGetFileSystemForPath(pathObjPtr);
}
if (fsPtr != srcFsPathPtr->fsRecPtr->fsPtr) {
return NULL;
}
if (srcFsPathPtr->nativePathPtr == NULL) {
Tcl_FSCreateInternalRepProc *proc;
proc = srcFsPathPtr->fsRecPtr->fsPtr->createInternalRepProc;
if (proc == NULL) {
return NULL;
}
srcFsPathPtr->nativePathPtr = (*proc)(pathObjPtr);
}
return srcFsPathPtr->nativePathPtr;
}
/*
*---------------------------------------------------------------------------
*
* Tcl_FSGetNativePath --
*
* This function is for use by the Win/Unix/MacOS native filesystems,
* so that they can easily retrieve the native (char* or TCHAR*)
* representation of a path. Other filesystems will probably
* want to implement similar functions. They basically act as a
* safety net around Tcl_FSGetInternalRep. Normally your file-
* system procedures will always be called with path objects
* already converted to the correct filesystem, but if for
* some reason they are called directly (i.e. by procedures
* not in this file), then one cannot necessarily guarantee that
* the path object pointer is from the correct filesystem.
*
* Note: in the future it might be desireable to have separate
* versions of this function with different signatures, for
* example Tcl_FSGetNativeMacPath, Tcl_FSGetNativeUnixPath etc.
* Right now, since native paths are all string based, we use just
* one function. On MacOS we could possibly use an FSSpec or
* FSRef as the native representation.
*
* Results:
* NULL or a valid native path.
*
* Side effects:
* See Tcl_FSGetInternalRep.
*
*---------------------------------------------------------------------------
*/
char*
Tcl_FSGetNativePath(pathObjPtr)
Tcl_Obj* pathObjPtr;
{
return (char*)Tcl_FSGetInternalRep(pathObjPtr, &nativeFilesystem);
}
/*
*---------------------------------------------------------------------------
*
* NativeCreateNativeRep --
*
* Create a native representation for the given path.
*
* Results:
* None.
*
* Side effects:
* None.
*
*---------------------------------------------------------------------------
*/
ClientData
NativeCreateNativeRep(pathObjPtr)
Tcl_Obj* pathObjPtr;
{
char *nativePathPtr;
Tcl_DString ds;
Tcl_Obj* normPtr;
int len;
char *str;
/* Make sure the normalized path is set */
normPtr = Tcl_FSGetNormalizedPath(NULL, pathObjPtr);
str = Tcl_GetStringFromObj(normPtr,&len);
#ifdef __WIN32__
Tcl_WinUtfToTChar(str, len, &ds);
nativePathPtr = ckalloc((unsigned)(2+Tcl_DStringLength(&ds)));
memcpy((VOID*)nativePathPtr, (VOID*)Tcl_DStringValue(&ds),
(size_t) (2+Tcl_DStringLength(&ds)));
#else
Tcl_UtfToExternalDString(NULL, str, len, &ds);
nativePathPtr = ckalloc((unsigned)(1+Tcl_DStringLength(&ds)));
memcpy((VOID*)nativePathPtr, (VOID*)Tcl_DStringValue(&ds),
(size_t) (1+Tcl_DStringLength(&ds)));
#endif
Tcl_DStringFree(&ds);
return (ClientData)nativePathPtr;
}
/*
*---------------------------------------------------------------------------
*
* TclpNativeToNormalized --
*
* Convert native format to a normalized path object, with refCount
* of zero.
*
* Results:
* A valid normalized path.
*
* Side effects:
* None.
*
*---------------------------------------------------------------------------
*/
Tcl_Obj*
TclpNativeToNormalized(clientData)
ClientData clientData;
{
Tcl_DString ds;
Tcl_Obj *objPtr;
#ifdef __WIN32__
Tcl_WinTCharToUtf((char*)clientData, -1, &ds);
#else
Tcl_ExternalToUtfDString(NULL, (char*)clientData, -1, &ds);
#endif
objPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds),Tcl_DStringLength(&ds));
Tcl_DStringFree(&ds);
return objPtr;
}
/*
*---------------------------------------------------------------------------
*
* NativeDupInternalRep --
*
* Duplicate the native representation.
*
* Results:
* The copied native representation, or NULL if it is not possible
* to copy the representation.
*
* Side effects:
* None.
*
*---------------------------------------------------------------------------
*/
ClientData
NativeDupInternalRep(clientData)
ClientData clientData;
{
#ifdef __WIN32__
/* Copying internal representations is complicated with multi-byte TChars */
return NULL;
#else
if (clientData == NULL) {
return NULL;
} else {
char *native = (char*)clientData;
char *copy = ckalloc((unsigned)(1+strlen(native)));
strcpy(copy,native);
return (ClientData)copy;
}
#endif
}
/*
*---------------------------------------------------------------------------
*
* NativePathInFilesystem --
*
* Any path object is acceptable to the native filesystem, by
* default (we will throw errors when illegal paths are actually
* tried to be used).
*
* Results:
* TCL_OK, to indicate 'yes', -1 to indicate no.
*
* Side effects:
* None.
*
*---------------------------------------------------------------------------
*/
int
NativePathInFilesystem(pathPtr, clientDataPtr)
Tcl_Obj *pathPtr;
ClientData *clientDataPtr;
{
int len;
Tcl_GetStringFromObj(pathPtr,&len);
if (len == 0) {
return -1;
} else {
/* We accept any path as valid */
return TCL_OK;
}
}
/*
*---------------------------------------------------------------------------
*
* NativeFreeInternalRep --
*
* Free a native internal representation, which will be non-NULL.
*
* Results:
* None.
*
* Side effects:
* Memory is released.
*
*---------------------------------------------------------------------------
*/
void
NativeFreeInternalRep(clientData)
ClientData clientData;
{
ckfree((char*)clientData);
}
/*
*---------------------------------------------------------------------------
*
* Tcl_FSFileSystemInfo --
*
* This function returns a list of two elements. The first
* element is the name of the filesystem (e.g. "native" or "vfs"),
* and the second is the particular type of the given path within
* that filesystem.
*
* Results:
* A list of two elements.
*
* Side effects:
* The object may be converted to a path type.
*
*---------------------------------------------------------------------------
*/
Tcl_Obj*
Tcl_FSFileSystemInfo(pathObjPtr)
Tcl_Obj* pathObjPtr;
{
Tcl_Obj *resPtr;
Tcl_FSFilesystemPathTypeProc *proc;
Tcl_Filesystem *fsPtr = Tcl_FSGetFileSystemForPath(pathObjPtr);
if (fsPtr == NULL) {
return NULL;
}
resPtr = Tcl_NewListObj(0,NULL);
Tcl_ListObjAppendElement(NULL, resPtr,
Tcl_NewStringObj(fsPtr->typeName,-1));
proc = fsPtr->filesystemPathTypeProc;
if (proc != NULL) {
Tcl_Obj *typePtr = (*proc)(pathObjPtr);
if (typePtr != NULL) {
Tcl_ListObjAppendElement(NULL, resPtr, typePtr);
}
}
return resPtr;
}
/*
*---------------------------------------------------------------------------
*
* Tcl_FSPathSeparator --
*
* This function returns the separator to be used for a given
* path. The object returned should have a refCount of zero
*
* Results:
* A Tcl object, with a refCount of zero. If the caller
* needs to retain a reference to the object, it should
* call Tcl_IncrRefCount.
*
* Side effects:
* The path object may be converted to a path type.
*
*---------------------------------------------------------------------------
*/
Tcl_Obj*
Tcl_FSPathSeparator(pathObjPtr)
Tcl_Obj* pathObjPtr;
{
Tcl_Filesystem *fsPtr = Tcl_FSGetFileSystemForPath(pathObjPtr);
if (fsPtr == NULL) {
return NULL;
}
if (fsPtr->filesystemSeparatorProc != NULL) {
return (*fsPtr->filesystemSeparatorProc)(pathObjPtr);
}
return NULL;
}
/*
*---------------------------------------------------------------------------
*
* NativeFilesystemSeparator --
*
* This function is part of the native filesystem support, and
* returns the separator for the given path.
*
* Results:
* String object containing the separator character.
*
* Side effects:
* None.
*
*---------------------------------------------------------------------------
*/
Tcl_Obj*
NativeFilesystemSeparator(pathObjPtr)
Tcl_Obj* pathObjPtr;
{
char *separator = NULL; /* lint */
switch (tclPlatform) {
case TCL_PLATFORM_UNIX:
separator = "/";
break;
case TCL_PLATFORM_WINDOWS:
separator = "\\";
break;
case TCL_PLATFORM_MAC:
separator = ":";
break;
}
return Tcl_NewStringObj(separator,1);
}
/*
*---------------------------------------------------------------------------
*
* NativeFilesystemPathType --
*
* This function is part of the native filesystem support, and
* returns the path type of the given path. Right now it simply
* returns NULL. In the future it could return specific path
* types, like 'network' for a natively-networked path, etc.
*
* Results:
* NULL at present.
*
* Side effects:
* None.
*
*---------------------------------------------------------------------------
*/
Tcl_Obj*
NativeFilesystemPathType(pathObjPtr)
Tcl_Obj* pathObjPtr;
{
/* All native paths are of the same type */
return NULL;
}
/*
*---------------------------------------------------------------------------
*
* Tcl_FSGetFileSystemForPath --
*
* This function determines which filesystem to use for a
* particular path object, and returns the filesystem which
* accepts this file. If no filesystem will accept this object
* as a valid file path, then NULL is returned.
*
* Results:
* NULL or a filesystem which will accept this path.
*
* Side effects:
* The object may be converted to a path type.
*
*---------------------------------------------------------------------------
*/
static Tcl_Filesystem*
Tcl_FSGetFileSystemForPath(pathObjPtr)
Tcl_Obj* pathObjPtr;
{
FilesystemRecord *fsRecPtr;
Tcl_Filesystem* retVal = NULL;
FsPath* srcFsPathPtr;
/* Make sure pathObjPtr is of our type */
if (Tcl_FSConvertToPathType(NULL, pathObjPtr) != TCL_OK) {
return NULL;
}
if (Tcl_FSGetNormalizedPath(NULL, pathObjPtr) == NULL) {
return NULL;
}
/*
* Get a lock on filesystemEpoch and the filesystemList
*
* While we don't need the fsRecPtr until the while loop
* below, we do want to make sure the filesystemEpoch doesn't
* change between the 'if' and 'while' blocks, getting this
* iterator will ensure that everything is consistent
*/
fsRecPtr = FsGetIterator();
/* Make sure pathObjPtr is of the correct epoch */
srcFsPathPtr = (FsPath*) pathObjPtr->internalRep.otherValuePtr;
if (srcFsPathPtr->filesystemEpoch != -1) {
/*
* Check if the filesystem has changed in some way since
* this object's internal representation was calculated.
*/
if (srcFsPathPtr->filesystemEpoch != filesystemEpoch) {
/*
* We have to discard the stale representation and
* recalculate it
*/
FreeFsPathInternalRep(pathObjPtr);
pathObjPtr->typePtr = NULL;
if (SetFsPathFromAny(NULL, pathObjPtr) != TCL_OK) {
goto done;
}
srcFsPathPtr = (FsPath*) pathObjPtr->internalRep.otherValuePtr;
}
}
/* Check whether the object is already assigned to a fs */
if (srcFsPathPtr->fsRecPtr != NULL) {
retVal = srcFsPathPtr->fsRecPtr->fsPtr;
goto done;
}
/*
* Call each of the "pathInFilesystem" functions in succession. A
* non-return value of -1 indicates the particular function has
* succeeded.
*/
while ((retVal == NULL) && (fsRecPtr != NULL)) {
Tcl_FSPathInFilesystemProc *proc = fsRecPtr->fsPtr->pathInFilesystemProc;
if (proc != NULL) {
ClientData clientData = NULL;
int ret = (*proc)(pathObjPtr, &clientData);
if (ret != -1) {
/*
* We assume the srcFsPathPtr hasn't been changed
* by the above call to the pathInFilesystemProc.
*/
srcFsPathPtr->fsRecPtr = fsRecPtr;
srcFsPathPtr->nativePathPtr = clientData;
srcFsPathPtr->filesystemEpoch = filesystemEpoch;
fsRecPtr->refCount++;
retVal = fsRecPtr->fsPtr;
}
}
fsRecPtr = fsRecPtr->nextPtr;
}
done:
FsReleaseIterator();
return retVal;
}
/*
*---------------------------------------------------------------------------
*
* Tcl_FSEqualPaths --
*
* This function tests whether the two paths given are equal path
* objects.
*
* Results:
* 1 or 0.
*
* Side effects:
* None.
*
*---------------------------------------------------------------------------
*/
int
Tcl_FSEqualPaths(firstPtr, secondPtr)
Tcl_Obj* firstPtr;
Tcl_Obj* secondPtr;
{
if (firstPtr == secondPtr) {
return 1;
} else {
int tempErrno;
if (firstPtr == NULL || secondPtr == NULL) {
return 0;
}
if (!(strcmp(Tcl_GetString(firstPtr), Tcl_GetString(secondPtr)))) {
return 1;
}
/*
* Try the most thorough, correct method of comparing fully
* normalized paths
*/
tempErrno = Tcl_GetErrno();
firstPtr = Tcl_FSGetNormalizedPath(NULL, firstPtr);
secondPtr = Tcl_FSGetNormalizedPath(NULL, secondPtr);
Tcl_SetErrno(tempErrno);
if (firstPtr == NULL || secondPtr == NULL) {
return 0;
}
if (!(strcmp(Tcl_GetString(firstPtr), Tcl_GetString(secondPtr)))) {
return 1;
}
}
return 0;
}
/* Wrappers */
Tcl_Channel
NativeOpenFileChannel(interp, pathPtr, modeString, permissions)
Tcl_Interp *interp;
Tcl_Obj *pathPtr;
char *modeString;
int permissions;
{
char *trans = Tcl_FSGetTranslatedPath(interp, pathPtr);
if (trans == NULL) {
return NULL;
}
return TclpOpenFileChannel(interp, trans, modeString, permissions);
}
/*
* utime wants a normalized, NOT native path. I assume a native
* version of 'utime' doesn't exist (at least under that name) on NT/2000.
* If a native function does exist somewhere, then we could use:
*
* return native_utime(Tcl_FSGetNativePath(pathPtr),tval);
*
* This seems rather strange when compared with stat, lstat, access, etc.
* all of which want a native path.
*/
int
NativeUtime(pathPtr, tval)
Tcl_Obj *pathPtr;
struct utimbuf *tval;
{
#ifdef MAC_TCL
long gmt_offset=TclpGetGMTOffset();
struct utimbuf local_tval;
local_tval.actime=tval->actime+gmt_offset;
local_tval.modtime=tval->modtime+gmt_offset;
return utime(Tcl_GetString(Tcl_FSGetNormalizedPath(NULL,pathPtr)),&local_tval);
#else
return utime(Tcl_GetString(Tcl_FSGetNormalizedPath(NULL,pathPtr)),tval);
#endif
}
int
NativeLoadFile(interp, pathPtr, sym1, sym2, proc1Ptr, proc2Ptr, clientDataPtr)
Tcl_Interp * interp;
Tcl_Obj *pathPtr;
char * sym1;
char * sym2;
Tcl_PackageInitProc ** proc1Ptr;
Tcl_PackageInitProc ** proc2Ptr;
ClientData * clientDataPtr;
{
return TclpLoadFile(interp, Tcl_FSGetTranslatedPath(NULL, pathPtr),
sym1, sym2, proc1Ptr, proc2Ptr, clientDataPtr);
}
/* Everything from here on is contained in this obsolete ifdef */
#ifdef USE_OBSOLETE_FS_HOOKS
/*
*----------------------------------------------------------------------
*
* TclStatInsertProc --
*
* Insert the passed procedure pointer at the head of the list of
* functions which are used during a call to 'TclStat(...)'. The
|
| ︙ | ︙ | |||
601 602 603 604 605 606 607 |
if (proc != NULL) {
StatProc *newStatProcPtr;
newStatProcPtr = (StatProc *)ckalloc(sizeof(StatProc));
if (newStatProcPtr != NULL) {
newStatProcPtr->proc = proc;
| | | | 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 |
if (proc != NULL) {
StatProc *newStatProcPtr;
newStatProcPtr = (StatProc *)ckalloc(sizeof(StatProc));
if (newStatProcPtr != NULL) {
newStatProcPtr->proc = proc;
Tcl_MutexLock(&obsoleteFsHookMutex);
newStatProcPtr->nextPtr = statProcList;
statProcList = newStatProcPtr;
Tcl_MutexUnlock(&obsoleteFsHookMutex);
retVal = TCL_OK;
}
}
return (retVal);
}
|
| ︙ | ︙ | |||
640 641 642 643 644 645 646 |
TclStatDeleteProc (proc)
TclStatProc_ *proc;
{
int retVal = TCL_ERROR;
StatProc *tmpStatProcPtr;
StatProc *prevStatProcPtr = NULL;
| | | | | | 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 |
TclStatDeleteProc (proc)
TclStatProc_ *proc;
{
int retVal = TCL_ERROR;
StatProc *tmpStatProcPtr;
StatProc *prevStatProcPtr = NULL;
Tcl_MutexLock(&obsoleteFsHookMutex);
tmpStatProcPtr = statProcList;
/*
* Traverse the 'statProcList' looking for the particular node
* whose 'proc' member matches 'proc' and remove that one from
* the list. Ensure that the "default" node cannot be removed.
*/
while ((retVal == TCL_ERROR) && (tmpStatProcPtr != NULL)) {
if (tmpStatProcPtr->proc == proc) {
if (prevStatProcPtr == NULL) {
statProcList = tmpStatProcPtr->nextPtr;
} else {
prevStatProcPtr->nextPtr = tmpStatProcPtr->nextPtr;
}
ckfree((char *)tmpStatProcPtr);
retVal = TCL_OK;
} else {
prevStatProcPtr = tmpStatProcPtr;
tmpStatProcPtr = tmpStatProcPtr->nextPtr;
}
}
Tcl_MutexUnlock(&obsoleteFsHookMutex);
return (retVal);
}
/*
*----------------------------------------------------------------------
*
* TclAccessInsertProc --
|
| ︙ | ︙ | |||
704 705 706 707 708 709 710 |
if (proc != NULL) {
AccessProc *newAccessProcPtr;
newAccessProcPtr = (AccessProc *)ckalloc(sizeof(AccessProc));
if (newAccessProcPtr != NULL) {
newAccessProcPtr->proc = proc;
| | | | 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 |
if (proc != NULL) {
AccessProc *newAccessProcPtr;
newAccessProcPtr = (AccessProc *)ckalloc(sizeof(AccessProc));
if (newAccessProcPtr != NULL) {
newAccessProcPtr->proc = proc;
Tcl_MutexLock(&obsoleteFsHookMutex);
newAccessProcPtr->nextPtr = accessProcList;
accessProcList = newAccessProcPtr;
Tcl_MutexUnlock(&obsoleteFsHookMutex);
retVal = TCL_OK;
}
}
return (retVal);
}
|
| ︙ | ︙ | |||
749 750 751 752 753 754 755 |
/*
* Traverse the 'accessProcList' looking for the particular node
* whose 'proc' member matches 'proc' and remove that one from
* the list. Ensure that the "default" node cannot be removed.
*/
| | | | | | 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 |
/*
* Traverse the 'accessProcList' looking for the particular node
* whose 'proc' member matches 'proc' and remove that one from
* the list. Ensure that the "default" node cannot be removed.
*/
Tcl_MutexLock(&obsoleteFsHookMutex);
tmpAccessProcPtr = accessProcList;
while ((retVal == TCL_ERROR) && (tmpAccessProcPtr != NULL)) {
if (tmpAccessProcPtr->proc == proc) {
if (prevAccessProcPtr == NULL) {
accessProcList = tmpAccessProcPtr->nextPtr;
} else {
prevAccessProcPtr->nextPtr = tmpAccessProcPtr->nextPtr;
}
ckfree((char *)tmpAccessProcPtr);
retVal = TCL_OK;
} else {
prevAccessProcPtr = tmpAccessProcPtr;
tmpAccessProcPtr = tmpAccessProcPtr->nextPtr;
}
}
Tcl_MutexUnlock(&obsoleteFsHookMutex);
return (retVal);
}
/*
*----------------------------------------------------------------------
*
|
| ︙ | ︙ | |||
809 810 811 812 813 814 815 |
OpenFileChannelProc *newOpenFileChannelProcPtr;
newOpenFileChannelProcPtr =
(OpenFileChannelProc *)ckalloc(sizeof(OpenFileChannelProc));
if (newOpenFileChannelProcPtr != NULL) {
newOpenFileChannelProcPtr->proc = proc;
| | | | 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 |
OpenFileChannelProc *newOpenFileChannelProcPtr;
newOpenFileChannelProcPtr =
(OpenFileChannelProc *)ckalloc(sizeof(OpenFileChannelProc));
if (newOpenFileChannelProcPtr != NULL) {
newOpenFileChannelProcPtr->proc = proc;
Tcl_MutexLock(&obsoleteFsHookMutex);
newOpenFileChannelProcPtr->nextPtr = openFileChannelProcList;
openFileChannelProcList = newOpenFileChannelProcPtr;
Tcl_MutexUnlock(&obsoleteFsHookMutex);
retVal = TCL_OK;
}
}
return (retVal);
}
|
| ︙ | ︙ | |||
851 852 853 854 855 856 857 |
int retVal = TCL_ERROR;
OpenFileChannelProc *tmpOpenFileChannelProcPtr = openFileChannelProcList;
OpenFileChannelProc *prevOpenFileChannelProcPtr = NULL;
/*
* Traverse the 'openFileChannelProcList' looking for the particular
* node whose 'proc' member matches 'proc' and remove that one from
| | | | | | > | 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 |
int retVal = TCL_ERROR;
OpenFileChannelProc *tmpOpenFileChannelProcPtr = openFileChannelProcList;
OpenFileChannelProc *prevOpenFileChannelProcPtr = NULL;
/*
* Traverse the 'openFileChannelProcList' looking for the particular
* node whose 'proc' member matches 'proc' and remove that one from
* the list.
*/
Tcl_MutexLock(&obsoleteFsHookMutex);
tmpOpenFileChannelProcPtr = openFileChannelProcList;
while ((retVal == TCL_ERROR) &&
(tmpOpenFileChannelProcPtr != NULL)) {
if (tmpOpenFileChannelProcPtr->proc == proc) {
if (prevOpenFileChannelProcPtr == NULL) {
openFileChannelProcList = tmpOpenFileChannelProcPtr->nextPtr;
} else {
prevOpenFileChannelProcPtr->nextPtr =
tmpOpenFileChannelProcPtr->nextPtr;
}
ckfree((char *)tmpOpenFileChannelProcPtr);
retVal = TCL_OK;
} else {
prevOpenFileChannelProcPtr = tmpOpenFileChannelProcPtr;
tmpOpenFileChannelProcPtr = tmpOpenFileChannelProcPtr->nextPtr;
}
}
Tcl_MutexUnlock(&obsoleteFsHookMutex);
return (retVal);
}
#endif /* USE_OBSOLETE_FS_HOOKS */
|
Changes to generic/tclInt.decls.
1 2 3 4 5 6 7 8 9 10 11 12 | # tclInt.decls -- # # This file contains the declarations for all unsupported # functions that are exported by the Tcl library. This file # is used to generate the tclIntDecls.h, tclIntPlatDecls.h, # tclIntStub.c, tclPlatStub.c, tclCompileDecls.h and tclCompileStub.c # files # # Copyright (c) 1998-1999 by Scriptics Corporation. # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | # tclInt.decls -- # # This file contains the declarations for all unsupported # functions that are exported by the Tcl library. This file # is used to generate the tclIntDecls.h, tclIntPlatDecls.h, # tclIntStub.c, tclPlatStub.c, tclCompileDecls.h and tclCompileStub.c # files # # Copyright (c) 1998-1999 by Scriptics Corporation. # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: tclInt.decls,v 1.29 2001/07/31 19:12:06 vincentdarley Exp $ library tcl # Define the unsupported generic interfaces. interface tclInt |
| ︙ | ︙ | |||
70 71 72 73 74 75 76 |
void TclDeleteCompiledLocalVars(Interp *iPtr, CallFrame *framePtr)
}
declare 12 generic {
void TclDeleteVars(Interp *iPtr, Tcl_HashTable *tablePtr)
}
declare 13 generic {
int TclDoGlob(Tcl_Interp *interp, char *separators, \
| | > | | < > | | < > | | < > | | < > | | < > | 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
void TclDeleteCompiledLocalVars(Interp *iPtr, CallFrame *framePtr)
}
declare 12 generic {
void TclDeleteVars(Interp *iPtr, Tcl_HashTable *tablePtr)
}
declare 13 generic {
int TclDoGlob(Tcl_Interp *interp, char *separators, \
Tcl_DString *headPtr, char *tail, Tcl_GlobTypeData *types)
}
declare 14 generic {
void TclDumpMemoryInfo(FILE *outFile)
}
# Removed in 8.1:
# declare 15 generic {
# void TclExpandParseValue(ParseValue *pvPtr, int needed)
# }
declare 16 generic {
void TclExprFloatError(Tcl_Interp *interp, double value)
}
# Removed in 8.4
#declare 17 generic {
# int TclFileAttrsCmd(Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
#}
#declare 18 generic {
# int TclFileCopyCmd(Tcl_Interp *interp, int argc, char **argv)
#}
#declare 19 generic {
# int TclFileDeleteCmd(Tcl_Interp *interp, int argc, char **argv)
#}
#declare 20 generic {
# int TclFileMakeDirsCmd(Tcl_Interp *interp, int argc, char **argv)
#}
#declare 21 generic {
# int TclFileRenameCmd(Tcl_Interp *interp, int argc, char **argv)
#}
declare 22 generic {
int TclFindElement(Tcl_Interp *interp, CONST char *listStr, \
int listLength, CONST char **elementPtr, CONST char **nextPtr, \
int *sizePtr, int *bracePtr)
}
declare 23 generic {
Proc * TclFindProc(Interp *iPtr, char *procName)
|
| ︙ | ︙ | |||
231 232 233 234 235 236 237 |
# int TclLooksLikeInt(char *p)
# }
declare 58 generic {
Var * TclLookupVar(Tcl_Interp *interp, char *part1, char *part2, \
int flags, char *msg, int createPart1, int createPart2, \
Var **arrayPtrPtr)
}
| > | | | < > | 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 |
# int TclLooksLikeInt(char *p)
# }
declare 58 generic {
Var * TclLookupVar(Tcl_Interp *interp, char *part1, char *part2, \
int flags, char *msg, int createPart1, int createPart2, \
Var **arrayPtrPtr)
}
# Replaced by Tcl_FSMatchInDirectory in 8.4
#declare 59 generic {
# int TclpMatchFiles(Tcl_Interp *interp, char *separators, \
# Tcl_DString *dirPtr, char *pattern, char *tail)
#}
declare 60 generic {
int TclNeedSpace(char *start, char *end)
}
declare 61 generic {
Tcl_Obj * TclNewProcBodyObj(Proc *procPtr)
}
declare 62 generic {
|
| ︙ | ︙ | |||
268 269 270 271 272 273 274 |
}
declare 68 generic {
int TclpAccess(CONST char *path, int mode)
}
declare 69 generic {
char * TclpAlloc(unsigned int size)
}
| | | < > | | | < > | | < > | | < > | 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 |
}
declare 68 generic {
int TclpAccess(CONST char *path, int mode)
}
declare 69 generic {
char * TclpAlloc(unsigned int size)
}
#declare 70 generic {
# int TclpCopyFile(CONST char *source, CONST char *dest)
#}
#declare 71 generic {
# int TclpCopyDirectory(CONST char *source, CONST char *dest, \
# Tcl_DString *errorPtr)
#}
#declare 72 generic {
# int TclpCreateDirectory(CONST char *path)
#}
#declare 73 generic {
# int TclpDeleteFile(CONST char *path)
#}
declare 74 generic {
void TclpFree(char *ptr)
}
declare 75 generic {
unsigned long TclpGetClicks(void)
}
declare 76 generic {
|
| ︙ | ︙ | |||
306 307 308 309 310 311 312 |
declare 80 generic {
Tcl_Channel TclpOpenFileChannel(Tcl_Interp *interp, char *fileName, \
char *modeString, int permissions)
}
declare 81 generic {
char * TclpRealloc(char *ptr, unsigned int size)
}
| | | | < > | | < > | 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 |
declare 80 generic {
Tcl_Channel TclpOpenFileChannel(Tcl_Interp *interp, char *fileName, \
char *modeString, int permissions)
}
declare 81 generic {
char * TclpRealloc(char *ptr, unsigned int size)
}
#declare 82 generic {
# int TclpRemoveDirectory(CONST char *path, int recursive, \
# Tcl_DString *errorPtr)
#}
#declare 83 generic {
# int TclpRenameFile(CONST char *source, CONST char *dest)
#}
# Removed in 8.1:
# declare 84 generic {
# int TclParseBraces(Tcl_Interp *interp, char *str, char **termPtr, \
# ParseValue *pvPtr)
# }
# declare 85 generic {
# int TclParseNestedCmd(Tcl_Interp *interp, char *str, int flags, \
|
| ︙ | ︙ | |||
508 509 510 511 512 513 514 |
}
declare 135 generic {
int TclpCheckStackSpace(void)
}
# Added in 8.1:
| | | < > | | < > | 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 |
}
declare 135 generic {
int TclpCheckStackSpace(void)
}
# Added in 8.1:
#declare 137 generic {
# int TclpChdir(CONST char *dirName)
#}
declare 138 generic {
char * TclGetEnv(CONST char *name, Tcl_DString *valuePtr)
}
declare 139 generic {
int TclpLoadFile(Tcl_Interp *interp, char *fileName, char *sym1, \
char *sym2, Tcl_PackageInitProc **proc1Ptr, \
Tcl_PackageInitProc **proc2Ptr, ClientData *clientDataPtr)
}
declare 140 generic {
int TclLooksLikeInt(char *bytes, int length)
}
#declare 141 generic {
# char *TclpGetCwd(Tcl_Interp *interp, Tcl_DString *cwdPtr)
#}
declare 142 generic {
int TclSetByteCodeFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr, \
CompileHookProc *hookProc, ClientData clientData)
}
declare 143 generic {
int TclAddLiteralObj(struct CompileEnv *envPtr, Tcl_Obj *objPtr, \
LiteralEntry **litPtrPtr)
|
| ︙ | ︙ | |||
597 598 599 600 601 602 603 |
}
declare 158 generic {
void TclSetStartupScriptFileName(char *filename)
}
declare 159 generic {
char *TclGetStartupScriptFileName(void)
}
| | | | < > > > > > > > > > > > > > > > > > > > > > > > > > > | 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 |
}
declare 158 generic {
void TclSetStartupScriptFileName(char *filename)
}
declare 159 generic {
char *TclGetStartupScriptFileName(void)
}
#declare 160 generic {
# int TclpMatchFilesTypes(Tcl_Interp *interp, char *separators, \
# Tcl_DString *dirPtr, char *pattern, char *tail, GlobTypeData *types)
#}
# new in 8.3.2/8.4a2
declare 161 generic {
int TclChannelTransform(Tcl_Interp *interp, Tcl_Channel chan, \
Tcl_Obj *cmdObjPtr)
}
declare 162 generic {
void TclChannelEventScriptInvoker(ClientData clientData, int flags)
}
# for virtual filesystem support. These should eventually be moved to
# Tcl's external API and properly documented, to allow extension writers
# to use them easily (hence providing automatic VFS support to all
# extensions)
declare 163 generic {
int TclFileCopyCmd(Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
}
declare 164 generic {
int TclFileRenameCmd(Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
}
declare 165 generic {
int TclFileDeleteCmd(Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
}
declare 166 generic {
int TclFileMakeDirsCmd(Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
}
declare 167 generic {
int TclFileAttrsCmd(Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
}
declare 168 generic {
Tcl_Obj* TclpTempFileName(void)
}
declare 169 generic {
void TclpSetInitialEncodings(void)
}
##############################################################################
# Define the platform specific internal Tcl interface. These functions are
# only available on the designated platform.
|
| ︙ | ︙ | |||
866 867 868 869 870 871 872 |
}
# Added in 8.1:
declare 9 unix {
TclFile TclpCreateTempFile(CONST char *contents)
}
| > | 893 894 895 896 897 898 899 900 |
}
# Added in 8.1:
declare 9 unix {
TclFile TclpCreateTempFile(CONST char *contents)
}
|
Changes to generic/tclInt.h.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* * tclInt.h -- * * Declarations of things used internally by the Tcl interpreter. * * Copyright (c) 1987-1993 The Regents of the University of California. * Copyright (c) 1993-1997 Lucent Technologies. * Copyright (c) 1994-1998 Sun Microsystems, Inc. * Copyright (c) 1998-1999 by Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* * tclInt.h -- * * Declarations of things used internally by the Tcl interpreter. * * Copyright (c) 1987-1993 The Regents of the University of California. * Copyright (c) 1993-1997 Lucent Technologies. * Copyright (c) 1994-1998 Sun Microsystems, Inc. * Copyright (c) 1998-1999 by Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclInt.h,v 1.58 2001/07/31 19:12:06 vincentdarley Exp $ */ #ifndef _TCLINT #define _TCLINT /* * Common include files needed by most of the Tcl source files are |
| ︙ | ︙ | |||
1270 1271 1272 1273 1274 1275 1276 |
* process local variables appropriately. */
ResolverScheme *resolverPtr;
/* Linked list of name resolution schemes
* added to this interpreter. Schemes
* are added/removed by calling
* Tcl_AddInterpResolvers and
* Tcl_RemoveInterpResolver. */
| | | < < | 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 |
* process local variables appropriately. */
ResolverScheme *resolverPtr;
/* Linked list of name resolution schemes
* added to this interpreter. Schemes
* are added/removed by calling
* Tcl_AddInterpResolvers and
* Tcl_RemoveInterpResolver. */
Tcl_Obj *scriptFile; /* NULL means there is no nested source
* command active; otherwise this points to
* pathPtr of the file being sourced. */
int flags; /* Various flag bits. See below. */
long randSeed; /* Seed used for rand() function. */
Trace *tracePtr; /* List of traces for this interpreter. */
Tcl_HashTable *assocData; /* Hash table for associating data with
* this interpreter. Cleaned up when
* this interpreter is deleted. */
struct ExecEnv *execEnvPtr; /* Execution environment for Tcl bytecode
|
| ︙ | ︙ | |||
1500 1501 1502 1503 1504 1505 1506 1507 1508 |
/*
* Opaque handle used in pipeline routines to encapsulate platform-dependent
* state.
*/
typedef struct TclFile_ *TclFile;
/*
*----------------------------------------------------------------
| > > > > > > > > > > > > > > > > | < < < < < < < | | | < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < < > > > < < | 1498 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 |
/*
* Opaque handle used in pipeline routines to encapsulate platform-dependent
* state.
*/
typedef struct TclFile_ *TclFile;
/*
* Opaque names for platform specific types.
*/
typedef struct TclpTime_t_ *TclpTime_t;
/*
* The "globParameters" argument of the function TclGlob is an
* or'ed combination of the following values:
*/
#define TCL_GLOBMODE_NO_COMPLAIN 1
#define TCL_GLOBMODE_JOIN 2
#define TCL_GLOBMODE_DIR 4
#define TCL_GLOBMODE_TAILS 8
/*
*----------------------------------------------------------------
* Data structures related to obsolete filesystem hooks
*----------------------------------------------------------------
*/
typedef int (TclStatProc_) _ANSI_ARGS_((CONST char *path, struct stat *buf));
typedef int (TclAccessProc_) _ANSI_ARGS_((CONST char *path, int mode));
typedef Tcl_Channel (TclOpenFileChannelProc_) _ANSI_ARGS_((Tcl_Interp *interp,
char *fileName, char *modeString,
int permissions));
/*
*----------------------------------------------------------------
* Data structures related to procedures
*----------------------------------------------------------------
*/
typedef int (*TclCmdProcType) _ANSI_ARGS_((ClientData clientData,
Tcl_Interp *interp, int argc, char *argv[]));
typedef int (*TclObjCmdProcType) _ANSI_ARGS_((ClientData clientData,
Tcl_Interp *interp, int objc, struct Tcl_Obj * CONST objv[]));
/*
*----------------------------------------------------------------
* Variables shared among Tcl modules but not used by the outside world.
*----------------------------------------------------------------
*/
extern Tcl_Time tclBlockTime;
extern int tclBlockTimeSet;
extern char * tclExecutableName;
extern char * tclNativeExecutableName;
extern char * tclDefaultEncodingDir;
extern Tcl_ChannelType tclFileChannelType;
extern char * tclMemDumpFileName;
extern TclPlatformType tclPlatform;
/*
* Variables denoting the Tcl object types defined in the core.
*/
extern Tcl_ObjType tclBooleanType;
extern Tcl_ObjType tclByteArrayType;
|
| ︙ | ︙ | |||
1630 1631 1632 1633 1634 1635 1636 | /* *---------------------------------------------------------------- * Procedures shared among Tcl modules but not used by the outside * world: *---------------------------------------------------------------- */ | < < | 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 | /* *---------------------------------------------------------------- * Procedures shared among Tcl modules but not used by the outside * world: *---------------------------------------------------------------- */ EXTERN int TclAccessDeleteProc _ANSI_ARGS_((TclAccessProc_ *proc)); EXTERN int TclAccessInsertProc _ANSI_ARGS_((TclAccessProc_ *proc)); EXTERN void TclAllocateFreeObjects _ANSI_ARGS_((void)); EXTERN int TclArraySet _ANSI_ARGS_((Tcl_Interp *interp, Tcl_Obj *arrayNameObj, Tcl_Obj *arrayElemObj)); EXTERN int TclCheckBadOctal _ANSI_ARGS_((Tcl_Interp *interp, char *value)); |
| ︙ | ︙ | |||
1663 1664 1665 1666 1667 1668 1669 | Proc **procPtrPtr)); EXTERN void TclDeleteCompiledLocalVars _ANSI_ARGS_(( Interp *iPtr, CallFrame *framePtr)); EXTERN void TclDeleteVars _ANSI_ARGS_((Interp *iPtr, Tcl_HashTable *tablePtr)); EXTERN int TclDoGlob _ANSI_ARGS_((Tcl_Interp *interp, char *separators, Tcl_DString *headPtr, | | | | | | | 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 | Proc **procPtrPtr)); EXTERN void TclDeleteCompiledLocalVars _ANSI_ARGS_(( Interp *iPtr, CallFrame *framePtr)); EXTERN void TclDeleteVars _ANSI_ARGS_((Interp *iPtr, Tcl_HashTable *tablePtr)); EXTERN int TclDoGlob _ANSI_ARGS_((Tcl_Interp *interp, char *separators, Tcl_DString *headPtr, char *tail, Tcl_GlobTypeData *types)); EXTERN void TclDumpMemoryInfo _ANSI_ARGS_((FILE *outFile)); EXTERN void TclExpandTokenArray _ANSI_ARGS_(( Tcl_Parse *parsePtr)); EXTERN void TclExprFloatError _ANSI_ARGS_((Tcl_Interp *interp, double value)); EXTERN int TclFileAttrsCmd _ANSI_ARGS_((Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); EXTERN int TclFileCopyCmd _ANSI_ARGS_((Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])) ; EXTERN int TclFileDeleteCmd _ANSI_ARGS_((Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); EXTERN int TclFileMakeDirsCmd _ANSI_ARGS_((Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])) ; EXTERN int TclFileRenameCmd _ANSI_ARGS_((Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])) ; EXTERN void TclFinalizeAllocSubsystem _ANSI_ARGS_((void)); EXTERN void TclFinalizeCompExecEnv _ANSI_ARGS_((void)); EXTERN void TclFinalizeCompilation _ANSI_ARGS_((void)); EXTERN void TclFinalizeEncodingSubsystem _ANSI_ARGS_((void)); EXTERN void TclFinalizeEnvironment _ANSI_ARGS_((void)); EXTERN void TclFinalizeExecution _ANSI_ARGS_((void)); EXTERN void TclFinalizeIOSubsystem _ANSI_ARGS_((void)); |
| ︙ | ︙ | |||
1726 1727 1728 1729 1730 1731 1732 | CONST char **simpleNamePtr)); EXTERN TclObjCmdProcType TclGetObjInterpProc _ANSI_ARGS_((void)); EXTERN int TclGetOpenMode _ANSI_ARGS_((Tcl_Interp *interp, char *string, int *seekFlagPtr)); EXTERN Tcl_Command TclGetOriginalCommand _ANSI_ARGS_(( Tcl_Command command)); EXTERN int TclGlob _ANSI_ARGS_((Tcl_Interp *interp, | | | | 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 | CONST char **simpleNamePtr)); EXTERN TclObjCmdProcType TclGetObjInterpProc _ANSI_ARGS_((void)); EXTERN int TclGetOpenMode _ANSI_ARGS_((Tcl_Interp *interp, char *string, int *seekFlagPtr)); EXTERN Tcl_Command TclGetOriginalCommand _ANSI_ARGS_(( Tcl_Command command)); EXTERN int TclGlob _ANSI_ARGS_((Tcl_Interp *interp, char *pattern, Tcl_Obj *unquotedPrefix, int globFlags, Tcl_GlobTypeData* types)); EXTERN int TclGlobalInvoke _ANSI_ARGS_((Tcl_Interp *interp, int argc, char **argv, int flags)); EXTERN int TclGuessPackageName _ANSI_ARGS_((char *fileName, Tcl_DString *bufPtr)); EXTERN int TclHideUnsafeCommands _ANSI_ARGS_(( Tcl_Interp *interp)); EXTERN int TclInExit _ANSI_ARGS_((void)); |
| ︙ | ︙ | |||
1787 1788 1789 1790 1791 1792 1793 | int objc, Tcl_Obj *CONST objv[], int flags)); EXTERN int TclObjInvokeGlobal _ANSI_ARGS_((Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], int flags)); EXTERN int TclOpenFileChannelDeleteProc _ANSI_ARGS_(( TclOpenFileChannelProc_ *proc)); EXTERN int TclOpenFileChannelInsertProc _ANSI_ARGS_(( TclOpenFileChannelProc_ *proc)); | | > > | 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 | int objc, Tcl_Obj *CONST objv[], int flags)); EXTERN int TclObjInvokeGlobal _ANSI_ARGS_((Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], int flags)); EXTERN int TclOpenFileChannelDeleteProc _ANSI_ARGS_(( TclOpenFileChannelProc_ *proc)); EXTERN int TclOpenFileChannelInsertProc _ANSI_ARGS_(( TclOpenFileChannelProc_ *proc)); EXTERN int TclpObjAccess _ANSI_ARGS_((Tcl_Obj *filename, int mode)); EXTERN int TclpObjLstat _ANSI_ARGS_((Tcl_Obj *pathPtr, struct stat *buf)); EXTERN char * TclpAlloc _ANSI_ARGS_((unsigned int size)); EXTERN int TclpCheckStackSpace _ANSI_ARGS_((void)); EXTERN int TclpCopyFile _ANSI_ARGS_((CONST char *source, CONST char *dest)); EXTERN int TclpCopyDirectory _ANSI_ARGS_((CONST char *source, CONST char *dest, Tcl_DString *errorPtr)); EXTERN int TclpCreateDirectory _ANSI_ARGS_((CONST char *path)); |
| ︙ | ︙ | |||
1812 1813 1814 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 | EXTERN char * TclpFindExecutable _ANSI_ARGS_(( CONST char *argv0)); EXTERN int TclpFindVariable _ANSI_ARGS_((CONST char *name, int *lengthPtr)); EXTERN void TclpFree _ANSI_ARGS_((char *ptr)); EXTERN unsigned long TclpGetClicks _ANSI_ARGS_((void)); EXTERN Tcl_Channel TclpGetDefaultStdChannel _ANSI_ARGS_((int type)); EXTERN unsigned long TclpGetSeconds _ANSI_ARGS_((void)); EXTERN void TclpGetTime _ANSI_ARGS_((Tcl_Time *time)); EXTERN int TclpGetTimeZone _ANSI_ARGS_((unsigned long time)); EXTERN char * TclpGetUserHome _ANSI_ARGS_((CONST char *name, Tcl_DString *bufferPtr)); EXTERN int TclpHasSockets _ANSI_ARGS_((Tcl_Interp *interp)); EXTERN void TclpInitLibraryPath _ANSI_ARGS_((CONST char *argv0)); EXTERN void TclpInitLock _ANSI_ARGS_((void)); EXTERN void TclpInitPlatform _ANSI_ARGS_((void)); EXTERN void TclpInitUnlock _ANSI_ARGS_((void)); EXTERN int TclpListVolumes _ANSI_ARGS_((Tcl_Interp *interp)); EXTERN void TclpMasterLock _ANSI_ARGS_((void)); EXTERN void TclpMasterUnlock _ANSI_ARGS_((void)); EXTERN int TclpMatchFiles _ANSI_ARGS_((Tcl_Interp *interp, char *separators, Tcl_DString *dirPtr, char *pattern, char *tail)); EXTERN Tcl_Channel TclpOpenFileChannel _ANSI_ARGS_((Tcl_Interp *interp, char *fileName, char *modeString, int permissions)); EXTERN void TclpPanic _ANSI_ARGS_(TCL_VARARGS(CONST char *, format)); EXTERN char * TclpReadlink _ANSI_ARGS_((CONST char *fileName, Tcl_DString *linkPtr)); | > > > > > > > > > > > > > > > > > > > > | 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 | EXTERN char * TclpFindExecutable _ANSI_ARGS_(( CONST char *argv0)); EXTERN int TclpFindVariable _ANSI_ARGS_((CONST char *name, int *lengthPtr)); EXTERN void TclpFree _ANSI_ARGS_((char *ptr)); EXTERN unsigned long TclpGetClicks _ANSI_ARGS_((void)); EXTERN Tcl_Channel TclpGetDefaultStdChannel _ANSI_ARGS_((int type)); EXTERN long TclpGetGMTOffset _ANSI_ARGS_((void)); EXTERN unsigned long TclpGetSeconds _ANSI_ARGS_((void)); EXTERN void TclpGetTime _ANSI_ARGS_((Tcl_Time *time)); EXTERN int TclpGetTimeZone _ANSI_ARGS_((unsigned long time)); EXTERN char * TclpGetUserHome _ANSI_ARGS_((CONST char *name, Tcl_DString *bufferPtr)); EXTERN int TclpHasSockets _ANSI_ARGS_((Tcl_Interp *interp)); EXTERN void TclpInitLibraryPath _ANSI_ARGS_((CONST char *argv0)); EXTERN void TclpInitLock _ANSI_ARGS_((void)); EXTERN void TclpInitPlatform _ANSI_ARGS_((void)); EXTERN void TclpInitUnlock _ANSI_ARGS_((void)); EXTERN int TclpListVolumes _ANSI_ARGS_((Tcl_Interp *interp)); EXTERN void TclpMasterLock _ANSI_ARGS_((void)); EXTERN void TclpMasterUnlock _ANSI_ARGS_((void)); EXTERN int TclpMatchFiles _ANSI_ARGS_((Tcl_Interp *interp, char *separators, Tcl_DString *dirPtr, char *pattern, char *tail)); EXTERN int TclpObjNormalizePath _ANSI_ARGS_((Tcl_Interp *interp, Tcl_Obj *pathPtr, int nextCheckpoint)); EXTERN int TclpObjCreateDirectory _ANSI_ARGS_((Tcl_Obj *pathPtr)); EXTERN int TclpObjDeleteFile _ANSI_ARGS_((Tcl_Obj *pathPtr)); EXTERN int TclpObjCopyDirectory _ANSI_ARGS_((Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr, Tcl_Obj **errorPtr)); EXTERN int TclpObjCopyFile _ANSI_ARGS_((Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr)); EXTERN int TclpObjRemoveDirectory _ANSI_ARGS_((Tcl_Obj *pathPtr, int recursive, Tcl_Obj **errorPtr)); EXTERN int TclpObjRenameFile _ANSI_ARGS_((Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr)); EXTERN int TclpMatchInDirectory _ANSI_ARGS_((Tcl_Interp *interp, Tcl_Obj *resultPtr, Tcl_Obj *pathPtr, char *pattern, Tcl_GlobTypeData *types)); EXTERN int TclpChdir _ANSI_ARGS_((CONST char *dirName)); EXTERN char * TclpGetCwd _ANSI_ARGS_((Tcl_Interp *interp, Tcl_DString *bufferPtr)); EXTERN Tcl_Obj* TclpObjGetCwd _ANSI_ARGS_((Tcl_Interp *interp)); EXTERN Tcl_Obj* TclpObjReadlink _ANSI_ARGS_((Tcl_Obj *pathPtr)); EXTERN int TclpObjChdir _ANSI_ARGS_((Tcl_Obj *pathPtr)); EXTERN int TclpObjStat _ANSI_ARGS_((Tcl_Obj *pathPtr, struct stat *buf)); EXTERN Tcl_Channel TclpOpenFileChannel _ANSI_ARGS_((Tcl_Interp *interp, char *fileName, char *modeString, int permissions)); EXTERN void TclpPanic _ANSI_ARGS_(TCL_VARARGS(CONST char *, format)); EXTERN char * TclpReadlink _ANSI_ARGS_((CONST char *fileName, Tcl_DString *linkPtr)); |
| ︙ | ︙ | |||
1890 1891 1892 1893 1894 1895 1896 | EXTERN void TclSetupEnv _ANSI_ARGS_((Tcl_Interp *interp)); EXTERN VOID TclSignalExitThread _ANSI_ARGS_((Tcl_ThreadId id, int result)); EXTERN int TclSockGetPort _ANSI_ARGS_((Tcl_Interp *interp, char *string, char *proto, int *portPtr)); EXTERN int TclSockMinimumBuffers _ANSI_ARGS_((int sock, int size)); | < < > > | 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 |
EXTERN void TclSetupEnv _ANSI_ARGS_((Tcl_Interp *interp));
EXTERN VOID TclSignalExitThread _ANSI_ARGS_((Tcl_ThreadId id,
int result));
EXTERN int TclSockGetPort _ANSI_ARGS_((Tcl_Interp *interp,
char *string, char *proto, int *portPtr));
EXTERN int TclSockMinimumBuffers _ANSI_ARGS_((int sock,
int size));
EXTERN int TclStatDeleteProc _ANSI_ARGS_((TclStatProc_ *proc));
EXTERN int TclStatInsertProc _ANSI_ARGS_((TclStatProc_ *proc));
EXTERN void TclTeardownNamespace _ANSI_ARGS_((Namespace *nsPtr));
EXTERN void TclTransferResult _ANSI_ARGS_((Tcl_Interp *sourceInterp,
int result, Tcl_Interp *targetInterp));
EXTERN int TclUpdateReturnInfo _ANSI_ARGS_((Interp *iPtr));
EXTERN Tcl_Obj* TclpNativeToNormalized
_ANSI_ARGS_((ClientData clientData));
/*
*----------------------------------------------------------------
* Command procedures in the generic core:
*----------------------------------------------------------------
*/
|
| ︙ | ︙ |
Changes to generic/tclIntDecls.h.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* * tclIntDecls.h -- * * This file contains the declarations for all unsupported * functions that are exported by the Tcl library. These * interfaces are not guaranteed to remain the same between * versions. Use at your own risk. * * Copyright (c) 1998-1999 by Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* * tclIntDecls.h -- * * This file contains the declarations for all unsupported * functions that are exported by the Tcl library. These * interfaces are not guaranteed to remain the same between * versions. Use at your own risk. * * Copyright (c) 1998-1999 by Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclIntDecls.h,v 1.25 2001/07/31 19:12:06 vincentdarley Exp $ */ #ifndef _TCLINTDECLS #define _TCLINTDECLS /* * WARNING: This file is automatically generated by the tools/genStubs.tcl |
| ︙ | ︙ | |||
85 86 87 88 89 90 91 | Interp * iPtr, CallFrame * framePtr)); /* 12 */ EXTERN void TclDeleteVars _ANSI_ARGS_((Interp * iPtr, Tcl_HashTable * tablePtr)); /* 13 */ EXTERN int TclDoGlob _ANSI_ARGS_((Tcl_Interp * interp, char * separators, Tcl_DString * headPtr, | | | < < | < < | < < | < < | < < | 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | Interp * iPtr, CallFrame * framePtr)); /* 12 */ EXTERN void TclDeleteVars _ANSI_ARGS_((Interp * iPtr, Tcl_HashTable * tablePtr)); /* 13 */ EXTERN int TclDoGlob _ANSI_ARGS_((Tcl_Interp * interp, char * separators, Tcl_DString * headPtr, char * tail, Tcl_GlobTypeData * types)); /* 14 */ EXTERN void TclDumpMemoryInfo _ANSI_ARGS_((FILE * outFile)); /* Slot 15 is reserved */ /* 16 */ EXTERN void TclExprFloatError _ANSI_ARGS_((Tcl_Interp * interp, double value)); /* Slot 17 is reserved */ /* Slot 18 is reserved */ /* Slot 19 is reserved */ /* Slot 20 is reserved */ /* Slot 21 is reserved */ /* 22 */ EXTERN int TclFindElement _ANSI_ARGS_((Tcl_Interp * interp, CONST char * listStr, int listLength, CONST char ** elementPtr, CONST char ** nextPtr, int * sizePtr, int * bracePtr)); /* 23 */ |
| ︙ | ︙ | |||
219 220 221 222 223 224 225 | /* Slot 56 is reserved */ /* Slot 57 is reserved */ /* 58 */ EXTERN Var * TclLookupVar _ANSI_ARGS_((Tcl_Interp * interp, char * part1, char * part2, int flags, char * msg, int createPart1, int createPart2, Var ** arrayPtrPtr)); | | < < < | 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 | /* Slot 56 is reserved */ /* Slot 57 is reserved */ /* 58 */ EXTERN Var * TclLookupVar _ANSI_ARGS_((Tcl_Interp * interp, char * part1, char * part2, int flags, char * msg, int createPart1, int createPart2, Var ** arrayPtrPtr)); /* Slot 59 is reserved */ /* 60 */ EXTERN int TclNeedSpace _ANSI_ARGS_((char * start, char * end)); /* 61 */ EXTERN Tcl_Obj * TclNewProcBodyObj _ANSI_ARGS_((Proc * procPtr)); /* 62 */ EXTERN int TclObjCommandComplete _ANSI_ARGS_((Tcl_Obj * cmdPtr)); /* 63 */ |
| ︙ | ︙ | |||
249 250 251 252 253 254 255 | /* 67 */ EXTERN int TclOpenFileChannelInsertProc _ANSI_ARGS_(( TclOpenFileChannelProc_ * proc)); /* 68 */ EXTERN int TclpAccess _ANSI_ARGS_((CONST char * path, int mode)); /* 69 */ EXTERN char * TclpAlloc _ANSI_ARGS_((unsigned int size)); | | < < | < < | < | < | < < | < < | 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 | /* 67 */ EXTERN int TclOpenFileChannelInsertProc _ANSI_ARGS_(( TclOpenFileChannelProc_ * proc)); /* 68 */ EXTERN int TclpAccess _ANSI_ARGS_((CONST char * path, int mode)); /* 69 */ EXTERN char * TclpAlloc _ANSI_ARGS_((unsigned int size)); /* Slot 70 is reserved */ /* Slot 71 is reserved */ /* Slot 72 is reserved */ /* Slot 73 is reserved */ /* 74 */ EXTERN void TclpFree _ANSI_ARGS_((char * ptr)); /* 75 */ EXTERN unsigned long TclpGetClicks _ANSI_ARGS_((void)); /* 76 */ EXTERN unsigned long TclpGetSeconds _ANSI_ARGS_((void)); /* 77 */ EXTERN void TclpGetTime _ANSI_ARGS_((Tcl_Time * time)); /* 78 */ EXTERN int TclpGetTimeZone _ANSI_ARGS_((unsigned long time)); /* 79 */ EXTERN int TclpListVolumes _ANSI_ARGS_((Tcl_Interp * interp)); /* 80 */ EXTERN Tcl_Channel TclpOpenFileChannel _ANSI_ARGS_((Tcl_Interp * interp, char * fileName, char * modeString, int permissions)); /* 81 */ EXTERN char * TclpRealloc _ANSI_ARGS_((char * ptr, unsigned int size)); /* Slot 82 is reserved */ /* Slot 83 is reserved */ /* Slot 84 is reserved */ /* Slot 85 is reserved */ /* Slot 86 is reserved */ /* Slot 87 is reserved */ /* 88 */ EXTERN char * TclPrecTraceProc _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, char * name1, |
| ︙ | ︙ | |||
452 453 454 455 456 457 458 | EXTERN struct tm * TclpGetDate _ANSI_ARGS_((TclpTime_t time, int useGMT)); /* 134 */ EXTERN size_t TclpStrftime _ANSI_ARGS_((char * s, size_t maxsize, CONST char * format, CONST struct tm * t)); /* 135 */ EXTERN int TclpCheckStackSpace _ANSI_ARGS_((void)); /* Slot 136 is reserved */ | | < | < < | 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 | EXTERN struct tm * TclpGetDate _ANSI_ARGS_((TclpTime_t time, int useGMT)); /* 134 */ EXTERN size_t TclpStrftime _ANSI_ARGS_((char * s, size_t maxsize, CONST char * format, CONST struct tm * t)); /* 135 */ EXTERN int TclpCheckStackSpace _ANSI_ARGS_((void)); /* Slot 136 is reserved */ /* Slot 137 is reserved */ /* 138 */ EXTERN char * TclGetEnv _ANSI_ARGS_((CONST char * name, Tcl_DString * valuePtr)); /* 139 */ EXTERN int TclpLoadFile _ANSI_ARGS_((Tcl_Interp * interp, char * fileName, char * sym1, char * sym2, Tcl_PackageInitProc ** proc1Ptr, Tcl_PackageInitProc ** proc2Ptr, ClientData * clientDataPtr)); /* 140 */ EXTERN int TclLooksLikeInt _ANSI_ARGS_((char * bytes, int length)); /* Slot 141 is reserved */ /* 142 */ EXTERN int TclSetByteCodeFromAny _ANSI_ARGS_(( Tcl_Interp * interp, Tcl_Obj * objPtr, CompileHookProc * hookProc, ClientData clientData)); /* 143 */ EXTERN int TclAddLiteralObj _ANSI_ARGS_(( |
| ︙ | ︙ | |||
514 515 516 517 518 519 520 | EXTERN Var * TclVarTraceExists _ANSI_ARGS_((Tcl_Interp * interp, char * varName)); /* 158 */ EXTERN void TclSetStartupScriptFileName _ANSI_ARGS_(( char * filename)); /* 159 */ EXTERN char * TclGetStartupScriptFileName _ANSI_ARGS_((void)); | | < < < < > > > > > > > > > > > > > > > > > > > | 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 |
EXTERN Var * TclVarTraceExists _ANSI_ARGS_((Tcl_Interp * interp,
char * varName));
/* 158 */
EXTERN void TclSetStartupScriptFileName _ANSI_ARGS_((
char * filename));
/* 159 */
EXTERN char * TclGetStartupScriptFileName _ANSI_ARGS_((void));
/* Slot 160 is reserved */
/* 161 */
EXTERN int TclChannelTransform _ANSI_ARGS_((Tcl_Interp * interp,
Tcl_Channel chan, Tcl_Obj * cmdObjPtr));
/* 162 */
EXTERN void TclChannelEventScriptInvoker _ANSI_ARGS_((
ClientData clientData, int flags));
/* 163 */
EXTERN int TclFileCopyCmd _ANSI_ARGS_((Tcl_Interp * interp,
int objc, Tcl_Obj *CONST objv[]));
/* 164 */
EXTERN int TclFileRenameCmd _ANSI_ARGS_((Tcl_Interp * interp,
int objc, Tcl_Obj *CONST objv[]));
/* 165 */
EXTERN int TclFileDeleteCmd _ANSI_ARGS_((Tcl_Interp * interp,
int objc, Tcl_Obj *CONST objv[]));
/* 166 */
EXTERN int TclFileMakeDirsCmd _ANSI_ARGS_((Tcl_Interp * interp,
int objc, Tcl_Obj *CONST objv[]));
/* 167 */
EXTERN int TclFileAttrsCmd _ANSI_ARGS_((Tcl_Interp * interp,
int objc, Tcl_Obj *CONST objv[]));
/* 168 */
EXTERN Tcl_Obj* TclpTempFileName _ANSI_ARGS_((void));
/* 169 */
EXTERN void TclpSetInitialEncodings _ANSI_ARGS_((void));
typedef struct TclIntStubs {
int magic;
struct TclIntStubHooks *hooks;
int (*tclAccess) _ANSI_ARGS_((CONST char * path, int mode)); /* 0 */
int (*tclAccessDeleteProc) _ANSI_ARGS_((TclAccessProc_ * proc)); /* 1 */
|
| ︙ | ︙ | |||
559 560 561 562 563 564 565 |
#endif /* __WIN32__ */
#ifdef MAC_TCL
void *reserved9;
#endif /* MAC_TCL */
int (*tclCreateProc) _ANSI_ARGS_((Tcl_Interp * interp, Namespace * nsPtr, CONST char * procName, Tcl_Obj * argsPtr, Tcl_Obj * bodyPtr, Proc ** procPtrPtr)); /* 10 */
void (*tclDeleteCompiledLocalVars) _ANSI_ARGS_((Interp * iPtr, CallFrame * framePtr)); /* 11 */
void (*tclDeleteVars) _ANSI_ARGS_((Interp * iPtr, Tcl_HashTable * tablePtr)); /* 12 */
| | | | | | | | 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 |
#endif /* __WIN32__ */
#ifdef MAC_TCL
void *reserved9;
#endif /* MAC_TCL */
int (*tclCreateProc) _ANSI_ARGS_((Tcl_Interp * interp, Namespace * nsPtr, CONST char * procName, Tcl_Obj * argsPtr, Tcl_Obj * bodyPtr, Proc ** procPtrPtr)); /* 10 */
void (*tclDeleteCompiledLocalVars) _ANSI_ARGS_((Interp * iPtr, CallFrame * framePtr)); /* 11 */
void (*tclDeleteVars) _ANSI_ARGS_((Interp * iPtr, Tcl_HashTable * tablePtr)); /* 12 */
int (*tclDoGlob) _ANSI_ARGS_((Tcl_Interp * interp, char * separators, Tcl_DString * headPtr, char * tail, Tcl_GlobTypeData * types)); /* 13 */
void (*tclDumpMemoryInfo) _ANSI_ARGS_((FILE * outFile)); /* 14 */
void *reserved15;
void (*tclExprFloatError) _ANSI_ARGS_((Tcl_Interp * interp, double value)); /* 16 */
void *reserved17;
void *reserved18;
void *reserved19;
void *reserved20;
void *reserved21;
int (*tclFindElement) _ANSI_ARGS_((Tcl_Interp * interp, CONST char * listStr, int listLength, CONST char ** elementPtr, CONST char ** nextPtr, int * sizePtr, int * bracePtr)); /* 22 */
Proc * (*tclFindProc) _ANSI_ARGS_((Interp * iPtr, char * procName)); /* 23 */
int (*tclFormatInt) _ANSI_ARGS_((char * buffer, long n)); /* 24 */
void (*tclFreePackageInfo) _ANSI_ARGS_((Interp * iPtr)); /* 25 */
void *reserved26;
int (*tclGetDate) _ANSI_ARGS_((char * p, unsigned long now, long zone, unsigned long * timePtr)); /* 27 */
Tcl_Channel (*tclpGetDefaultStdChannel) _ANSI_ARGS_((int type)); /* 28 */
|
| ︙ | ︙ | |||
605 606 607 608 609 610 611 |
int (*tclInvoke) _ANSI_ARGS_((Tcl_Interp * interp, int argc, char ** argv, int flags)); /* 52 */
int (*tclInvokeObjectCommand) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char ** argv)); /* 53 */
int (*tclInvokeStringCommand) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 54 */
Proc * (*tclIsProc) _ANSI_ARGS_((Command * cmdPtr)); /* 55 */
void *reserved56;
void *reserved57;
Var * (*tclLookupVar) _ANSI_ARGS_((Tcl_Interp * interp, char * part1, char * part2, int flags, char * msg, int createPart1, int createPart2, Var ** arrayPtrPtr)); /* 58 */
| | | | | | | | | 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 |
int (*tclInvoke) _ANSI_ARGS_((Tcl_Interp * interp, int argc, char ** argv, int flags)); /* 52 */
int (*tclInvokeObjectCommand) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char ** argv)); /* 53 */
int (*tclInvokeStringCommand) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 54 */
Proc * (*tclIsProc) _ANSI_ARGS_((Command * cmdPtr)); /* 55 */
void *reserved56;
void *reserved57;
Var * (*tclLookupVar) _ANSI_ARGS_((Tcl_Interp * interp, char * part1, char * part2, int flags, char * msg, int createPart1, int createPart2, Var ** arrayPtrPtr)); /* 58 */
void *reserved59;
int (*tclNeedSpace) _ANSI_ARGS_((char * start, char * end)); /* 60 */
Tcl_Obj * (*tclNewProcBodyObj) _ANSI_ARGS_((Proc * procPtr)); /* 61 */
int (*tclObjCommandComplete) _ANSI_ARGS_((Tcl_Obj * cmdPtr)); /* 62 */
int (*tclObjInterpProc) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 63 */
int (*tclObjInvoke) _ANSI_ARGS_((Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[], int flags)); /* 64 */
int (*tclObjInvokeGlobal) _ANSI_ARGS_((Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[], int flags)); /* 65 */
int (*tclOpenFileChannelDeleteProc) _ANSI_ARGS_((TclOpenFileChannelProc_ * proc)); /* 66 */
int (*tclOpenFileChannelInsertProc) _ANSI_ARGS_((TclOpenFileChannelProc_ * proc)); /* 67 */
int (*tclpAccess) _ANSI_ARGS_((CONST char * path, int mode)); /* 68 */
char * (*tclpAlloc) _ANSI_ARGS_((unsigned int size)); /* 69 */
void *reserved70;
void *reserved71;
void *reserved72;
void *reserved73;
void (*tclpFree) _ANSI_ARGS_((char * ptr)); /* 74 */
unsigned long (*tclpGetClicks) _ANSI_ARGS_((void)); /* 75 */
unsigned long (*tclpGetSeconds) _ANSI_ARGS_((void)); /* 76 */
void (*tclpGetTime) _ANSI_ARGS_((Tcl_Time * time)); /* 77 */
int (*tclpGetTimeZone) _ANSI_ARGS_((unsigned long time)); /* 78 */
int (*tclpListVolumes) _ANSI_ARGS_((Tcl_Interp * interp)); /* 79 */
Tcl_Channel (*tclpOpenFileChannel) _ANSI_ARGS_((Tcl_Interp * interp, char * fileName, char * modeString, int permissions)); /* 80 */
char * (*tclpRealloc) _ANSI_ARGS_((char * ptr, unsigned int size)); /* 81 */
void *reserved82;
void *reserved83;
void *reserved84;
void *reserved85;
void *reserved86;
void *reserved87;
char * (*tclPrecTraceProc) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, char * name1, char * name2, int flags)); /* 88 */
int (*tclPreventAliasLoop) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Interp * cmdInterp, Tcl_Command cmd)); /* 89 */
void *reserved90;
|
| ︙ | ︙ | |||
699 700 701 702 703 704 705 |
int (*tcl_RemoveInterpResolvers) _ANSI_ARGS_((Tcl_Interp * interp, char * name)); /* 130 */
void (*tcl_SetNamespaceResolvers) _ANSI_ARGS_((Tcl_Namespace * namespacePtr, Tcl_ResolveCmdProc * cmdProc, Tcl_ResolveVarProc * varProc, Tcl_ResolveCompiledVarProc * compiledVarProc)); /* 131 */
int (*tclpHasSockets) _ANSI_ARGS_((Tcl_Interp * interp)); /* 132 */
struct tm * (*tclpGetDate) _ANSI_ARGS_((TclpTime_t time, int useGMT)); /* 133 */
size_t (*tclpStrftime) _ANSI_ARGS_((char * s, size_t maxsize, CONST char * format, CONST struct tm * t)); /* 134 */
int (*tclpCheckStackSpace) _ANSI_ARGS_((void)); /* 135 */
void *reserved136;
| | | | > > > > > > > | 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 |
int (*tcl_RemoveInterpResolvers) _ANSI_ARGS_((Tcl_Interp * interp, char * name)); /* 130 */
void (*tcl_SetNamespaceResolvers) _ANSI_ARGS_((Tcl_Namespace * namespacePtr, Tcl_ResolveCmdProc * cmdProc, Tcl_ResolveVarProc * varProc, Tcl_ResolveCompiledVarProc * compiledVarProc)); /* 131 */
int (*tclpHasSockets) _ANSI_ARGS_((Tcl_Interp * interp)); /* 132 */
struct tm * (*tclpGetDate) _ANSI_ARGS_((TclpTime_t time, int useGMT)); /* 133 */
size_t (*tclpStrftime) _ANSI_ARGS_((char * s, size_t maxsize, CONST char * format, CONST struct tm * t)); /* 134 */
int (*tclpCheckStackSpace) _ANSI_ARGS_((void)); /* 135 */
void *reserved136;
void *reserved137;
char * (*tclGetEnv) _ANSI_ARGS_((CONST char * name, Tcl_DString * valuePtr)); /* 138 */
int (*tclpLoadFile) _ANSI_ARGS_((Tcl_Interp * interp, char * fileName, char * sym1, char * sym2, Tcl_PackageInitProc ** proc1Ptr, Tcl_PackageInitProc ** proc2Ptr, ClientData * clientDataPtr)); /* 139 */
int (*tclLooksLikeInt) _ANSI_ARGS_((char * bytes, int length)); /* 140 */
void *reserved141;
int (*tclSetByteCodeFromAny) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * objPtr, CompileHookProc * hookProc, ClientData clientData)); /* 142 */
int (*tclAddLiteralObj) _ANSI_ARGS_((struct CompileEnv * envPtr, Tcl_Obj * objPtr, LiteralEntry ** litPtrPtr)); /* 143 */
void (*tclHideLiteral) _ANSI_ARGS_((Tcl_Interp * interp, struct CompileEnv * envPtr, int index)); /* 144 */
struct AuxDataType * (*tclGetAuxDataType) _ANSI_ARGS_((char * typeName)); /* 145 */
TclHandle (*tclHandleCreate) _ANSI_ARGS_((VOID * ptr)); /* 146 */
void (*tclHandleFree) _ANSI_ARGS_((TclHandle handle)); /* 147 */
TclHandle (*tclHandlePreserve) _ANSI_ARGS_((TclHandle handle)); /* 148 */
void (*tclHandleRelease) _ANSI_ARGS_((TclHandle handle)); /* 149 */
int (*tclRegAbout) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_RegExp re)); /* 150 */
void (*tclRegExpRangeUniChar) _ANSI_ARGS_((Tcl_RegExp re, int index, int * startPtr, int * endPtr)); /* 151 */
void (*tclSetLibraryPath) _ANSI_ARGS_((Tcl_Obj * pathPtr)); /* 152 */
Tcl_Obj * (*tclGetLibraryPath) _ANSI_ARGS_((void)); /* 153 */
void *reserved154;
void *reserved155;
void (*tclRegError) _ANSI_ARGS_((Tcl_Interp * interp, char * msg, int status)); /* 156 */
Var * (*tclVarTraceExists) _ANSI_ARGS_((Tcl_Interp * interp, char * varName)); /* 157 */
void (*tclSetStartupScriptFileName) _ANSI_ARGS_((char * filename)); /* 158 */
char * (*tclGetStartupScriptFileName) _ANSI_ARGS_((void)); /* 159 */
void *reserved160;
int (*tclChannelTransform) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Channel chan, Tcl_Obj * cmdObjPtr)); /* 161 */
void (*tclChannelEventScriptInvoker) _ANSI_ARGS_((ClientData clientData, int flags)); /* 162 */
int (*tclFileCopyCmd) _ANSI_ARGS_((Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 163 */
int (*tclFileRenameCmd) _ANSI_ARGS_((Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 164 */
int (*tclFileDeleteCmd) _ANSI_ARGS_((Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 165 */
int (*tclFileMakeDirsCmd) _ANSI_ARGS_((Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 166 */
int (*tclFileAttrsCmd) _ANSI_ARGS_((Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 167 */
Tcl_Obj* (*tclpTempFileName) _ANSI_ARGS_((void)); /* 168 */
void (*tclpSetInitialEncodings) _ANSI_ARGS_((void)); /* 169 */
} TclIntStubs;
#ifdef __cplusplus
extern "C" {
#endif
extern TclIntStubs *tclIntStubsPtr;
#ifdef __cplusplus
|
| ︙ | ︙ | |||
819 820 821 822 823 824 825 | (tclIntStubsPtr->tclDumpMemoryInfo) /* 14 */ #endif /* Slot 15 is reserved */ #ifndef TclExprFloatError #define TclExprFloatError \ (tclIntStubsPtr->tclExprFloatError) /* 16 */ #endif | | | | | | < < < < < < < < < < < < < < < | 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 | (tclIntStubsPtr->tclDumpMemoryInfo) /* 14 */ #endif /* Slot 15 is reserved */ #ifndef TclExprFloatError #define TclExprFloatError \ (tclIntStubsPtr->tclExprFloatError) /* 16 */ #endif /* Slot 17 is reserved */ /* Slot 18 is reserved */ /* Slot 19 is reserved */ /* Slot 20 is reserved */ /* Slot 21 is reserved */ #ifndef TclFindElement #define TclFindElement \ (tclIntStubsPtr->tclFindElement) /* 22 */ #endif #ifndef TclFindProc #define TclFindProc \ (tclIntStubsPtr->tclFindProc) /* 23 */ |
| ︙ | ︙ | |||
975 976 977 978 979 980 981 | #endif /* Slot 56 is reserved */ /* Slot 57 is reserved */ #ifndef TclLookupVar #define TclLookupVar \ (tclIntStubsPtr->tclLookupVar) /* 58 */ #endif | | < < < | 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 | #endif /* Slot 56 is reserved */ /* Slot 57 is reserved */ #ifndef TclLookupVar #define TclLookupVar \ (tclIntStubsPtr->tclLookupVar) /* 58 */ #endif /* Slot 59 is reserved */ #ifndef TclNeedSpace #define TclNeedSpace \ (tclIntStubsPtr->tclNeedSpace) /* 60 */ #endif #ifndef TclNewProcBodyObj #define TclNewProcBodyObj \ (tclIntStubsPtr->tclNewProcBodyObj) /* 61 */ |
| ︙ | ︙ | |||
1019 1020 1021 1022 1023 1024 1025 | #define TclpAccess \ (tclIntStubsPtr->tclpAccess) /* 68 */ #endif #ifndef TclpAlloc #define TclpAlloc \ (tclIntStubsPtr->tclpAlloc) /* 69 */ #endif | | | | | < < < < < < < < < < < < | 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 | #define TclpAccess \ (tclIntStubsPtr->tclpAccess) /* 68 */ #endif #ifndef TclpAlloc #define TclpAlloc \ (tclIntStubsPtr->tclpAlloc) /* 69 */ #endif /* Slot 70 is reserved */ /* Slot 71 is reserved */ /* Slot 72 is reserved */ /* Slot 73 is reserved */ #ifndef TclpFree #define TclpFree \ (tclIntStubsPtr->tclpFree) /* 74 */ #endif #ifndef TclpGetClicks #define TclpGetClicks \ (tclIntStubsPtr->tclpGetClicks) /* 75 */ |
| ︙ | ︙ | |||
1067 1068 1069 1070 1071 1072 1073 | #define TclpOpenFileChannel \ (tclIntStubsPtr->tclpOpenFileChannel) /* 80 */ #endif #ifndef TclpRealloc #define TclpRealloc \ (tclIntStubsPtr->tclpRealloc) /* 81 */ #endif | | | < < < < < < | 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 | #define TclpOpenFileChannel \ (tclIntStubsPtr->tclpOpenFileChannel) /* 80 */ #endif #ifndef TclpRealloc #define TclpRealloc \ (tclIntStubsPtr->tclpRealloc) /* 81 */ #endif /* Slot 82 is reserved */ /* Slot 83 is reserved */ /* Slot 84 is reserved */ /* Slot 85 is reserved */ /* Slot 86 is reserved */ /* Slot 87 is reserved */ #ifndef TclPrecTraceProc #define TclPrecTraceProc \ (tclIntStubsPtr->tclPrecTraceProc) /* 88 */ |
| ︙ | ︙ | |||
1282 1283 1284 1285 1286 1287 1288 | (tclIntStubsPtr->tclpStrftime) /* 134 */ #endif #ifndef TclpCheckStackSpace #define TclpCheckStackSpace \ (tclIntStubsPtr->tclpCheckStackSpace) /* 135 */ #endif /* Slot 136 is reserved */ | < < | < < < | < | 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 | (tclIntStubsPtr->tclpStrftime) /* 134 */ #endif #ifndef TclpCheckStackSpace #define TclpCheckStackSpace \ (tclIntStubsPtr->tclpCheckStackSpace) /* 135 */ #endif /* Slot 136 is reserved */ /* Slot 137 is reserved */ #ifndef TclGetEnv #define TclGetEnv \ (tclIntStubsPtr->tclGetEnv) /* 138 */ #endif #ifndef TclpLoadFile #define TclpLoadFile \ (tclIntStubsPtr->tclpLoadFile) /* 139 */ #endif #ifndef TclLooksLikeInt #define TclLooksLikeInt \ (tclIntStubsPtr->tclLooksLikeInt) /* 140 */ #endif /* Slot 141 is reserved */ #ifndef TclSetByteCodeFromAny #define TclSetByteCodeFromAny \ (tclIntStubsPtr->tclSetByteCodeFromAny) /* 142 */ #endif #ifndef TclAddLiteralObj #define TclAddLiteralObj \ (tclIntStubsPtr->tclAddLiteralObj) /* 143 */ |
| ︙ | ︙ | |||
1368 1369 1370 1371 1372 1373 1374 | #define TclSetStartupScriptFileName \ (tclIntStubsPtr->tclSetStartupScriptFileName) /* 158 */ #endif #ifndef TclGetStartupScriptFileName #define TclGetStartupScriptFileName \ (tclIntStubsPtr->tclGetStartupScriptFileName) /* 159 */ #endif | < < | < > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 | #define TclSetStartupScriptFileName \ (tclIntStubsPtr->tclSetStartupScriptFileName) /* 158 */ #endif #ifndef TclGetStartupScriptFileName #define TclGetStartupScriptFileName \ (tclIntStubsPtr->tclGetStartupScriptFileName) /* 159 */ #endif /* Slot 160 is reserved */ #ifndef TclChannelTransform #define TclChannelTransform \ (tclIntStubsPtr->tclChannelTransform) /* 161 */ #endif #ifndef TclChannelEventScriptInvoker #define TclChannelEventScriptInvoker \ (tclIntStubsPtr->tclChannelEventScriptInvoker) /* 162 */ #endif #ifndef TclFileCopyCmd #define TclFileCopyCmd \ (tclIntStubsPtr->tclFileCopyCmd) /* 163 */ #endif #ifndef TclFileRenameCmd #define TclFileRenameCmd \ (tclIntStubsPtr->tclFileRenameCmd) /* 164 */ #endif #ifndef TclFileDeleteCmd #define TclFileDeleteCmd \ (tclIntStubsPtr->tclFileDeleteCmd) /* 165 */ #endif #ifndef TclFileMakeDirsCmd #define TclFileMakeDirsCmd \ (tclIntStubsPtr->tclFileMakeDirsCmd) /* 166 */ #endif #ifndef TclFileAttrsCmd #define TclFileAttrsCmd \ (tclIntStubsPtr->tclFileAttrsCmd) /* 167 */ #endif #ifndef TclpTempFileName #define TclpTempFileName \ (tclIntStubsPtr->tclpTempFileName) /* 168 */ #endif #ifndef TclpSetInitialEncodings #define TclpSetInitialEncodings \ (tclIntStubsPtr->tclpSetInitialEncodings) /* 169 */ #endif #endif /* defined(USE_TCL_STUBS) && !defined(USE_TCL_STUB_PROCS) */ /* !END!: Do not edit above this line. */ #endif /* _TCLINTDECLS */ |
Changes to generic/tclLoad.c.
1 2 3 4 5 6 7 8 9 10 11 | /* * tclLoad.c -- * * This file provides the generic portion (those that are the same * on all platforms) of Tcl's dynamic loading facilities. * * Copyright (c) 1995-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | > | > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
/*
* tclLoad.c --
*
* This file provides the generic portion (those that are the same
* on all platforms) of Tcl's dynamic loading facilities.
*
* Copyright (c) 1995-1997 Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* RCS: @(#) $Id: tclLoad.c,v 1.5 2001/07/31 19:12:06 vincentdarley Exp $
*/
#include "tclInt.h"
/*
* The following structure describes a package that has been loaded
* either dynamically (with the "load" command) or statically (as
* indicated by a call to TclGetLoadedPackages). All such packages
* are linked together into a single list for the process. Packages
* are never unloaded, until the application exits, when
* TclFinalizeLoad is called, and these structures are freed.
*/
typedef struct LoadedPackage {
char *fileName; /* Name of the file from which the
* package was loaded. An empty string
* means the package is loaded statically.
* Malloc-ed. */
char *packageName; /* Name of package prefix for the package,
* properly capitalized (first letter UC,
* others LC), no "_", as in "Net".
* Malloc-ed. */
ClientData clientData; /* Token for the loaded file which should be
* passed to (*unLoadProcPtr)() when the file
* is no longer needed. If fileName is NULL,
* then this field is irrelevant. */
Tcl_PackageInitProc *initProc;
/* Initialization procedure to call to
* incorporate this package into a trusted
* interpreter. */
Tcl_PackageInitProc *safeInitProc;
/* Initialization procedure to call to
* incorporate this package into a safe
* interpreter (one that will execute
* untrusted scripts). NULL means the
* package can't be used in unsafe
* interpreters. */
Tcl_FSUnloadFileProc *unLoadProcPtr;
/* Procedure to use to unload this package.
* If NULL, then we do not attempt to unload
* the package. If fileName is NULL, then
* this field is irrelevant. */
struct LoadedPackage *nextPtr;
/* Next in list of all packages loaded into
* this application process. NULL means
* end of list. */
} LoadedPackage;
/*
|
| ︙ | ︙ | |||
109 110 111 112 113 114 115 |
ClientData dummy; /* Not used. */
Tcl_Interp *interp; /* Current interpreter. */
int objc; /* Number of arguments. */
Tcl_Obj *CONST objv[]; /* Argument objects. */
{
Tcl_Interp *target;
LoadedPackage *pkgPtr, *defaultPtr;
| | | > | < < > > | 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
ClientData dummy; /* Not used. */
Tcl_Interp *interp; /* Current interpreter. */
int objc; /* Number of arguments. */
Tcl_Obj *CONST objv[]; /* Argument objects. */
{
Tcl_Interp *target;
LoadedPackage *pkgPtr, *defaultPtr;
Tcl_DString pkgName, tmp, initName, safeInitName;
Tcl_PackageInitProc *initProc, *safeInitProc;
InterpPackage *ipFirstPtr, *ipPtr;
int code, namesMatch, filesMatch;
char *p, *fullFileName, *packageName;
ClientData clientData;
Tcl_FSUnloadFileProc *unLoadProcPtr = NULL;
Tcl_UniChar ch;
int offset;
if ((objc < 2) || (objc > 4)) {
Tcl_WrongNumArgs(interp, 1, objv, "fileName ?packageName? ?interp?");
return TCL_ERROR;
}
if (Tcl_FSConvertToPathType(interp, objv[1]) != TCL_OK) {
return TCL_ERROR;
}
fullFileName = Tcl_GetString(objv[1]);
Tcl_DStringInit(&pkgName);
Tcl_DStringInit(&initName);
Tcl_DStringInit(&safeInitName);
Tcl_DStringInit(&tmp);
packageName = NULL;
if (objc >= 3) {
|
| ︙ | ︙ | |||
324 325 326 327 328 329 330 | /* * Call platform-specific code to load the package and find the * two initialization procedures. */ Tcl_MutexLock(&packageMutex); | | | > | > > | 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 |
/*
* Call platform-specific code to load the package and find the
* two initialization procedures.
*/
Tcl_MutexLock(&packageMutex);
code = Tcl_FSLoadFile(interp, objv[1], Tcl_DStringValue(&initName),
Tcl_DStringValue(&safeInitName), &initProc, &safeInitProc,
&clientData,&unLoadProcPtr);
Tcl_MutexUnlock(&packageMutex);
if (code != TCL_OK) {
goto done;
}
if (initProc == NULL) {
Tcl_AppendResult(interp, "couldn't find procedure ",
Tcl_DStringValue(&initName), (char *) NULL);
if (unLoadProcPtr != NULL) {
(*unLoadProcPtr)(clientData);
}
code = TCL_ERROR;
goto done;
}
/*
* Create a new record to describe this package.
*/
pkgPtr = (LoadedPackage *) ckalloc(sizeof(LoadedPackage));
pkgPtr->fileName = (char *) ckalloc((unsigned)
(strlen(fullFileName) + 1));
strcpy(pkgPtr->fileName, fullFileName);
pkgPtr->packageName = (char *) ckalloc((unsigned)
(Tcl_DStringLength(&pkgName) + 1));
strcpy(pkgPtr->packageName, Tcl_DStringValue(&pkgName));
pkgPtr->clientData = clientData;
pkgPtr->unLoadProcPtr = unLoadProcPtr;
pkgPtr->initProc = initProc;
pkgPtr->safeInitProc = safeInitProc;
Tcl_MutexLock(&packageMutex);
pkgPtr->nextPtr = firstPackagePtr;
firstPackagePtr = pkgPtr;
Tcl_MutexUnlock(&packageMutex);
}
|
| ︙ | ︙ | |||
406 407 408 409 410 411 412 |
TclTransferResult(target, code, interp);
}
done:
Tcl_DStringFree(&pkgName);
Tcl_DStringFree(&initName);
Tcl_DStringFree(&safeInitName);
| < | 416 417 418 419 420 421 422 423 424 425 426 427 428 429 |
TclTransferResult(target, code, interp);
}
done:
Tcl_DStringFree(&pkgName);
Tcl_DStringFree(&initName);
Tcl_DStringFree(&safeInitName);
Tcl_DStringFree(&tmp);
return code;
}
/*
*----------------------------------------------------------------------
*
|
| ︙ | ︙ | |||
649 650 651 652 653 654 655 |
/*
* Some Unix dlls are poorly behaved - registering things like
* atexit calls that can't be unregistered. If you unload
* such dlls, you get a core on exit because it wants to
* call a function in the dll after it's been unloaded.
*/
if (pkgPtr->fileName[0] != '\0') {
| > > | > | 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 |
/*
* Some Unix dlls are poorly behaved - registering things like
* atexit calls that can't be unregistered. If you unload
* such dlls, you get a core on exit because it wants to
* call a function in the dll after it's been unloaded.
*/
if (pkgPtr->fileName[0] != '\0') {
Tcl_FSUnloadFileProc *unLoadProcPtr = pkgPtr->unLoadProcPtr;
if (unLoadProcPtr != NULL) {
(*unLoadProcPtr)(pkgPtr->clientData);
}
}
#endif
ckfree(pkgPtr->fileName);
ckfree(pkgPtr->packageName);
ckfree((char *) pkgPtr);
}
}
|
Changes to generic/tclStubInit.c.
1 2 3 4 5 6 7 8 9 10 | /* * tclStubInit.c -- * * This file contains the initializers for the Tcl stub vectors. * * Copyright (c) 1998-1999 by Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | /* * tclStubInit.c -- * * This file contains the initializers for the Tcl stub vectors. * * Copyright (c) 1998-1999 by Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclStubInit.c,v 1.54 2001/07/31 19:12:06 vincentdarley Exp $ */ #include "tclInt.h" #include "tclPort.h" /* * Remove macros that will interfere with the definitions below. |
| ︙ | ︙ | |||
76 77 78 79 80 81 82 |
TclCreateProc, /* 10 */
TclDeleteCompiledLocalVars, /* 11 */
TclDeleteVars, /* 12 */
TclDoGlob, /* 13 */
TclDumpMemoryInfo, /* 14 */
NULL, /* 15 */
TclExprFloatError, /* 16 */
| | | | | | | 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
TclCreateProc, /* 10 */
TclDeleteCompiledLocalVars, /* 11 */
TclDeleteVars, /* 12 */
TclDoGlob, /* 13 */
TclDumpMemoryInfo, /* 14 */
NULL, /* 15 */
TclExprFloatError, /* 16 */
NULL, /* 17 */
NULL, /* 18 */
NULL, /* 19 */
NULL, /* 20 */
NULL, /* 21 */
TclFindElement, /* 22 */
TclFindProc, /* 23 */
TclFormatInt, /* 24 */
TclFreePackageInfo, /* 25 */
NULL, /* 26 */
TclGetDate, /* 27 */
TclpGetDefaultStdChannel, /* 28 */
|
| ︙ | ︙ | |||
118 119 120 121 122 123 124 |
TclInvoke, /* 52 */
TclInvokeObjectCommand, /* 53 */
TclInvokeStringCommand, /* 54 */
TclIsProc, /* 55 */
NULL, /* 56 */
NULL, /* 57 */
TclLookupVar, /* 58 */
| | | | | | | | | 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
TclInvoke, /* 52 */
TclInvokeObjectCommand, /* 53 */
TclInvokeStringCommand, /* 54 */
TclIsProc, /* 55 */
NULL, /* 56 */
NULL, /* 57 */
TclLookupVar, /* 58 */
NULL, /* 59 */
TclNeedSpace, /* 60 */
TclNewProcBodyObj, /* 61 */
TclObjCommandComplete, /* 62 */
TclObjInterpProc, /* 63 */
TclObjInvoke, /* 64 */
TclObjInvokeGlobal, /* 65 */
TclOpenFileChannelDeleteProc, /* 66 */
TclOpenFileChannelInsertProc, /* 67 */
TclpAccess, /* 68 */
TclpAlloc, /* 69 */
NULL, /* 70 */
NULL, /* 71 */
NULL, /* 72 */
NULL, /* 73 */
TclpFree, /* 74 */
TclpGetClicks, /* 75 */
TclpGetSeconds, /* 76 */
TclpGetTime, /* 77 */
TclpGetTimeZone, /* 78 */
TclpListVolumes, /* 79 */
TclpOpenFileChannel, /* 80 */
TclpRealloc, /* 81 */
NULL, /* 82 */
NULL, /* 83 */
NULL, /* 84 */
NULL, /* 85 */
NULL, /* 86 */
NULL, /* 87 */
TclPrecTraceProc, /* 88 */
TclPreventAliasLoop, /* 89 */
NULL, /* 90 */
|
| ︙ | ︙ | |||
212 213 214 215 216 217 218 |
Tcl_RemoveInterpResolvers, /* 130 */
Tcl_SetNamespaceResolvers, /* 131 */
TclpHasSockets, /* 132 */
TclpGetDate, /* 133 */
TclpStrftime, /* 134 */
TclpCheckStackSpace, /* 135 */
NULL, /* 136 */
| | | | > > > > > > > | 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 |
Tcl_RemoveInterpResolvers, /* 130 */
Tcl_SetNamespaceResolvers, /* 131 */
TclpHasSockets, /* 132 */
TclpGetDate, /* 133 */
TclpStrftime, /* 134 */
TclpCheckStackSpace, /* 135 */
NULL, /* 136 */
NULL, /* 137 */
TclGetEnv, /* 138 */
TclpLoadFile, /* 139 */
TclLooksLikeInt, /* 140 */
NULL, /* 141 */
TclSetByteCodeFromAny, /* 142 */
TclAddLiteralObj, /* 143 */
TclHideLiteral, /* 144 */
TclGetAuxDataType, /* 145 */
TclHandleCreate, /* 146 */
TclHandleFree, /* 147 */
TclHandlePreserve, /* 148 */
TclHandleRelease, /* 149 */
TclRegAbout, /* 150 */
TclRegExpRangeUniChar, /* 151 */
TclSetLibraryPath, /* 152 */
TclGetLibraryPath, /* 153 */
NULL, /* 154 */
NULL, /* 155 */
TclRegError, /* 156 */
TclVarTraceExists, /* 157 */
TclSetStartupScriptFileName, /* 158 */
TclGetStartupScriptFileName, /* 159 */
NULL, /* 160 */
TclChannelTransform, /* 161 */
TclChannelEventScriptInvoker, /* 162 */
TclFileCopyCmd, /* 163 */
TclFileRenameCmd, /* 164 */
TclFileDeleteCmd, /* 165 */
TclFileMakeDirsCmd, /* 166 */
TclFileAttrsCmd, /* 167 */
TclpTempFileName, /* 168 */
TclpSetInitialEncodings, /* 169 */
};
TclIntPlatStubs tclIntPlatStubs = {
TCL_STUB_MAGIC,
NULL,
#if !defined(__WIN32__) && !defined(MAC_TCL) /* UNIX */
TclGetAndDetachPids, /* 0 */
|
| ︙ | ︙ | |||
829 830 831 832 833 834 835 836 837 838 |
Tcl_AttemptDbCkrealloc, /* 431 */
Tcl_AttemptSetObjLength, /* 432 */
Tcl_GetChannelThread, /* 433 */
Tcl_GetUnicodeFromObj, /* 434 */
Tcl_GetMathFuncInfo, /* 435 */
Tcl_ListMathFuncs, /* 436 */
Tcl_SubstObj, /* 437 */
};
/* !END!: Do not edit above this line. */
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 |
Tcl_AttemptDbCkrealloc, /* 431 */
Tcl_AttemptSetObjLength, /* 432 */
Tcl_GetChannelThread, /* 433 */
Tcl_GetUnicodeFromObj, /* 434 */
Tcl_GetMathFuncInfo, /* 435 */
Tcl_ListMathFuncs, /* 436 */
Tcl_SubstObj, /* 437 */
Tcl_DetachChannel, /* 438 */
Tcl_IsStandardChannel, /* 439 */
Tcl_FSCopyFile, /* 440 */
Tcl_FSCopyDirectory, /* 441 */
Tcl_FSCreateDirectory, /* 442 */
Tcl_FSDeleteFile, /* 443 */
Tcl_FSLoadFile, /* 444 */
Tcl_FSMatchInDirectory, /* 445 */
Tcl_FSReadlink, /* 446 */
Tcl_FSRemoveDirectory, /* 447 */
Tcl_FSRenameFile, /* 448 */
Tcl_FSLstat, /* 449 */
Tcl_FSUtime, /* 450 */
Tcl_FSFileAttrsGet, /* 451 */
Tcl_FSFileAttrsSet, /* 452 */
Tcl_FSFileAttrStrings, /* 453 */
Tcl_FSStat, /* 454 */
Tcl_FSAccess, /* 455 */
Tcl_FSOpenFileChannel, /* 456 */
Tcl_FSGetCwd, /* 457 */
Tcl_FSChdir, /* 458 */
Tcl_FSConvertToPathType, /* 459 */
Tcl_FSJoinPath, /* 460 */
Tcl_FSSplitPath, /* 461 */
Tcl_FSEqualPaths, /* 462 */
Tcl_FSGetNormalizedPath, /* 463 */
Tcl_FSJoinToPath, /* 464 */
Tcl_FSGetInternalRep, /* 465 */
Tcl_FSGetTranslatedPath, /* 466 */
Tcl_FSEvalFile, /* 467 */
Tcl_FSNewNativePath, /* 468 */
Tcl_FSGetNativePath, /* 469 */
Tcl_FSFileSystemInfo, /* 470 */
Tcl_FSPathSeparator, /* 471 */
Tcl_FSListVolumes, /* 472 */
Tcl_FSRegister, /* 473 */
Tcl_FSUnregister, /* 474 */
Tcl_FSData, /* 475 */
};
/* !END!: Do not edit above this line. */
|
Changes to generic/tclTest.c.
| ︙ | ︙ | |||
9 10 11 12 13 14 15 | * Copyright (c) 1993-1994 The Regents of the University of California. * Copyright (c) 1994-1997 Sun Microsystems, Inc. * Copyright (c) 1998-2000 Ajuba Solutions. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | * Copyright (c) 1993-1994 The Regents of the University of California. * Copyright (c) 1994-1997 Sun Microsystems, Inc. * Copyright (c) 1998-2000 Ajuba Solutions. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclTest.c,v 1.26 2001/07/31 19:12:06 vincentdarley Exp $ */ #define TCL_TEST #include "tclInt.h" #include "tclPort.h" |
| ︙ | ︙ | |||
297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 | static int TestGetIndexFromObjStructObjCmd _ANSI_ARGS_(( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); static int TestChannelCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv)); static int TestChannelEventCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv)); /* * External (platform specific) initialization routine, these declarations * explicitly don't use EXTERN since this code does not get compiled * into the library: */ extern int TclplatformtestInit _ANSI_ARGS_((Tcl_Interp *interp)); | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 |
static int TestGetIndexFromObjStructObjCmd _ANSI_ARGS_((
ClientData clientData, Tcl_Interp *interp,
int objc, Tcl_Obj *CONST objv[]));
static int TestChannelCmd _ANSI_ARGS_((ClientData clientData,
Tcl_Interp *interp, int argc, char **argv));
static int TestChannelEventCmd _ANSI_ARGS_((ClientData clientData,
Tcl_Interp *interp, int argc, char **argv));
/* Filesystem testing */
static int TestFilesystemObjCmd _ANSI_ARGS_((ClientData dummy,
Tcl_Interp *interp, int objc,
Tcl_Obj *CONST objv[]));
static void TestReport _ANSI_ARGS_((CONST char* cmd, Tcl_Obj* arg1, Tcl_Obj* arg2));
static Tcl_FSStatProc TestReportStat;
static Tcl_FSAccessProc TestReportAccess;
static Tcl_FSOpenFileChannelProc TestReportOpenFileChannel;
static Tcl_FSMatchInDirectoryProc TestReportMatchInDirectory;
static Tcl_FSGetCwdProc TestReportGetCwd;
static Tcl_FSChdirProc TestReportChdir;
static Tcl_FSLstatProc TestReportLstat;
static Tcl_FSCopyFileProc TestReportCopyFile;
static Tcl_FSDeleteFileProc TestReportDeleteFile;
static Tcl_FSRenameFileProc TestReportRenameFile;
static Tcl_FSCreateDirectoryProc TestReportCreateDirectory;
static Tcl_FSCopyDirectoryProc TestReportCopyDirectory;
static Tcl_FSRemoveDirectoryProc TestReportRemoveDirectory;
static Tcl_FSLoadFileProc TestReportLoadFile;
static Tcl_FSUnloadFileProc TestReportUnloadFile;
static Tcl_FSReadlinkProc TestReportReadlink;
static Tcl_FSListVolumesProc TestReportListVolumes;
static Tcl_FSFileAttrStringsProc TestReportFileAttrStrings;
static Tcl_FSFileAttrsGetProc TestReportFileAttrsGet;
static Tcl_FSFileAttrsSetProc TestReportFileAttrsSet;
static Tcl_FSUtimeProc TestReportUtime;
static Tcl_FSNormalizePathProc TestReportNormalizePath;
static Tcl_Filesystem testReportingFilesystem = {
"reporting",
sizeof(Tcl_Filesystem),
TCL_FILESYSTEM_VERSION_1,
NULL, /* path in */
NULL, /* native dup */
NULL, /* native free */
NULL, /* native to norm */
NULL, /* convert to native */
&TestReportNormalizePath,
NULL, /* path type */
NULL, /* separator */
&TestReportStat,
&TestReportAccess,
&TestReportOpenFileChannel,
&TestReportMatchInDirectory,
&TestReportUtime,
&TestReportReadlink,
&TestReportListVolumes,
&TestReportFileAttrStrings,
&TestReportFileAttrsGet,
&TestReportFileAttrsSet,
&TestReportCreateDirectory,
&TestReportRemoveDirectory,
&TestReportDeleteFile,
&TestReportLstat,
&TestReportCopyFile,
&TestReportRenameFile,
&TestReportCopyDirectory,
&TestReportLoadFile,
&TestReportUnloadFile,
&TestReportGetCwd,
&TestReportChdir
};
/*
* External (platform specific) initialization routine, these declarations
* explicitly don't use EXTERN since this code does not get compiled
* into the library:
*/
extern int TclplatformtestInit _ANSI_ARGS_((Tcl_Interp *interp));
|
| ︙ | ︙ | |||
347 348 349 350 351 352 353 354 355 356 357 358 359 360 |
Tcl_CreateCommand(interp, "gettimes", GetTimesCmd, (ClientData) 0,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateCommand(interp, "noop", NoopCmd, (ClientData) 0,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "noop", NoopObjCmd, (ClientData) 0,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "testwrongnumargs", TestWrongNumArgsObjCmd,
(ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "testgetindexfromobjstruct",
TestGetIndexFromObjStructObjCmd, (ClientData) 0,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateCommand(interp, "testaccessproc", TestaccessprocCmd, (ClientData) 0,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateCommand(interp, "testasync", TestasyncCmd, (ClientData) 0,
| > > | 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 |
Tcl_CreateCommand(interp, "gettimes", GetTimesCmd, (ClientData) 0,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateCommand(interp, "noop", NoopCmd, (ClientData) 0,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "noop", NoopObjCmd, (ClientData) 0,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "testwrongnumargs", TestWrongNumArgsObjCmd,
(ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "testfilesystem", TestFilesystemObjCmd,
(ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateObjCommand(interp, "testgetindexfromobjstruct",
TestGetIndexFromObjStructObjCmd, (ClientData) 0,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateCommand(interp, "testaccessproc", TestaccessprocCmd, (ClientData) 0,
(Tcl_CmdDeleteProc *) NULL);
Tcl_CreateCommand(interp, "testasync", TestasyncCmd, (ClientData) 0,
|
| ︙ | ︙ | |||
4265 4266 4267 4268 4269 4270 4271 |
char *fileName; /* Name of file to open. */
char *modeString; /* A list of POSIX open modes or
* a string such as "rw". */
int permissions; /* If the open involves creating a
* file, with what modes to create
* it? */
{
| | > > > > > > > > | > > > > > > > > | > > > > > > > > | 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 |
char *fileName; /* Name of file to open. */
char *modeString; /* A list of POSIX open modes or
* a string such as "rw". */
int permissions; /* If the open involves creating a
* file, with what modes to create
* it? */
{
char *expectname="testOpenFileChannel1%.fil";
Tcl_DString ds;
Tcl_DStringInit(&ds);
Tcl_JoinPath(1, &expectname, &ds);
if (!strcmp(Tcl_DStringValue(&ds), fileName)) {
Tcl_DStringFree(&ds);
return (TclpOpenFileChannel(interp, "__testOpenFileChannel1%__.fil",
modeString, permissions));
} else {
Tcl_DStringFree(&ds);
return (NULL);
}
}
static Tcl_Channel
TestOpenFileChannelProc2(interp, fileName, modeString, permissions)
Tcl_Interp *interp; /* Interpreter for error reporting;
* can be NULL. */
char *fileName; /* Name of file to open. */
char *modeString; /* A list of POSIX open modes or
* a string such as "rw". */
int permissions; /* If the open involves creating a
* file, with what modes to create
* it? */
{
char *expectname="testOpenFileChannel2%.fil";
Tcl_DString ds;
Tcl_DStringInit(&ds);
Tcl_JoinPath(1, &expectname, &ds);
if (!strcmp(Tcl_DStringValue(&ds), fileName)) {
Tcl_DStringFree(&ds);
return (TclpOpenFileChannel(interp, "__testOpenFileChannel2%__.fil",
modeString, permissions));
} else {
Tcl_DStringFree(&ds);
return (NULL);
}
}
static Tcl_Channel
TestOpenFileChannelProc3(interp, fileName, modeString, permissions)
Tcl_Interp *interp; /* Interpreter for error reporting;
* can be NULL. */
char *fileName; /* Name of file to open. */
char *modeString; /* A list of POSIX open modes or
* a string such as "rw". */
int permissions; /* If the open involves creating a
* file, with what modes to create
* it? */
{
char *expectname="testOpenFileChannel3%.fil";
Tcl_DString ds;
Tcl_DStringInit(&ds);
Tcl_JoinPath(1, &expectname, &ds);
if (!strcmp(Tcl_DStringValue(&ds), fileName)) {
Tcl_DStringFree(&ds);
return (TclpOpenFileChannel(interp, "__testOpenFileChannel3%__.fil",
modeString, permissions));
} else {
Tcl_DStringFree(&ds);
return (NULL);
}
}
/*
*----------------------------------------------------------------------
*
|
| ︙ | ︙ | |||
4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 |
return TCL_ERROR;
}
TclFormatInt(buf, Tcl_IsChannelShared(chan));
Tcl_AppendResult(interp, buf, (char *) NULL);
return TCL_OK;
}
if ((cmdName[0] == 'm') && (strncmp(cmdName, "mode", len) == 0)) {
if (argc != 3) {
Tcl_AppendResult(interp, "channel name required",
(char *) NULL);
return TCL_ERROR;
}
| > > > > > > > > > > > | 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 |
return TCL_ERROR;
}
TclFormatInt(buf, Tcl_IsChannelShared(chan));
Tcl_AppendResult(interp, buf, (char *) NULL);
return TCL_OK;
}
if ((cmdName[0] == 'i') && (strncmp(cmdName, "isstandard", len) == 0)) {
if (argc != 3) {
Tcl_AppendResult(interp, "channel name required", (char *) NULL);
return TCL_ERROR;
}
TclFormatInt(buf, Tcl_IsStandardChannel(chan));
Tcl_AppendResult(interp, buf, (char *) NULL);
return TCL_OK;
}
if ((cmdName[0] == 'm') && (strncmp(cmdName, "mode", len) == 0)) {
if (argc != 3) {
Tcl_AppendResult(interp, "channel name required",
(char *) NULL);
return TCL_ERROR;
}
|
| ︙ | ︙ | |||
5049 5050 5051 5052 5053 5054 5055 |
sprintf(buffer, "%d", target);
Tcl_AppendResult(interp, " when ", buffer, " expected", NULL);
return TCL_ERROR;
}
Tcl_WrongNumArgs(interp, 3, objv, NULL);
return TCL_OK;
}
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182 5183 5184 5185 5186 5187 5188 5189 5190 5191 5192 5193 5194 5195 5196 5197 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 5253 5254 5255 5256 5257 5258 5259 5260 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 5289 5290 5291 5292 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 5311 5312 5313 5314 5315 5316 5317 5318 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349 5350 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366 5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 5407 5408 5409 5410 5411 5412 5413 5414 5415 5416 5417 5418 5419 5420 5421 5422 5423 5424 5425 5426 5427 5428 5429 5430 5431 5432 5433 5434 5435 5436 5437 5438 5439 5440 5441 5442 5443 5444 5445 5446 5447 5448 5449 5450 5451 |
sprintf(buffer, "%d", target);
Tcl_AppendResult(interp, " when ", buffer, " expected", NULL);
return TCL_ERROR;
}
Tcl_WrongNumArgs(interp, 3, objv, NULL);
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
* TestFilesystemObjCmd --
*
* This procedure implements the "testfilesystem" command. It is
* used to test Tcl_FSRegister, Tcl_FSUnregister, and can be used
* to test that the pluggable filesystem works.
*
* Results:
* A standard Tcl result.
*
* Side effects:
* Inserts or removes a filesystem from Tcl's stack.
*
*----------------------------------------------------------------------
*/
static int
TestFilesystemObjCmd(dummy, interp, objc, objv)
ClientData dummy;
Tcl_Interp *interp;
int objc;
Tcl_Obj *CONST objv[];
{
int res;
int onOff;
if (objc != 2) {
char *cmd = Tcl_GetString(objv[0]);
Tcl_AppendResult(interp, "wrong # args: should be \"", cmd,
" (1 or 0)\"", (char *) NULL);
return TCL_ERROR;
}
if (Tcl_GetBooleanFromObj(interp, objv[1], &onOff) != TCL_OK) {
return TCL_ERROR;
}
if (onOff) {
res = Tcl_FSRegister((ClientData)interp, &testReportingFilesystem);
if (res == TCL_OK) {
Tcl_SetResult(interp, "registered", TCL_STATIC);
} else {
Tcl_SetResult(interp, "failed", TCL_STATIC);
}
} else {
res = Tcl_FSUnregister(&testReportingFilesystem);
if (res == TCL_OK) {
Tcl_SetResult(interp, "unregistered", TCL_STATIC);
} else {
Tcl_SetResult(interp, "failed", TCL_STATIC);
}
}
return res;
}
void
TestReport(cmd, arg1, arg2)
CONST char* cmd;
Tcl_Obj* arg1;
Tcl_Obj* arg2;
{
Tcl_Interp* interp = (Tcl_Interp*) Tcl_FSData(&testReportingFilesystem);
if (interp == NULL) {
/* This is bad, but not much we can do about it */
} else {
Tcl_SavedResult savedResult;
Tcl_DString ds;
Tcl_DStringInit(&ds);
Tcl_DStringAppend(&ds, "puts stderr ",-1);
Tcl_DStringStartSublist(&ds);
Tcl_DStringAppendElement(&ds, cmd);
if (arg1 != NULL) {
Tcl_DStringAppendElement(&ds, Tcl_GetString(arg1));
}
if (arg2 != NULL) {
Tcl_DStringAppendElement(&ds, Tcl_GetString(arg2));
}
Tcl_DStringEndSublist(&ds);
Tcl_SaveResult(interp, &savedResult);
Tcl_Eval(interp, Tcl_DStringValue(&ds));
Tcl_DStringFree(&ds);
Tcl_RestoreResult(interp, &savedResult);
}
}
int
TestReportStat(path, buf)
Tcl_Obj *path; /* Path of file to stat (in current CP). */
struct stat *buf; /* Filled with results of stat call. */
{
TestReport("stat",path, NULL);
return -1;
}
int
TestReportLstat(path, buf)
Tcl_Obj *path; /* Path of file to stat (in current CP). */
struct stat *buf; /* Filled with results of stat call. */
{
TestReport("lstat",path, NULL);
return -1;
}
int
TestReportAccess(path, mode)
Tcl_Obj *path; /* Path of file to access (in current CP). */
int mode; /* Permission setting. */
{
TestReport("access",path,NULL);
return -1;
}
Tcl_Channel
TestReportOpenFileChannel(interp, fileName, modeString, permissions)
Tcl_Interp *interp; /* Interpreter for error reporting;
* can be NULL. */
Tcl_Obj *fileName; /* Name of file to open. */
char *modeString; /* A list of POSIX open modes or
* a string such as "rw". */
int permissions; /* If the open involves creating a
* file, with what modes to create
* it? */
{
TestReport("open",fileName, NULL);
return NULL;
}
int
TestReportMatchInDirectory(interp, resultPtr, dirPtr, pattern, types)
Tcl_Interp *interp; /* Interpreter to receive results. */
Tcl_Obj *resultPtr; /* Directory separators to pass to TclDoGlob. */
Tcl_Obj *dirPtr; /* Contains path to directory to search. */
char *pattern; /* Pattern to match against. */
Tcl_GlobTypeData *types; /* Object containing list of acceptable types.
* May be NULL. */
{
TestReport("matchindirectory",dirPtr, NULL);
return -1;
}
Tcl_Obj *
TestReportGetCwd(interp)
Tcl_Interp *interp;
{
TestReport("cwd",NULL,NULL);
return NULL;
}
int
TestReportChdir(dirName)
Tcl_Obj *dirName;
{
TestReport("chdir",dirName,NULL);
return -1;
}
int
TestReportLoadFile(interp, fileName, sym1, sym2, proc1Ptr, proc2Ptr, clientDataPtr)
Tcl_Interp *interp; /* Used for error reporting. */
Tcl_Obj *fileName; /* Name of the file containing the desired
* code. */
char *sym1, *sym2; /* Names of two procedures to look up in
* the file's symbol table. */
Tcl_PackageInitProc **proc1Ptr, **proc2Ptr;
/* Where to return the addresses corresponding
* to sym1 and sym2. */
ClientData *clientDataPtr; /* Filled with token for dynamically loaded
* file which will be passed back to
* TclpUnloadFile() to unload the file. */
{
TestReport("loadfile",fileName,NULL);
return -1;
}
void
TestReportUnloadFile(clientData)
ClientData clientData; /* ClientData returned by a previous call
* to TclpLoadFile(). The clientData is
* a token that represents the loaded
* file. */
{
TestReport("unloadfile",NULL,NULL);
}
Tcl_Obj *
TestReportReadlink(path)
Tcl_Obj *path; /* Path of file to readlink (UTF-8). */
{
TestReport("readlink",path,NULL);
return NULL;
}
int
TestReportListVolumes(interp)
Tcl_Interp *interp; /* Interpreter for returning volume list. */
{
TestReport("listvolumes",NULL,NULL);
return TCL_OK;
}
int
TestReportRenameFile(src, dst)
Tcl_Obj *src; /* Pathname of file or dir to be renamed
* (UTF-8). */
Tcl_Obj *dst; /* New pathname of file or directory
* (UTF-8). */
{
TestReport("renamefile",src,dst);
return -1;
}
int
TestReportCopyFile(src, dst)
Tcl_Obj *src; /* Pathname of file to be copied (UTF-8). */
Tcl_Obj *dst; /* Pathname of file to copy to (UTF-8). */
{
TestReport("copyfile",src,dst);
return -1;
}
int
TestReportDeleteFile(path)
Tcl_Obj *path; /* Pathname of file to be removed (UTF-8). */
{
TestReport("deletefile",path,NULL);
return -1;
}
int
TestReportCreateDirectory(path)
Tcl_Obj *path; /* Pathname of directory to create (UTF-8). */
{
TestReport("createdirectory",path,NULL);
return -1;
}
int
TestReportCopyDirectory(src, dst, errorPtr)
Tcl_Obj *src; /* Pathname of directory to be copied
* (UTF-8). */
Tcl_Obj *dst; /* Pathname of target directory (UTF-8). */
Tcl_Obj **errorPtr; /* If non-NULL, uninitialized or free
* DString filled with UTF-8 name of file
* causing error. */
{
TestReport("copydirectory",src,dst);
return -1;
}
int
TestReportRemoveDirectory(path, recursive, errorPtr)
Tcl_Obj *path; /* Pathname of directory to be removed
* (UTF-8). */
int recursive; /* If non-zero, removes directories that
* are nonempty. Otherwise, will only remove
* empty directories. */
Tcl_Obj **errorPtr; /* If non-NULL, uninitialized or free
* DString filled with UTF-8 name of file
* causing error. */
{
TestReport("removedirectory",path,NULL);
return -1;
}
char**
TestReportFileAttrStrings(fileName, objPtrRef)
Tcl_Obj* fileName;
Tcl_Obj** objPtrRef;
{
TestReport("fileattributestrings",fileName,NULL);
return NULL;
}
int
TestReportFileAttrsGet(interp, index, fileName, objPtrRef)
Tcl_Interp *interp; /* The interpreter for error reporting. */
int index; /* index of the attribute command. */
Tcl_Obj *fileName; /* filename we are operating on. */
Tcl_Obj **objPtrRef; /* for output. */
{
TestReport("fileattributesget",fileName,NULL);
return -1;
}
int
TestReportFileAttrsSet(interp, index, fileName, objPtr)
Tcl_Interp *interp; /* The interpreter for error reporting. */
int index; /* index of the attribute command. */
Tcl_Obj *fileName; /* filename we are operating on. */
Tcl_Obj *objPtr; /* for input. */
{
TestReport("fileattributesset",fileName,objPtr);
return -1;
}
int
TestReportUtime (fileName, tval)
Tcl_Obj* fileName;
struct utimbuf *tval;
{
TestReport("utime",fileName,NULL);
return -1;
}
int
TestReportNormalizePath(interp, pathPtr, nextCheckpoint)
Tcl_Interp *interp;
Tcl_Obj *pathPtr;
int nextCheckpoint;
{
TestReport("normalizepath",pathPtr,NULL);
return nextCheckpoint;
}
|
Changes to generic/tclUtil.c.
1 2 3 4 5 6 7 8 9 10 11 12 | /* * tclUtil.c -- * * This file contains utility procedures that are used by many Tcl * commands. * * Copyright (c) 1987-1993 The Regents of the University of California. * Copyright (c) 1994-1998 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | /* * tclUtil.c -- * * This file contains utility procedures that are used by many Tcl * commands. * * Copyright (c) 1987-1993 The Regents of the University of California. * Copyright (c) 1994-1998 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclUtil.c,v 1.21 2001/07/31 19:12:07 vincentdarley Exp $ */ #include "tclInt.h" #include "tclPort.h" /* * The following variable holds the full path name of the binary |
| ︙ | ︙ | |||
2270 2271 2272 2273 2274 2275 2276 |
*/
CONST char *
Tcl_GetNameOfExecutable()
{
return (tclExecutableName);
}
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 2270 2271 2272 2273 2274 2275 2276 |
*/
CONST char *
Tcl_GetNameOfExecutable()
{
return (tclExecutableName);
}
|
Changes to library/init.tcl.
1 2 3 4 5 | # init.tcl -- # # Default system startup file for Tcl-based applications. Defines # "unknown" procedure and auto-load facilities. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 | # init.tcl -- # # Default system startup file for Tcl-based applications. Defines # "unknown" procedure and auto-load facilities. # # RCS: @(#) $Id: init.tcl,v 1.49 2001/07/31 19:12:07 vincentdarley Exp $ # # Copyright (c) 1991-1993 The Regents of the University of California. # Copyright (c) 1994-1996 Sun Microsystems, Inc. # Copyright (c) 1998-1999 Scriptics Corporation. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. |
| ︙ | ︙ | |||
622 623 624 625 626 627 628 |
return $auto_execs($name)
}
}
return ""
}
}
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 |
return $auto_execs($name)
}
}
return ""
}
}
namespace eval tcl {}
# ::tcl::CopyDirectory --
#
# This procedure is called by Tcl's core when attempts to call the
# filesystem's copydirectory function fail. The semantics of the call
# are that 'dest' does not yet exist, i.e. dest should become the exact
# image of src. If dest does exist, we throw an error.
#
# Note that making changes to this procedure can change the results
# of running Tcl's tests.
#
# Arguments:
# action - "renaming" or "copying"
# src - source directory
# dest - destination directory
proc ::tcl::CopyDirectory {action src dest} {
set nsrc [file normalize $src]
set ndest [file normalize $dest]
if {[string equal $action "renaming"]} {
# Can't rename volumes
if {[lsearch -exact [file volumes] $nsrc] != -1} {
return -code error "error $action \"$src\" to\
\"$dest\": trying to rename a volume or move a directory\
into itself"
}
}
if {[file exists $dest]} {
if {$nsrc == $ndest} {
return -code error "error $action \"$src\" to\
\"$dest\": trying to rename a volume or move a directory\
into itself"
}
if {[string equal $action "copying"]} {
return -code error "error $action \"$src\" to\
\"$dest\": file already exists"
} else {
# Depending on the platform, and on the current
# working directory, the directories '.', '..'
# can be returned in various combinations. Anyway,
# if any other file is returned, we must signal an error.
set existing [glob -nocomplain -directory $dest * .*]
eval [list lappend existing] \
[glob -nocomplain -directory $dest -type hidden * .*]
foreach s $existing {
if {([file tail $s] != ".") && ([file tail $s] != "..")} {
return -code error "error $action \"$src\" to\
\"$dest\": file already exists"
}
}
}
} else {
if {[string first $nsrc $ndest] != -1} {
set srclen [expr {[llength [file split $nsrc]] -1}]
set ndest [lindex [file split $ndest] $srclen]
if {$ndest == [file tail $nsrc]} {
return -code error "error $action \"$src\" to\
\"$dest\": trying to rename a volume or move a directory\
into itself"
}
}
file mkdir $dest
}
# Have to be careful to capture both visible and hidden files
foreach s [glob -nocomplain -directory $src *] {
if {([file tail $s] != ".") && ([file tail $s] != "..")} {
file copy $s [file join $dest [file tail $s]]
}
}
# This will pick up things beginning with '.' on Unix and on
# Windows/MacOS those files which the OS considers invisible.
foreach s [glob -nocomplain -directory $src -types hidden *] {
if {([file tail $s] != ".") && ([file tail $s] != "..")} {
file copy $s [file join $dest [file tail $s]]
}
}
return
}
|
Changes to mac/tclMacFCmd.c.
1 2 3 4 5 6 7 8 9 10 11 | /* * tclMacFCmd.c -- * * Implements the Macintosh specific portions of the file manipulation * subcommands of the "file" command. * * Copyright (c) 1996-1998 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | /* * tclMacFCmd.c -- * * Implements the Macintosh specific portions of the file manipulation * subcommands of the "file" command. * * Copyright (c) 1996-1998 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclMacFCmd.c,v 1.8 2001/07/31 19:12:07 vincentdarley Exp $ */ #include "tclInt.h" #include "tclMac.h" #include "tclMacInt.h" #include "tclPort.h" #include <FSpCompat.h> #include <MoreFilesExtras.h> #include <Strings.h> #include <Errors.h> #include <FileCopy.h> #include <DirectoryCopy.h> #include <Script.h> #include <string.h> #include <Finder.h> #include <Aliases.h> /* * Callback for the file attributes code. */ static int GetFileFinderAttributes _ANSI_ARGS_((Tcl_Interp *interp, int objIndex, CONST char *fileName, |
| ︙ | ︙ | |||
93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
Boolean *pathExistsPtr,
Boolean *pathIsDirectoryPtr));
static OSErr MoveRename _ANSI_ARGS_((const FSSpec *srcSpecPtr,
const FSSpec *dstSpecPtr, StringPtr copyName));
static int Pstrequal _ANSI_ARGS_((ConstStr255Param stringA,
ConstStr255Param stringB));
/*
*---------------------------------------------------------------------------
*
* TclpRenameFile, DoRenameFile --
*
* Changes the name of an existing file or directory, from src to dst.
* If src and dst refer to the same file or directory, does nothing
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
Boolean *pathExistsPtr,
Boolean *pathIsDirectoryPtr));
static OSErr MoveRename _ANSI_ARGS_((const FSSpec *srcSpecPtr,
const FSSpec *dstSpecPtr, StringPtr copyName));
static int Pstrequal _ANSI_ARGS_((ConstStr255Param stringA,
ConstStr255Param stringB));
int
TclpObjCreateDirectory(pathPtr)
Tcl_Obj *pathPtr;
{
return TclpCreateDirectory(Tcl_FSGetTranslatedPath(NULL, pathPtr));
}
int
TclpObjDeleteFile(pathPtr)
Tcl_Obj *pathPtr;
{
return TclpDeleteFile(Tcl_FSGetTranslatedPath(NULL, pathPtr));
}
int
TclpObjCopyDirectory(srcPathPtr, destPathPtr, errorPtr)
Tcl_Obj *srcPathPtr;
Tcl_Obj *destPathPtr;
Tcl_Obj **errorPtr;
{
Tcl_DString ds;
int ret;
ret = TclpCopyDirectory(Tcl_FSGetTranslatedPath(NULL,srcPathPtr),
Tcl_FSGetTranslatedPath(NULL,destPathPtr), &ds);
if (ret != TCL_OK) {
*errorPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds), -1);
Tcl_DStringFree(&ds);
Tcl_IncrRefCount(*errorPtr);
}
return ret;
}
int
TclpObjCopyFile(srcPathPtr, destPathPtr)
Tcl_Obj *srcPathPtr;
Tcl_Obj *destPathPtr;
{
return TclpCopyFile(Tcl_FSGetTranslatedPath(NULL,srcPathPtr),
Tcl_FSGetTranslatedPath(NULL,destPathPtr));
}
int
TclpObjRemoveDirectory(pathPtr, recursive, errorPtr)
Tcl_Obj *pathPtr;
int recursive;
Tcl_Obj **errorPtr;
{
Tcl_DString ds;
int ret;
ret = TclpRemoveDirectory(Tcl_FSGetTranslatedPath(NULL, pathPtr),recursive, &ds);
if (ret != TCL_OK) {
*errorPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds), -1);
Tcl_DStringFree(&ds);
Tcl_IncrRefCount(*errorPtr);
}
return ret;
}
int
TclpObjRenameFile(srcPathPtr, destPathPtr)
Tcl_Obj *srcPathPtr;
Tcl_Obj *destPathPtr;
{
return TclpRenameFile(Tcl_FSGetTranslatedPath(NULL,srcPathPtr),
Tcl_FSGetTranslatedPath(NULL,destPathPtr));
}
/*
*---------------------------------------------------------------------------
*
* TclpRenameFile, DoRenameFile --
*
* Changes the name of an existing file or directory, from src to dst.
* If src and dst refer to the same file or directory, does nothing
|
| ︙ | ︙ | |||
1544 1545 1546 1547 1548 1549 1550 |
volIndex++;
}
Tcl_SetObjResult(interp, resultPtr);
return TCL_OK;
}
| | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 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 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 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 |
volIndex++;
}
Tcl_SetObjResult(interp, resultPtr);
return TCL_OK;
}
/*
*---------------------------------------------------------------------------
*
* TclpObjNormalizePath --
*
* This function scans through a path specification and replaces
* it, in place, with a normalized version. On MacOS, this means
* resolving all aliases present in the path and replacing the head of
* pathPtr with the absolute case-sensitive path to the last file or
* directory that could be validated in the path.
*
* Results:
* The new 'nextCheckpoint' value, giving as far as we could
* understand in the path.
*
* Side effects:
* The pathPtr string, which must contain a valid path, is
* possibly modified in place.
*
*---------------------------------------------------------------------------
*/
int
TclpObjNormalizePath(interp, pathPtr, nextCheckpoint)
Tcl_Interp *interp;
Tcl_Obj *pathPtr;
int nextCheckpoint;
{
#define MAXMACFILENAMELEN 31 /* assumed to be < sizeof(StrFileName) */
StrFileName fileName;
StringPtr fileNamePtr;
int fileNameLen,newPathLen;
Handle newPathHandle;
OSErr err;
short vRefNum;
long dirID;
Boolean isDirectory;
Boolean wasAlias;
FSSpec fileSpec;
Tcl_DString nativeds;
char cur;
int firstCheckpoint=nextCheckpoint, lastCheckpoint;
int origPathLen;
char *path = Tcl_GetStringFromObj(pathPtr,&origPathLen);
{
int currDirValid=0;
/*
* check if substring to first ':' after initial
* nextCheckpoint is a valid relative or absolute
* path to a directory, if not we return without
* normalizing anything
*/
while (1) {
cur = path[nextCheckpoint];
if (cur == ':' || cur == 0) {
if (cur == ':') { nextCheckpoint++; cur = path[nextCheckpoint]; } /* jump over separator */
Tcl_UtfToExternalDString(NULL,path,nextCheckpoint,&nativeds);
err = FSpLocationFromPath(Tcl_DStringLength(&nativeds), Tcl_DStringValue(&nativeds), &fileSpec);
Tcl_DStringFree(&nativeds);
if (err == noErr) {
err = FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory);
currDirValid = ((err == noErr) && isDirectory);
vRefNum = fileSpec.vRefNum;
}
break;
}
nextCheckpoint++;
}
if(!currDirValid) return firstCheckpoint; /* can't determine root dir, bail out */
}
/*
* Now vRefNum and dirID point to a valid
* directory, so walk the rest of the path
* ( code adapted from FSpLocationFromPath() )
*/
lastCheckpoint=nextCheckpoint;
while (1) {
cur = path[nextCheckpoint];
if (cur == ':' || cur == 0) {
fileNameLen=nextCheckpoint-lastCheckpoint;
fileNamePtr=fileName;
if(fileNameLen==0) {
if (cur == ':') {
/*
* special case for empty dirname i.e. encountered
* a '::' path component: get parent dir of currDir
*/
fileName[0]=2;
strcpy((char *) fileName + 1, "::");
lastCheckpoint--;
} else {
/*
* empty filename, i.e. want FSSpec for currDir
*/
fileNamePtr=NULL;
}
} else {
Tcl_UtfToExternalDString(NULL,&path[lastCheckpoint],fileNameLen,&nativeds);
fileNameLen=Tcl_DStringLength(&nativeds);
if(fileNameLen > MAXMACFILENAMELEN) fileNameLen=MAXMACFILENAMELEN;
fileName[0]=fileNameLen;
strncpy((char *) fileName + 1, Tcl_DStringValue(&nativeds), fileNameLen);
Tcl_DStringFree(&nativeds);
}
err=FSMakeFSSpecCompat(vRefNum, dirID, fileNamePtr, &fileSpec);
if(err != noErr) {
if(err != fnfErr) {
/*
* this can if trying to get parent of a root volume via '::'
* or when using an illegal filename
* revert to last checkpoint and stop processing path further
*/
err=FSMakeFSSpecCompat(vRefNum, dirID, NULL, &fileSpec);
if(err != noErr) return firstCheckpoint; /* should never happen, bail out */
nextCheckpoint=lastCheckpoint;
cur = path[lastCheckpoint];
}
break; /* arrived at nonexistent file or dir */
} else {
/* fileSpec could point to an alias, resolve it */
err = ResolveAliasFile(&fileSpec, true, &isDirectory, &wasAlias);
if (err != noErr || !isDirectory) break; /* fileSpec doesn't point to a dir */
}
if (cur == 0) break; /* arrived at end of path */
/* fileSpec points to possibly nonexisting subdirectory; validate */
err = FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory);
if (err != noErr || !isDirectory) break; /* fileSpec doesn't point to existing dir */
vRefNum = fileSpec.vRefNum;
/* found a new valid subdir in path, continue processing path */
lastCheckpoint=nextCheckpoint+1;
}
nextCheckpoint++;
}
/*
* fileSpec now points to a possibly nonexisting file or dir
* inside a valid dir; get full path name to it
*/
err=FSpPathFromLocation(&fileSpec, &newPathLen, &newPathHandle);
if(err != noErr) return firstCheckpoint; /* should not see any errors here, bail out */
HLock(newPathHandle);
Tcl_ExternalToUtfDString(NULL,*newPathHandle,newPathLen,&nativeds);
if (cur != 0) {
/* not at end, append remaining path */
if ( newPathLen==0 || *(*newPathHandle+(newPathLen-1))!=':') {
Tcl_DStringAppend(&nativeds, ":" , 1);
}
Tcl_DStringAppend(&nativeds, &path[nextCheckpoint+1], strlen(&path[nextCheckpoint+1]));
}
DisposeHandle(newPathHandle);
fileNameLen=Tcl_DStringLength(&nativeds);
Tcl_SetStringObj(pathPtr,Tcl_DStringValue(&nativeds),fileNameLen);
Tcl_DStringFree(&nativeds);
return nextCheckpoint+(fileNameLen-origPathLen);
}
|
Changes to mac/tclMacFile.c.
1 2 3 4 5 6 7 8 9 10 11 12 | /* * tclMacFile.c -- * * This file implements the channel drivers for Macintosh * files. It also comtains Macintosh version of other Tcl * functions that deal with the file system. * * Copyright (c) 1995-1998 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | | < > | | | > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
/*
* tclMacFile.c --
*
* This file implements the channel drivers for Macintosh
* files. It also comtains Macintosh version of other Tcl
* functions that deal with the file system.
*
* Copyright (c) 1995-1998 Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* RCS: @(#) $Id: tclMacFile.c,v 1.10 2001/07/31 19:12:07 vincentdarley Exp $
*/
/*
* Note: This code eventually needs to support async I/O. In doing this
* we will need to keep track of all current async I/O. If exit to shell
* is called - we shouldn't exit until all asyc I/O completes.
*/
#include "tclInt.h"
#include "tclPort.h"
#include "tclMacInt.h"
#include <Aliases.h>
#include <Errors.h>
#include <Processes.h>
#include <Strings.h>
#include <Types.h>
#include <MoreFiles.h>
#include <MoreFilesExtras.h>
#include <FSpCompat.h>
static OSErr FspLocationFromFsPath _ANSI_ARGS_((Tcl_Obj *pathPtr, FSSpec* specPtr));
OSErr
FspLocationFromFsPath(pathPtr, specPtr)
Tcl_Obj *pathPtr;
FSSpec* specPtr;
{
char *native = Tcl_FSGetNativePath(pathPtr);
return FSpLocationFromPath(strlen(native), native, specPtr);
}
/*
*----------------------------------------------------------------------
*
* TclpFindExecutable --
*
|
| ︙ | ︙ | |||
98 99 100 101 102 103 104 |
Tcl_DStringFree(&ds);
return tclExecutableName;
}
/*
*----------------------------------------------------------------------
*
| | < < < > | | > | | | | | < < < | | > | < | < > > > > > > > > > > | | | > > > > > > > > > > > > > > > > > | | | > > > > > > > < < < < < < < < < < < < < < < < < < < | < < < > | | | | > | > > | > > > > > > | > > > | > > > > | | | < < < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < < < < < < < < < > < < < < < < < < < < < < < < < < < < < | 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 |
Tcl_DStringFree(&ds);
return tclExecutableName;
}
/*
*----------------------------------------------------------------------
*
* TclpMatchInDirectory --
*
* This routine is used by the globbing code to search a
* directory for all files which match a given pattern.
*
* Results:
*
* The return value is a standard Tcl result indicating whether an
* error occurred in globbing. Errors are left in interp, good
* results are lappended to resultPtr (which must be a valid object)
*
* Side effects:
* None.
*
*---------------------------------------------------------------------- */
int
TclpMatchInDirectory(interp, resultPtr, pathPtr, pattern, types)
Tcl_Interp *interp; /* Interpreter to receive errors. */
Tcl_Obj *resultPtr; /* List object to lappend results. */
Tcl_Obj *pathPtr; /* Contains path to directory to search. */
char *pattern; /* Pattern to match against. */
Tcl_GlobTypeData *types; /* Object containing list of acceptable types.
* May be NULL. In particular the directory
* flag is very important. */
{
char *fname;
int fnameLen, result = TCL_OK;
int baseLength;
CInfoPBRec pb;
OSErr err;
FSSpec dirSpec;
Boolean isDirectory;
long dirID;
short itemIndex;
Str255 fileName;
Tcl_DString fileString;
OSType okType = 0;
OSType okCreator = 0;
Tcl_DString dsOrig;
char *fileName2;
fileName2 = Tcl_FSGetTranslatedPath(interp, pathPtr);
if (fileName2 == NULL) {
return TCL_ERROR;
}
Tcl_DStringInit(&dsOrig);
Tcl_DStringAppend(&dsOrig, fileName2, -1);
baseLength = Tcl_DStringLength(&dsOrig);
/*
* Make sure that the directory part of the name really is a
* directory.
*/
Tcl_UtfToExternalDString(NULL, Tcl_DStringValue(&dsOrig),
Tcl_DStringLength(&dsOrig), &fileString);
err = FSpLocationFromPath(Tcl_DStringLength(&fileString), Tcl_DStringValue(&fileString), &dirSpec);
Tcl_DStringFree(&fileString);
if (err == noErr)
err = FSpGetDirectoryID(&dirSpec, &dirID, &isDirectory);
if ((err != noErr) || !isDirectory) {
/*
* Check if we had a relative path (unix style rel path compatibility for glob)
*/
Tcl_DStringFree(&dsOrig);
Tcl_DStringAppend(&dsOrig, ":", 1);
Tcl_DStringAppend(&dsOrig, fileName2, -1);
baseLength = Tcl_DStringLength(&dsOrig);
Tcl_UtfToExternalDString(NULL, Tcl_DStringValue(&dsOrig),
Tcl_DStringLength(&dsOrig), &fileString);
err = FSpLocationFromPath(Tcl_DStringLength(&fileString), Tcl_DStringValue(&fileString), &dirSpec);
Tcl_DStringFree(&fileString);
if (err == noErr)
err = FSpGetDirectoryID(&dirSpec, &dirID, &isDirectory);
if ((err != noErr) || !isDirectory) {
Tcl_DStringFree(&dsOrig);
return TCL_OK;
}
}
/* Make sure we have a trailing directory delimiter */
if (Tcl_DStringValue(&dsOrig)[baseLength-1] != ':') {
Tcl_DStringAppend(&dsOrig, ":", 1);
baseLength++;
}
/*
* Now open the directory for reading and iterate over the contents.
*/
pb.hFileInfo.ioVRefNum = dirSpec.vRefNum;
pb.hFileInfo.ioDirID = dirID;
pb.hFileInfo.ioNamePtr = (StringPtr) fileName;
pb.hFileInfo.ioFDirIndex = itemIndex = 1;
if (types != NULL) {
if (types->macType != NULL) {
Tcl_GetOSTypeFromObj(NULL, types->macType, &okType);
}
if (types->macCreator != NULL) {
Tcl_GetOSTypeFromObj(NULL, types->macCreator, &okCreator);
}
}
while (1) {
pb.hFileInfo.ioFDirIndex = itemIndex;
pb.hFileInfo.ioDirID = dirID;
err = PBGetCatInfoSync(&pb);
if (err != noErr) {
break;
}
/*
* Now check to see if the file matches.
*/
Tcl_ExternalToUtfDString(NULL, (char *) fileName + 1, fileName[0],
&fileString);
if (Tcl_StringMatch(Tcl_DStringValue(&fileString), pattern)) {
int typeOk = 1;
Tcl_DStringSetLength(&dsOrig, baseLength);
Tcl_DStringAppend(&dsOrig, Tcl_DStringValue(&fileString), -1);
fname = Tcl_DStringValue(&dsOrig);
fnameLen = Tcl_DStringLength(&dsOrig);
if (types == NULL) {
/* If invisible, don't return the file */
if (pb.hFileInfo.ioFlFndrInfo.fdFlags & kIsInvisible) {
typeOk = 0;
}
} else {
if (pb.hFileInfo.ioFlFndrInfo.fdFlags & kIsInvisible) {
/* If invisible */
if ((types->perm == 0) ||
!(types->perm & TCL_GLOB_PERM_HIDDEN)) {
typeOk = 0;
}
} else {
/* Visible */
if (types->perm & TCL_GLOB_PERM_HIDDEN) {
typeOk = 0;
}
}
if (typeOk == 1 && types->perm != 0) {
if (
((types->perm & TCL_GLOB_PERM_RONLY) &&
!(pb.hFileInfo.ioFlAttrib & 1)) ||
((types->perm & TCL_GLOB_PERM_R) &&
(TclpAccess(fname, R_OK) != 0)) ||
((types->perm & TCL_GLOB_PERM_W) &&
(TclpAccess(fname, W_OK) != 0)) ||
((types->perm & TCL_GLOB_PERM_X) &&
(TclpAccess(fname, X_OK) != 0))
) {
typeOk = 0;
}
}
if (typeOk == 1 && types->type != 0) {
struct stat buf;
/*
* We must match at least one flag to be listed
*/
typeOk = 0;
if (TclpLstat(fname, &buf) >= 0) {
/*
* In order bcdpfls as in 'find -t'
*/
if (
((types->type & TCL_GLOB_TYPE_BLOCK) &&
S_ISBLK(buf.st_mode)) ||
((types->type & TCL_GLOB_TYPE_CHAR) &&
S_ISCHR(buf.st_mode)) ||
((types->type & TCL_GLOB_TYPE_DIR) &&
S_ISDIR(buf.st_mode)) ||
((types->type & TCL_GLOB_TYPE_PIPE) &&
S_ISFIFO(buf.st_mode)) ||
((types->type & TCL_GLOB_TYPE_FILE) &&
S_ISREG(buf.st_mode))
#ifdef S_ISLNK
|| ((types->type & TCL_GLOB_TYPE_LINK) &&
S_ISLNK(buf.st_mode))
#endif
#ifdef S_ISSOCK
|| ((types->type & TCL_GLOB_TYPE_SOCK) &&
S_ISSOCK(buf.st_mode))
#endif
) {
typeOk = 1;
}
} else {
/* Posix error occurred */
}
}
if (typeOk && (
((okType != 0) && (okType !=
pb.hFileInfo.ioFlFndrInfo.fdType)) ||
((okCreator != 0) && (okCreator !=
pb.hFileInfo.ioFlFndrInfo.fdCreator)))) {
typeOk = 0;
}
}
if (typeOk) {
if ((fnameLen > 1) && (strchr(fname+1, ':') == NULL)) {
Tcl_ListObjAppendElement(interp, resultPtr,
Tcl_NewStringObj(fname+1, fnameLen-1));
} else {
Tcl_ListObjAppendElement(interp, resultPtr,
Tcl_NewStringObj(fname, fnameLen));
}
}
}
Tcl_DStringFree(&fileString);
itemIndex++;
}
Tcl_DStringFree(&dsOrig);
return result;
}
/*
*----------------------------------------------------------------------
*
* TclpAccess --
*
|
| ︙ | ︙ | |||
348 349 350 351 352 353 354 |
*/
int
TclpAccess(
CONST char *path, /* Path of file to access (UTF-8). */
int mode) /* Permission setting. */
{
| < < < < < < < < < | < < < | < < < < | < < < < < < < < < < < | < < < < < < < < < < < < | < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < | 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 |
*/
int
TclpAccess(
CONST char *path, /* Path of file to access (UTF-8). */
int mode) /* Permission setting. */
{
int ret;
Tcl_Obj *obj = Tcl_NewStringObj(path,-1);
Tcl_IncrRefCount(obj);
ret = TclpObjAccess(obj,mode);
Tcl_DecrRefCount(obj);
return ret;
}
/*
*----------------------------------------------------------------------
*
* TclpChdir --
*
|
| ︙ | ︙ | |||
447 448 449 450 451 452 453 |
*----------------------------------------------------------------------
*/
int
TclpChdir(
CONST char *dirName) /* Path to new working directory (UTF-8). */
{
| < < < < < < | < < < | < < < < | < < < < < | < < < < | < < < < < < < < < | < < < | 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 |
*----------------------------------------------------------------------
*/
int
TclpChdir(
CONST char *dirName) /* Path to new working directory (UTF-8). */
{
int ret;
Tcl_Obj *obj = Tcl_NewStringObj(dirName,-1);
Tcl_IncrRefCount(obj);
ret = TclpObjChdir(obj);
Tcl_DecrRefCount(obj);
return ret;
}
/*
*----------------------------------------------------------------------
*
* TclpGetCwd --
*
|
| ︙ | ︙ | |||
724 725 726 727 728 729 730 |
*/
int
TclpStat(
CONST char *path, /* Path of file to stat (in UTF-8). */
struct stat *bufPtr) /* Filled with results of stat call. */
{
| < < < < < < < | < < < | < < < < | < < < | < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 |
*/
int
TclpStat(
CONST char *path, /* Path of file to stat (in UTF-8). */
struct stat *bufPtr) /* Filled with results of stat call. */
{
int ret;
Tcl_Obj *obj = Tcl_NewStringObj(path,-1);
Tcl_IncrRefCount(obj);
ret = TclpObjStat(obj,bufPtr);
Tcl_DecrRefCount(obj);
return ret;
}
/*
*----------------------------------------------------------------------
*
* Tcl_WaitPid --
*
|
| ︙ | ︙ | |||
990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 |
return EINVAL;
case diffVolErr:
return EXDEV;
default:
return EINVAL;
}
}
int
TclMacChmod(
char *path,
int mode)
{
HParamBlockRec hpb;
OSErr err;
| > | 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 |
return EINVAL;
case diffVolErr:
return EXDEV;
default:
return EINVAL;
}
}
int
TclMacChmod(
char *path,
int mode)
{
HParamBlockRec hpb;
OSErr err;
|
| ︙ | ︙ | |||
1017 1018 1019 1020 1021 1022 1023 |
if (err != noErr) {
errno = TclMacOSErrorToPosixError(err);
return -1;
}
return 0;
}
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 |
if (err != noErr) {
errno = TclMacOSErrorToPosixError(err);
return -1;
}
return 0;
}
int
TclpObjStat(pathPtr, bufPtr)
Tcl_Obj *pathPtr;
struct stat *bufPtr;
{
HFileInfo fpb;
HVolumeParam vpb;
OSErr err;
FSSpec fileSpec;
Boolean isDirectory;
long dirID;
err = FspLocationFromFsPath(pathPtr, &fileSpec);
if (err != noErr) {
errno = TclMacOSErrorToPosixError(err);
return -1;
}
/*
* Fill the fpb & vpb struct up with info about file or directory.
*/
FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory);
vpb.ioVRefNum = fpb.ioVRefNum = fileSpec.vRefNum;
vpb.ioNamePtr = fpb.ioNamePtr = fileSpec.name;
if (isDirectory) {
fpb.ioDirID = fileSpec.parID;
} else {
fpb.ioDirID = dirID;
}
fpb.ioFDirIndex = 0;
err = PBGetCatInfoSync((CInfoPBPtr)&fpb);
if (err == noErr) {
vpb.ioVolIndex = 0;
err = PBHGetVInfoSync((HParmBlkPtr)&vpb);
if (err == noErr && bufPtr != NULL) {
/*
* Files are always readable by everyone.
*/
bufPtr->st_mode = S_IRUSR | S_IRGRP | S_IROTH;
/*
* Use the Volume Info & File Info to fill out stat buf.
*/
if (fpb.ioFlAttrib & 0x10) {
bufPtr->st_mode |= S_IFDIR;
bufPtr->st_nlink = 2;
} else {
bufPtr->st_nlink = 1;
if (fpb.ioFlFndrInfo.fdFlags & 0x8000) {
bufPtr->st_mode |= S_IFLNK;
} else {
bufPtr->st_mode |= S_IFREG;
}
}
if ((fpb.ioFlAttrib & 0x10) || (fpb.ioFlFndrInfo.fdType == 'APPL')) {
/*
* Directories and applications are executable by everyone.
*/
bufPtr->st_mode |= S_IXUSR | S_IXGRP | S_IXOTH;
}
if ((fpb.ioFlAttrib & 0x01) == 0){
/*
* If not locked, then everyone has write acces.
*/
bufPtr->st_mode |= S_IWUSR | S_IWGRP | S_IWOTH;
}
bufPtr->st_ino = fpb.ioDirID;
bufPtr->st_dev = fpb.ioVRefNum;
bufPtr->st_uid = -1;
bufPtr->st_gid = -1;
bufPtr->st_rdev = 0;
bufPtr->st_size = fpb.ioFlLgLen;
bufPtr->st_blksize = vpb.ioVAlBlkSiz;
bufPtr->st_blocks = (bufPtr->st_size + bufPtr->st_blksize - 1)
/ bufPtr->st_blksize;
/*
* The times returned by the Mac file system are in the
* local time zone. We convert them to GMT so that the
* epoch starts from GMT. This is also consistant with
* what is returned from "clock seconds".
*/
bufPtr->st_atime = bufPtr->st_mtime = fpb.ioFlMdDat - TclpGetGMTOffset() + tcl_mac_epoch_offset;
bufPtr->st_ctime = fpb.ioFlCrDat - TclpGetGMTOffset() + tcl_mac_epoch_offset;
}
}
if (err != noErr) {
errno = TclMacOSErrorToPosixError(err);
}
return (err == noErr ? 0 : -1);
}
Tcl_Obj*
TclpObjGetCwd(interp)
Tcl_Interp *interp;
{
Tcl_DString ds;
if (TclpGetCwd(interp, &ds) != NULL) {
Tcl_Obj *cwdPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds), -1);
Tcl_IncrRefCount(cwdPtr);
Tcl_DStringFree(&ds);
return cwdPtr;
} else {
return NULL;
}
}
int
TclpObjChdir(pathPtr)
Tcl_Obj *pathPtr;
{
FSSpec spec;
OSErr err;
Boolean isFolder;
long dirID;
err = FspLocationFromFsPath(pathPtr, &spec);
if (err != noErr) {
errno = ENOENT;
return -1;
}
err = FSpGetDirectoryID(&spec, &dirID, &isFolder);
if (err != noErr) {
errno = ENOENT;
return -1;
}
if (isFolder != true) {
errno = ENOTDIR;
return -1;
}
err = FSpSetDefaultDir(&spec);
if (err != noErr) {
switch (err) {
case afpAccessDenied:
errno = EACCES;
break;
default:
errno = ENOENT;
}
return -1;
}
return 0;
}
int
TclpObjAccess(pathPtr, mode)
Tcl_Obj *pathPtr;
int mode;
{
HFileInfo fpb;
HVolumeParam vpb;
OSErr err;
FSSpec fileSpec;
Boolean isDirectory;
long dirID;
int full_mode = 0;
err = FspLocationFromFsPath(pathPtr, &fileSpec);
if (err != noErr) {
errno = TclMacOSErrorToPosixError(err);
return -1;
}
/*
* Fill the fpb & vpb struct up with info about file or directory.
*/
FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory);
vpb.ioVRefNum = fpb.ioVRefNum = fileSpec.vRefNum;
vpb.ioNamePtr = fpb.ioNamePtr = fileSpec.name;
if (isDirectory) {
fpb.ioDirID = fileSpec.parID;
} else {
fpb.ioDirID = dirID;
}
fpb.ioFDirIndex = 0;
err = PBGetCatInfoSync((CInfoPBPtr)&fpb);
if (err == noErr) {
vpb.ioVolIndex = 0;
err = PBHGetVInfoSync((HParmBlkPtr)&vpb);
if (err == noErr) {
/*
* Use the Volume Info & File Info to determine
* access information. If we have got this far
* we know the directory is searchable or the file
* exists. (We have F_OK)
*/
/*
* Check to see if the volume is hardware or
* software locked. If so we arn't W_OK.
*/
if (mode & W_OK) {
if ((vpb.ioVAtrb & 0x0080) || (vpb.ioVAtrb & 0x8000)) {
errno = EROFS;
return -1;
}
if (fpb.ioFlAttrib & 0x01) {
errno = EACCES;
return -1;
}
}
/*
* Directories are always searchable and executable. But only
* files of type 'APPL' are executable.
*/
if (!(fpb.ioFlAttrib & 0x10) && (mode & X_OK)
&& (fpb.ioFlFndrInfo.fdType != 'APPL')) {
return -1;
}
}
}
if (err != noErr) {
errno = TclMacOSErrorToPosixError(err);
return -1;
}
return 0;
}
int
TclpObjLstat(pathPtr, buf)
Tcl_Obj *pathPtr;
struct stat *buf;
{
return TclpObjStat(pathPtr, buf);
}
/*
*----------------------------------------------------------------------
*
* TclpTempFileName --
*
* This function returns a unique filename.
*
* Results:
* Returns a valid Tcl_Obj* with refCount 0, or NULL on failure.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
Tcl_Obj*
TclpTempFileName()
{
char fileName[L_tmpnam];
if (tmpnam(fileName) == NULL) { /* INTL: Native. */
return NULL;
}
return TclpNativeToNormalized((ClientData) fileName);
}
#ifdef S_IFLNK
Tcl_Obj*
TclpObjReadlink(pathPtr)
Tcl_Obj *pathPtr;
{
Tcl_DString ds;
Tcl_Obj* link = NULL;
if (TclpReadlink(Tcl_FSGetTranslatedPath(NULL, pathPtr), &ds) != NULL) {
link = Tcl_NewStringObj(Tcl_DStringValue(&ds), -1);
Tcl_IncrRefCount(link);
Tcl_DStringFree(&ds);
}
return link;
}
#endif
|
Changes to mac/tclMacInit.c.
1 2 3 4 5 6 7 8 9 10 | /* * tclMacInit.c -- * * Contains the Mac-specific interpreter initialization functions. * * Copyright (c) 1995-1998 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | /* * tclMacInit.c -- * * Contains the Mac-specific interpreter initialization functions. * * Copyright (c) 1995-1998 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclMacInit.c,v 1.5 2001/07/31 19:12:07 vincentdarley Exp $ */ #include <AppleEvents.h> #include <AEDataModel.h> #include <AEObjects.h> #include <AEPackObject.h> #include <AERegistry.h> |
| ︙ | ︙ | |||
127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
static Map cyrillicMap[] = {
{langUkrainian, "macUkraine"},
{langBulgarian, "macBulgaria"},
{NULL, NULL}
};
static int GetFinderFont(int *finderID);
/*
*----------------------------------------------------------------------
*
* GetFinderFont --
*
| > > > > > | 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
static Map cyrillicMap[] = {
{langUkrainian, "macUkraine"},
{langBulgarian, "macBulgaria"},
{NULL, NULL}
};
static int GetFinderFont(int *finderID);
/* Used to store the encoding used for binary files */
static Tcl_Encoding binaryEncoding = NULL;
/* Has the basic library path encoding issue been fixed */
static int libraryPathEncodingFixed = 0;
/*
*----------------------------------------------------------------------
*
* GetFinderFont --
*
|
| ︙ | ︙ | |||
389 390 391 392 393 394 395 | *--------------------------------------------------------------------------- * * TclpSetInitialEncodings -- * * Based on the locale, determine the encoding of the operating * system and the default encoding for newly opened files. * | | > > > | > > | > > | 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 |
*---------------------------------------------------------------------------
*
* TclpSetInitialEncodings --
*
* Based on the locale, determine the encoding of the operating
* system and the default encoding for newly opened files.
*
* Called at process initialization time, and part way through
* startup, we verify that the initial encodings were correctly
* setup. Depending on Tcl's environment, there may not have been
* enough information first time through (above).
*
* Results:
* None.
*
* Side effects:
* The Tcl library path is converted from native encoding to UTF-8,
* on the first call, and the encodings may be changed on first or
* second call.
*
*---------------------------------------------------------------------------
*/
void
TclpSetInitialEncodings()
{
CONST char *encoding;
Tcl_Obj *pathPtr;
int fontId;
fontId = 0;
GetFinderFont(&fontId);
encoding = TclMacGetFontEncoding(fontId);
if (encoding == NULL) {
encoding = "macRoman";
}
Tcl_SetSystemEncoding(NULL, encoding);
if (libraryPathEncodingFixed == 0) {
/*
* Until the system encoding was actually set, the library path was
* actually in the native multi-byte encoding, and not really UTF-8
* as advertised. We cheated as follows:
*
* 1. It was safe to allow the Tcl_SetSystemEncoding() call to
* append the ASCII chars that make up the encoding's filename to
|
| ︙ | ︙ | |||
457 458 459 460 461 462 463 |
string = Tcl_GetStringFromObj(objv[i], &length);
Tcl_ExternalToUtfDString(NULL, string, length, &ds);
Tcl_SetStringObj(objv[i], Tcl_DStringValue(&ds),
Tcl_DStringLength(&ds));
Tcl_DStringFree(&ds);
}
}
| > | > > > | | | | > | < | 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 |
string = Tcl_GetStringFromObj(objv[i], &length);
Tcl_ExternalToUtfDString(NULL, string, length, &ds);
Tcl_SetStringObj(objv[i], Tcl_DStringValue(&ds),
Tcl_DStringLength(&ds));
Tcl_DStringFree(&ds);
}
}
libraryPathEncodingFixed = 1;
}
/* This is only ever called from the startup thread */
if (binaryEncoding == NULL) {
/*
* Keep the iso8859-1 encoding preloaded. The IO package uses
* it for gets on a binary channel.
*/
binaryEncoding = Tcl_GetEncoding(NULL, "iso8859-1");
}
}
/*
*---------------------------------------------------------------------------
*
* TclpSetVariables --
*
|
| ︙ | ︙ |
Changes to mac/tclMacPort.h.
1 2 3 4 5 6 7 8 9 10 11 12 | /* * tclMacPort.h -- * * This header file handles porting issues that occur because of * differences between the Mac and Unix. It should be the only * file that contains #ifdefs to handle different flavors of OS. * * Copyright (c) 1995-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | /* * tclMacPort.h -- * * This header file handles porting issues that occur because of * differences between the Mac and Unix. It should be the only * file that contains #ifdefs to handle different flavors of OS. * * Copyright (c) 1995-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclMacPort.h,v 1.12 2001/07/31 19:12:07 vincentdarley Exp $ */ #ifndef _MACPORT #define _MACPORT #ifndef _TCLINT |
| ︙ | ︙ | |||
215 216 217 218 219 220 221 222 223 224 225 226 227 228 | * so this just keeps the status quo. The real answer is to not use the * MSL strftime, and provide the needed compat functions... * */ #define HAVE_TM_ZONE /* * The following macros have trivial definitions, allowing generic code to * address platform-specific issues. */ #define TclpGetPid(pid) ((unsigned long) (pid)) #define TclSetSystemEnv(a,b) | > > > > > > > > > > > > > > > > > > > > | 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 | * so this just keeps the status quo. The real answer is to not use the * MSL strftime, and provide the needed compat functions... * */ #define HAVE_TM_ZONE /* * If we're using the Metrowerks MSL, we need to convert time_t values from * the mac epoch to the msl epoch (== unix epoch) by adding the offset from * <time.mac.h> to mac time_t values, as MSL is using its epoch for file * access routines such as stat or utime */ #ifdef __MSL__ #include <time.mac.h> #ifdef _mac_msl_epoch_offset_ #define tcl_mac_epoch_offset _mac_msl_epoch_offset_ #define TCL_MAC_USE_MSL_EPOCH /* flag for TclDate.c */ #else #define tcl_mac_epoch_offset 0L #endif #else #define tcl_mac_epoch_offset 0L #endif /* * The following macros have trivial definitions, allowing generic code to * address platform-specific issues. */ #define TclpGetPid(pid) ((unsigned long) (pid)) #define TclSetSystemEnv(a,b) |
| ︙ | ︙ |
Changes to mac/tclMacResource.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* * tclMacResource.c -- * * This file contains several commands that manipulate or use * Macintosh resources. Included are extensions to the "source" * command, the mac specific "beep" and "resource" commands, and * administration for open resource file references. * * Copyright (c) 1996-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* * tclMacResource.c -- * * This file contains several commands that manipulate or use * Macintosh resources. Included are extensions to the "source" * command, the mac specific "beep" and "resource" commands, and * administration for open resource file references. * * Copyright (c) 1996-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclMacResource.c,v 1.8 2001/07/31 19:12:07 vincentdarley Exp $ */ #include <Errors.h> #include <FSpCompat.h> #include <Processes.h> #include <Resources.h> #include <Sound.h> |
| ︙ | ︙ | |||
950 951 952 953 954 955 956 |
if (objc < 2 || objc > 4) {
errStr = errNum;
goto sourceFmtErr;
}
if (objc == 2) {
| < | | 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 |
if (objc < 2 || objc > 4) {
errStr = errNum;
goto sourceFmtErr;
}
if (objc == 2) {
return Tcl_FSEvalFile(interp, objv[1]);
}
/*
* The following code supports a few older forms of this command
* for backward compatability.
*/
string = Tcl_GetStringFromObj(objv[1], &length);
|
| ︙ | ︙ |
Changes to mac/tclMacTime.c.
1 2 3 4 5 6 7 8 9 10 11 | /* * tclMacTime.c -- * * Contains Macintosh specific versions of Tcl functions that * obtain time values from the operating system. * * Copyright (c) 1995-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
/*
* tclMacTime.c --
*
* Contains Macintosh specific versions of Tcl functions that
* obtain time values from the operating system.
*
* Copyright (c) 1995-1997 Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* RCS: @(#) $Id: tclMacTime.c,v 1.4 2001/07/31 19:12:07 vincentdarley Exp $
*/
#include "tclInt.h"
#include "tclPort.h"
#include <OSUtils.h>
#include <Timer.h>
#include <time.h>
/*
* Static variables used by the TclpGetTime function.
*/
static int initalized = false;
static unsigned long baseSeconds;
static UnsignedWide microOffset;
static int gmt_initialized = false;
static long gmt_offset;
static int gmt_isdst;
TCL_DECLARE_MUTEX(gmtMutex)
static int gmt_lastGetDateUseGMT = 0;
/*
* Prototypes for procedures that are private to this file:
*/
static void SubtractUnsignedWide _ANSI_ARGS_((UnsignedWide *x,
UnsignedWide *y, UnsignedWide *result));
/*
*-----------------------------------------------------------------------------
*
* TclpGetGMTOffset --
*
* This procedure gets the offset seconds that needs to be _added_ to tcl time
* in seconds (i.e. GMT time) to get local time needed as input to various
* Mac OS APIs, to convert Mac OS API output to tcl time, _subtract_ this value.
*
* Results:
* Number of seconds separating GMT time and mac.
*
* Side effects:
* None.
*
*-----------------------------------------------------------------------------
*/
long
TclpGetGMTOffset()
{
if (gmt_initialized == false) {
MachineLocation loc;
Tcl_MutexLock(&gmtMutex);
ReadLocation(&loc);
gmt_offset = loc.u.gmtDelta & 0x00ffffff;
if (gmt_offset & 0x00800000) {
gmt_offset = gmt_offset | 0xff000000;
}
gmt_isdst=(loc.u.dlsDelta < 0);
gmt_initialized = true;
Tcl_MutexUnlock(&gmtMutex);
}
return (gmt_offset);
}
/*
*-----------------------------------------------------------------------------
*
* TclpGetSeconds --
*
* This procedure returns the number of seconds from the epoch. On
|
| ︙ | ︙ | |||
53 54 55 56 57 58 59 |
*-----------------------------------------------------------------------------
*/
unsigned long
TclpGetSeconds()
{
unsigned long seconds;
| < < | < < < < < < | | < < < < | 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
*-----------------------------------------------------------------------------
*/
unsigned long
TclpGetSeconds()
{
unsigned long seconds;
GetDateTime(&seconds);
return (seconds - TclpGetGMTOffset() + tcl_mac_epoch_offset);
}
/*
*-----------------------------------------------------------------------------
*
* TclpGetClicks --
*
|
| ︙ | ︙ | |||
119 120 121 122 123 124 125 |
*----------------------------------------------------------------------
*/
int
TclpGetTimeZone (
unsigned long currentTime) /* Ignored on Mac. */
{
| < | < < < < < < | | | 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
*----------------------------------------------------------------------
*/
int
TclpGetTimeZone (
unsigned long currentTime) /* Ignored on Mac. */
{
long offset;
/*
* Convert the Mac offset from seconds to minutes and
* add an hour if we have daylight savings time.
*/
offset = -TclpGetGMTOffset();
offset /= 60;
if (gmt_isdst) {
offset += 60;
}
return offset;
}
/*
|
| ︙ | ︙ | |||
168 169 170 171 172 173 174 |
{
UnsignedWide micro;
#ifndef NO_LONG_LONG
long long *microPtr;
#endif
if (initalized == false) {
| < < < < < < < < | < < < < < | | 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 |
{
UnsignedWide micro;
#ifndef NO_LONG_LONG
long long *microPtr;
#endif
if (initalized == false) {
GetDateTime(&baseSeconds);
/*
* Remove the local offset that ReadDateTime() adds.
*/
baseSeconds -= TclpGetGMTOffset() - tcl_mac_epoch_offset;
Microseconds(µOffset);
initalized = true;
}
Microseconds(µ);
#ifndef NO_LONG_LONG
|
| ︙ | ︙ | |||
242 243 244 245 246 247 248 |
struct tm *
TclpGetDate(
TclpTime_t time, /* Time struct to fill. */
int useGMT) /* True if date should reflect GNT time. */
{
const time_t *tp = (const time_t *)time;
DateTimeRec dtr;
| < | | < < | | | < < < < < | | < > > > | > | 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 |
struct tm *
TclpGetDate(
TclpTime_t time, /* Time struct to fill. */
int useGMT) /* True if date should reflect GNT time. */
{
const time_t *tp = (const time_t *)time;
DateTimeRec dtr;
unsigned long offset=0L;
static struct tm statictime;
static const short monthday[12] =
{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
if(useGMT)
SecondsToDate(*tp - tcl_mac_epoch_offset, &dtr);
else
SecondsToDate(*tp + TclpGetGMTOffset() - tcl_mac_epoch_offset, &dtr);
statictime.tm_sec = dtr.second;
statictime.tm_min = dtr.minute;
statictime.tm_hour = dtr.hour;
statictime.tm_mday = dtr.day;
statictime.tm_mon = dtr.month - 1;
statictime.tm_year = dtr.year - 1900;
statictime.tm_wday = dtr.dayOfWeek - 1;
statictime.tm_yday = monthday[statictime.tm_mon]
+ statictime.tm_mday - 1;
if (1 < statictime.tm_mon && !(statictime.tm_year & 3)) {
++statictime.tm_yday;
}
if(useGMT)
statictime.tm_isdst = 0;
else
statictime.tm_isdst = gmt_isdst;
gmt_lastGetDateUseGMT=useGMT; /* hack to make TclpGetTZName below work */
return(&statictime);
}
#ifdef NO_LONG_LONG
/*
*----------------------------------------------------------------------
*
|
| ︙ | ︙ |
Changes to tests/cmdAH.test.
1 2 3 4 5 6 7 8 9 10 11 12 | # The file tests the tclCmdAH.c file. # # This file contains a collection of tests for one or more of the Tcl # built-in commands. Sourcing this file into Tcl runs the tests and # generates output for errors. No output means no errors were found. # # Copyright (c) 1996-1998 by Sun Microsystems, Inc. # Copyright (c) 1998-1999 by Scriptics Corporation. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # | | > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# The file tests the tclCmdAH.c file.
#
# This file contains a collection of tests for one or more of the Tcl
# built-in commands. Sourcing this file into Tcl runs the tests and
# generates output for errors. No output means no errors were found.
#
# Copyright (c) 1996-1998 by Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: cmdAH.test,v 1.14 2001/07/31 19:12:07 vincentdarley Exp $
if {[lsearch [namespace children] ::tcltest] == -1} {
package require tcltest
namespace import -force ::tcltest::*
}
tcltest::testConstraint testchmod [string equal testchmod [info commands testchmod]]
global env
set cmdAHwd [pwd]
catch {set platform [testgetplatform]}
test cmdAH-0.1 {Tcl_BreakObjCmd, errors} {
list [catch {break foo} msg] $msg
|
| ︙ | ︙ | |||
162 163 164 165 166 167 168 |
} identity
test cmdAH-5.1 {Tcl_FileObjCmd} {
list [catch file msg] $msg
} {1 {wrong # args: should be "file option ?arg ...?"}}
test cmdAH-5.2 {Tcl_FileObjCmd} {
list [catch {file x} msg] $msg
| | | > > | 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
} identity
test cmdAH-5.1 {Tcl_FileObjCmd} {
list [catch file msg] $msg
} {1 {wrong # args: should be "file option ?arg ...?"}}
test cmdAH-5.2 {Tcl_FileObjCmd} {
list [catch {file x} msg] $msg
} {1 {bad option "x": must be atime, attributes, channels, copy, delete, dirname, executable, exists, extension, isdirectory, isfile, join, lstat, mtime, mkdir, nativename, normalize, owned, pathtype, readable, readlink, rename, rootname, separator, size, split, stat, system, tail, type, volumes, or writable}}
test cmdAH-5.3 {Tcl_FileObjCmd} {
list [catch {file exists} msg] $msg
} {1 {wrong # args: should be "file exists name"}}
test cmdAH-5.4 {Tcl_FileObjCmd} {
list [catch {file exists ""} msg] $msg
} {0 0}
#volume
test cmdAH-6.1 {Tcl_FileObjCmd: volumes} {
list [catch {file volumes x} msg] $msg
} {1 {wrong # args: should be "file volumes"}}
test cmdAH-6.2 {Tcl_FileObjCmd: volumes} {
|
| ︙ | ︙ | |||
995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 |
list [catch {file atime ~_bad_user} msg] $msg
} {1 {user "_bad_user" doesn't exist}}
testsetplatform $platform
}
# readable
if {[info commands testchmod] == {}} {
puts "This application hasn't been compiled with the \"testchmod\""
puts "command, so I can't test Tcl_FileObjCmd etc."
} else {
| > > > < < < | | | | | | > | | | | | | < | 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 |
list [catch {file atime ~_bad_user} msg] $msg
} {1 {user "_bad_user" doesn't exist}}
testsetplatform $platform
}
# readable
makeFile abcde gorp.file
makeDirectory dir.file
if {[info commands testchmod] == {}} {
puts "This application hasn't been compiled with the \"testchmod\""
puts "command, so I can't test Tcl_FileObjCmd etc."
} else {
test cmdAH-16.1 {Tcl_FileObjCmd: readable} {testchmod} {
list [catch {file readable a b} msg] $msg
} {1 {wrong # args: should be "file readable name"}}
testchmod 0444 gorp.file
test cmdAH-16.2 {Tcl_FileObjCmd: readable} {testchmod} {
file readable gorp.file
} 1
testchmod 0333 gorp.file
test cmdAH-16.3 {Tcl_FileObjCmd: readable} {unixOnly notRoot testchmod} {
file reada gorp.file
} 0
# writable
test cmdAH-17.1 {Tcl_FileObjCmd: writable} {testchmod} {
list [catch {file writable a b} msg] $msg
} {1 {wrong # args: should be "file writable name"}}
testchmod 0555 gorp.file
test cmdAH-17.2 {Tcl_FileObjCmd: writable} {notRoot testchmod} {
file writable gorp.file
} 0
testchmod 0222 gorp.file
test cmdAH-17.3 {Tcl_FileObjCmd: writable} {testchmod} {
file writable gorp.file
} 1
}
# executable
file delete -force dir.file gorp.file
file mkdir dir.file
makeFile abcde gorp.file
test cmdAH-18.1 {Tcl_FileObjCmd: executable} {testchmod} {
list [catch {file executable a b} msg] $msg
} {1 {wrong # args: should be "file executable name"}}
test cmdAH-18.2 {Tcl_FileObjCmd: executable} {testchmod} {
file executable gorp.file
} 0
test cmdAH-18.3 {Tcl_FileObjCmd: executable} {unixOnly testchmod} {
# Only on unix will setting the execute bit on a regular file
# cause that file to be executable.
testchmod 0775 gorp.file
file exe gorp.file
} 1
test cmdAH-18.4 {Tcl_FileObjCmd: executable} {macOnly testchmod} {
# On mac, the only executable files are of type APPL.
set x [file exe gorp.file]
file attrib gorp.file -type APPL
lappend x [file exe gorp.file]
} {0 1}
test cmdAH-18.5 {Tcl_FileObjCmd: executable} {pcOnly testchmod} {
# On pc, must be a .exe, .com, etc.
set x [file exe gorp.file]
makeFile foo gorp.exe
lappend x [file exe gorp.exe]
file delete gorp.exe
set x
} {0 1}
test cmdAH-18.6 {Tcl_FileObjCmd: executable} {testchmod} {
# Directories are always executable.
file exe dir.file
} 1
file delete -force dir.file
file delete gorp.file
file delete link.file
# exists
test cmdAH-19.1 {Tcl_FileObjCmd: exists} {
list [catch {file exists a b} msg] $msg
} {1 {wrong # args: should be "file exists name"}}
test cmdAH-19.2 {Tcl_FileObjCmd: exists} {file exists gorp.file} 0
|
| ︙ | ︙ | |||
1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 |
} {1 {could not read "_bogus_": no such file or directory} {posix enoent {no such file or directory}}}
test cmdAH-23.6 {Tcl_FileObjCmd: lstat errors} {
catch {unset x}
set x 44
list [catch {file lstat gorp.file x} msg] $msg $errorCode
} {1 {can't set "x(dev)": variable isn't array} NONE}
catch {unset stat}
# mtime
set file [makeFile "data" touch.me]
test cmdAH-24.1 {Tcl_FileObjCmd: mtime} {
list [catch {file mtime a b c} msg] $msg
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 |
} {1 {could not read "_bogus_": no such file or directory} {posix enoent {no such file or directory}}}
test cmdAH-23.6 {Tcl_FileObjCmd: lstat errors} {
catch {unset x}
set x 44
list [catch {file lstat gorp.file x} msg] $msg $errorCode
} {1 {can't set "x(dev)": variable isn't array} NONE}
catch {unset stat}
# mkdir
test cmdAH-23.7 {Tcl_FileObjCmd: mkdir} {
catch {file delete -force a}
file mkdir a
set res [file isdirectory a]
file delete a
set res
} {1}
test cmdAH-23.8 {Tcl_FileObjCmd: mkdir} {
catch {file delete -force a}
file mkdir a/b
set res [file isdirectory a/b]
file delete -force a
set res
} {1}
test cmdAH-23.9 {Tcl_FileObjCmd: mkdir} {
catch {file delete -force a}
file mkdir a/b/c
set res [file isdirectory a/b/c]
file delete -force a
set res
} {1}
test cmdAH-23.10 {Tcl_FileObjCmd: mkdir} {
catch {file delete -force a}
catch {file delete -force b}
file mkdir a/b b/a/c
set res [list [file isdirectory a/b] [file isdirectory b/a/c]]
file delete -force a
file delete -force b
set res
} {1 1}
# mtime
set file [makeFile "data" touch.me]
test cmdAH-24.1 {Tcl_FileObjCmd: mtime} {
list [catch {file mtime a b c} msg] $msg
|
| ︙ | ︙ | |||
1463 1464 1465 1466 1467 1468 1469 |
string tolower [list [catch {file type _bogus_} msg] $msg $errorCode]
} {1 {could not read "_bogus_": no such file or directory} {posix enoent {no such file or directory}}}
# Error conditions
test cmdAH-30.1 {Tcl_FileObjCmd: error conditions} {
list [catch {file gorp x} msg] $msg
| | | | | | | | | 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 |
string tolower [list [catch {file type _bogus_} msg] $msg $errorCode]
} {1 {could not read "_bogus_": no such file or directory} {posix enoent {no such file or directory}}}
# Error conditions
test cmdAH-30.1 {Tcl_FileObjCmd: error conditions} {
list [catch {file gorp x} msg] $msg
} {1 {bad option "gorp": must be atime, attributes, channels, copy, delete, dirname, executable, exists, extension, isdirectory, isfile, join, lstat, mtime, mkdir, nativename, normalize, owned, pathtype, readable, readlink, rename, rootname, separator, size, split, stat, system, tail, type, volumes, or writable}}
test cmdAH-30.2 {Tcl_FileObjCmd: error conditions} {
list [catch {file ex x} msg] $msg
} {1 {ambiguous option "ex": must be atime, attributes, channels, copy, delete, dirname, executable, exists, extension, isdirectory, isfile, join, lstat, mtime, mkdir, nativename, normalize, owned, pathtype, readable, readlink, rename, rootname, separator, size, split, stat, system, tail, type, volumes, or writable}}
test cmdAH-30.3 {Tcl_FileObjCmd: error conditions} {
list [catch {file is x} msg] $msg
} {1 {ambiguous option "is": must be atime, attributes, channels, copy, delete, dirname, executable, exists, extension, isdirectory, isfile, join, lstat, mtime, mkdir, nativename, normalize, owned, pathtype, readable, readlink, rename, rootname, separator, size, split, stat, system, tail, type, volumes, or writable}}
test cmdAH-30.4 {Tcl_FileObjCmd: error conditions} {
list [catch {file z x} msg] $msg
} {1 {bad option "z": must be atime, attributes, channels, copy, delete, dirname, executable, exists, extension, isdirectory, isfile, join, lstat, mtime, mkdir, nativename, normalize, owned, pathtype, readable, readlink, rename, rootname, separator, size, split, stat, system, tail, type, volumes, or writable}}
test cmdAH-30.5 {Tcl_FileObjCmd: error conditions} {
list [catch {file read x} msg] $msg
} {1 {ambiguous option "read": must be atime, attributes, channels, copy, delete, dirname, executable, exists, extension, isdirectory, isfile, join, lstat, mtime, mkdir, nativename, normalize, owned, pathtype, readable, readlink, rename, rootname, separator, size, split, stat, system, tail, type, volumes, or writable}}
test cmdAH-30.6 {Tcl_FileObjCmd: error conditions} {
list [catch {file s x} msg] $msg
} {1 {ambiguous option "s": must be atime, attributes, channels, copy, delete, dirname, executable, exists, extension, isdirectory, isfile, join, lstat, mtime, mkdir, nativename, normalize, owned, pathtype, readable, readlink, rename, rootname, separator, size, split, stat, system, tail, type, volumes, or writable}}
test cmdAH-30.7 {Tcl_FileObjCmd: error conditions} {
list [catch {file t x} msg] $msg
} {1 {ambiguous option "t": must be atime, attributes, channels, copy, delete, dirname, executable, exists, extension, isdirectory, isfile, join, lstat, mtime, mkdir, nativename, normalize, owned, pathtype, readable, readlink, rename, rootname, separator, size, split, stat, system, tail, type, volumes, or writable}}
test cmdAH-30.8 {Tcl_FileObjCmd: error conditions} {
list [catch {file dirname ~woohgy} msg] $msg
} {1 {user "woohgy" doesn't exist}}
# channels
# In testing 'file channels', we need to make sure that a channel
# created in one interp isn't visible in another.
|
| ︙ | ︙ |
Changes to tests/event.test.
1 2 3 4 5 6 7 8 9 10 11 | # This file contains a collection of tests for the procedures in the file # tclEvent.c, which includes the "update", and "vwait" Tcl # commands. Sourcing this file into Tcl runs the tests and generates # output for errors. No output means no errors were found. # # Copyright (c) 1995-1997 Sun Microsystems, Inc. # Copyright (c) 1998-1999 by Scriptics Corporation. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# This file contains a collection of tests for the procedures in the file
# tclEvent.c, which includes the "update", and "vwait" Tcl
# commands. Sourcing this file into Tcl runs the tests and generates
# output for errors. No output means no errors were found.
#
# Copyright (c) 1995-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: event.test,v 1.13 2001/07/31 19:12:07 vincentdarley Exp $
if {[lsearch [namespace children] ::tcltest] == -1} {
package require tcltest
namespace import -force ::tcltest::*
}
set ::tcltest::testConstraints(testfilehandler) \
|
| ︙ | ︙ | |||
166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
}
after idle {error "a simple error"}
after idle {open non_existent}
after idle {set errorInfo foobar; set errorCode xyzzy}
set x {}
update idletasks
rename bgerror {}
set x
} {{{a simple error} {a simple error
while executing
"error "a simple error""
("after" script)} NONE} {{couldn't open "non_existent": no such file or directory} {couldn't open "non_existent": no such file or directory
while executing
"open non_existent"
| > | 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
}
after idle {error "a simple error"}
after idle {open non_existent}
after idle {set errorInfo foobar; set errorCode xyzzy}
set x {}
update idletasks
rename bgerror {}
regsub -all [file join {} non_existent] $x "non_existent" x
set x
} {{{a simple error} {a simple error
while executing
"error "a simple error""
("after" script)} NONE} {{couldn't open "non_existent": no such file or directory} {couldn't open "non_existent": no such file or directory
while executing
"open non_existent"
|
| ︙ | ︙ |
Changes to tests/fCmd.test.
1 2 3 4 5 6 7 8 9 10 11 12 | # This file tests the tclFCmd.c file. # # This file contains a collection of tests for one or more of the Tcl # built-in commands. Sourcing this file into Tcl runs the tests and # generates output for errors. No output means no errors were found. # # Copyright (c) 1996-1997 Sun Microsystems, Inc. # Copyright (c) 1999 by Scriptics Corporation. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # | | < < < < < < | < < | < < < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# This file tests the tclFCmd.c file.
#
# This file contains a collection of tests for one or more of the Tcl
# built-in commands. Sourcing this file into Tcl runs the tests and
# generates output for errors. No output means no errors were found.
#
# Copyright (c) 1996-1997 Sun Microsystems, Inc.
# Copyright (c) 1999 by Scriptics Corporation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: fCmd.test,v 1.10 2001/07/31 19:12:07 vincentdarley Exp $
#
if {[lsearch [namespace children] ::tcltest] == -1} {
package require tcltest
namespace import -force ::tcltest::*
}
tcltest::testConstraint testsetplatform [string equal testsetplatform [info commands testsetplatform]]
tcltest::testConstraint testchmod [string equal testchmod [info commands testchmod]]
# Several tests require need to match results against the unix username
set user {}
if {$tcl_platform(platform) == "unix"} {
catch {set user [exec whoami]}
if {$user == ""} {
catch {regexp {^[^(]*\(([^)]*)\)} [exec id] dummy user}
|
| ︙ | ︙ | |||
70 71 72 73 74 75 76 |
return [string match $matchString $fileString]
}
proc openup {path} {
testchmod 777 $path
if {[file isdirectory $path]} {
catch {
| | > > > > > | | | 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
return [string match $matchString $fileString]
}
proc openup {path} {
testchmod 777 $path
if {[file isdirectory $path]} {
catch {
foreach p [glob -directory $path *] {
openup $p
}
}
}
}
proc cleanup {args} {
if {$::tcl_platform(platform) == "macintosh"} {
set wd [list :]
} else {
set wd [list .]
}
foreach p [concat $wd $args] {
set x ""
catch {
set x [glob -directory $p tf* td*]
}
foreach file $x {
if {[catch {file delete -force -- $file}]} {
catch {openup $file}
catch {file delete -force -- $file}
}
}
|
| ︙ | ︙ | |||
295 296 297 298 299 300 301 |
cleanup
file mkdir td1
set x [file exist td1]
file mkdir td1
list $x [file exist td1]
} {1 1}
test fCmd-4.11 {TclFileMakeDirsCmd: doesn't exist: errno != ENOENT} \
| | | | | 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 |
cleanup
file mkdir td1
set x [file exist td1]
file mkdir td1
list $x [file exist td1]
} {1 1}
test fCmd-4.11 {TclFileMakeDirsCmd: doesn't exist: errno != ENOENT} \
{unixOnly notRoot testchmod} {
cleanup
file mkdir td1/td2/td3
testchmod 000 td1/td2
set msg [list [catch {file mkdir td1/td2/td3/td4} msg] $msg]
testchmod 755 td1/td2
set msg
} {1 {can't create directory "td1/td2/td3": permission denied}}
test fCmd-4.12 {TclFileMakeDirsCmd: doesn't exist: errno != ENOENT} {macOnly} {
cleanup
list [catch {file mkdir nonexistentvolume:} msg] $msg
} {1 {can't create directory "nonexistentvolume:": invalid argument}}
test fCmd-4.13 {TclFileMakeDirsCmd: doesn't exist: errno == ENOENT} {notRoot} {
cleanup
set x [file exist td1]
file mkdir td1
list $x [file exist td1]
} {0 1}
test fCmd-4.14 {TclFileMakeDirsCmd: TclpCreateDirectory fails} \
|
| ︙ | ︙ | |||
411 412 413 414 415 416 417 |
} {tf2}
test fCmd-6.5 {CopyRenameOneFile: lstat(target) != 0} {notRoot} {
cleanup
createfile tf1
file rename tf1 tf2
glob tf*
} {tf2}
| | | 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 |
} {tf2}
test fCmd-6.5 {CopyRenameOneFile: lstat(target) != 0} {notRoot} {
cleanup
createfile tf1
file rename tf1 tf2
glob tf*
} {tf2}
test fCmd-6.6 {CopyRenameOneFile: errno != ENOENT} {unixOnly notRoot testchmod} {
cleanup
file mkdir td1
testchmod 000 td1
createfile tf1
set msg [list [catch {file rename tf1 td1} msg] $msg]
testchmod 755 td1
set msg
|
| ︙ | ︙ | |||
672 673 674 675 676 677 678 |
file delete -force td1
set result
} {1 {error renaming "td1" to "td2/td1": permission denied}}
test fCmd-9.2 {file rename: comprehensive: source doesn't exist} {notRoot} {
cleanup
list [catch {file rename tf1 tf2} msg] $msg
} {1 {error renaming "tf1": no such file or directory}}
| | | | | | | 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 |
file delete -force td1
set result
} {1 {error renaming "td1" to "td2/td1": permission denied}}
test fCmd-9.2 {file rename: comprehensive: source doesn't exist} {notRoot} {
cleanup
list [catch {file rename tf1 tf2} msg] $msg
} {1 {error renaming "tf1": no such file or directory}}
test fCmd-9.3 {file rename: comprehensive: file to new name} {notRoot testchmod} {
cleanup
createfile tf1
createfile tf2
testchmod 444 tf2
file rename tf1 tf3
file rename tf2 tf4
list [lsort [glob tf*]] [file writable tf3] [file writable tf4]
} {{tf3 tf4} 1 0}
test fCmd-9.4 {file rename: comprehensive: dir to new name} {unixOrPc notRoot testchmod} {
cleanup
file mkdir td1 td2
testchmod 555 td2
file rename td1 td3
file rename td2 td4
list [lsort [glob td*]] [file writable td3] [file writable td4]
} {{td3 td4} 1 0}
test fCmd-9.5 {file rename: comprehensive: file to self} {notRoot testchmod} {
cleanup
createfile tf1 tf1
createfile tf2 tf2
testchmod 444 tf2
file rename -force tf1 tf1
file rename -force tf2 tf2
list [contents tf1] [contents tf2] [file writable tf1] [file writable tf2]
} {tf1 tf2 1 0}
test fCmd-9.6 {file rename: comprehensive: dir to self} {notRoot unixOrPc testchmod} {
cleanup
file mkdir td1
file mkdir td2
testchmod 555 td2
file rename -force td1 .
file rename -force td2 .
list [lsort [glob td*]] [file writable td1] [file writable td2]
} {{td1 td2} 1 0}
test fCmd-9.7 {file rename: comprehensive: file to existing file} {notRoot testchmod} {
cleanup
createfile tf1
createfile tf2
createfile tfs1
createfile tfs2
createfile tfs3
createfile tfs4
|
| ︙ | ︙ | |||
730 731 732 733 734 735 736 |
set msg [list [catch {file rename tf1 tf2} msg] $msg]
file rename -force tfs1 tfd1
file rename -force tfs2 tfd2
file rename -force tfs3 tfd3
file rename -force tfs4 tfd4
list [lsort [glob tf*]] $msg [file writable tfd1] [file writable tfd2] [file writable tfd3] [file writable tfd4]
} {{tf1 tf2 tfd1 tfd2 tfd3 tfd4} {1 {error renaming "tf1" to "tf2": file already exists}} 1 1 0 0}
| | | 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 |
set msg [list [catch {file rename tf1 tf2} msg] $msg]
file rename -force tfs1 tfd1
file rename -force tfs2 tfd2
file rename -force tfs3 tfd3
file rename -force tfs4 tfd4
list [lsort [glob tf*]] $msg [file writable tfd1] [file writable tfd2] [file writable tfd3] [file writable tfd4]
} {{tf1 tf2 tfd1 tfd2 tfd3 tfd4} {1 {error renaming "tf1" to "tf2": file already exists}} 1 1 0 0}
test fCmd-9.8 {file rename: comprehensive: dir to empty dir} {notRoot testchmod} {
# Under unix, you can rename a read-only directory, but you can't
# move it into another directory.
cleanup
file mkdir td1
file mkdir [file join td2 td1]
file mkdir tds1
|
| ︙ | ︙ | |||
768 769 770 771 772 773 774 |
} else {
set w3 0
set w4 0
}
list [lsort [glob td*]] $msg [file writable [file join tdd1 tds1]] \
[file writable [file join tdd2 tds2]] $w3 $w4
} [subst {{td1 td2 tdd1 tdd2 tdd3 tdd4} {1 {error renaming "td1" to "[file join td2 td1]": file already exists}} 1 1 0 0}]
| | | | | | | | 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 |
} else {
set w3 0
set w4 0
}
list [lsort [glob td*]] $msg [file writable [file join tdd1 tds1]] \
[file writable [file join tdd2 tds2]] $w3 $w4
} [subst {{td1 td2 tdd1 tdd2 tdd3 tdd4} {1 {error renaming "td1" to "[file join td2 td1]": file already exists}} 1 1 0 0}]
test fCmd-9.9 {file rename: comprehensive: dir to non-empty dir} {notRoot testchmod} {
cleanup
file mkdir tds1
file mkdir tds2
file mkdir [file join tdd1 tds1 xxx]
file mkdir [file join tdd2 tds2 xxx]
if {$tcl_platform(platform) != "unix" && $tcl_platform(platform) != "macintosh"} {
testchmod 555 tds2
}
set a1 [list [catch {file rename -force tds1 tdd1} msg] $msg]
set a2 [list [catch {file rename -force tds2 tdd2} msg] $msg]
if {$tcl_platform(platform) != "unix" && $tcl_platform(platform) != "macintosh"} {
set w2 [file writable tds2]
} else {
set w2 0
}
list [lsort [glob td*]] $a1 $a2 [file writable tds1] $w2
} [subst {{tdd1 tdd2 tds1 tds2} {1 {error renaming "tds1" to "[file join tdd1 tds1]": file already exists}} {1 {error renaming "tds2" to "[file join tdd2 tds2]": file already exists}} 1 0}]
test fCmd-9.10 {file rename: comprehensive: file to new name and dir} {notRoot testchmod} {
cleanup
createfile tf1
createfile tf2
file mkdir td1
testchmod 444 tf2
file rename tf1 [file join td1 tf3]
file rename tf2 [file join td1 tf4]
list [catch {glob tf*}] [lsort [glob -directory td1 t*]] \
[file writable [file join td1 tf3]] [file writable [file join td1 tf4]]
} [subst {1 {[file join td1 tf3] [file join td1 tf4]} 1 0}]
test fCmd-9.11 {file rename: comprehensive: dir to new name and dir} {notRoot testchmod} {
cleanup
file mkdir td1
file mkdir td2
file mkdir td3
if {$tcl_platform(platform) != "unix" && $tcl_platform(platform) != "macintosh"} {
testchmod 555 td2
}
file rename td1 [file join td3 td3]
file rename td2 [file join td3 td4]
if {$tcl_platform(platform) != "unix" && $tcl_platform(platform) != "macintosh"} {
set w4 [file writable [file join td3 td4]]
} else {
set w4 0
}
list [lsort [glob td*]] [lsort [glob -directory td3 t*]] \
[file writable [file join td3 td3]] $w4
} [subst {td3 {[file join td3 td3] [file join td3 td4]} 1 0}]
test fCmd-9.12 {file rename: comprehensive: target exists} {notRoot testchmod} {
cleanup
file mkdir [file join td1 td2] [file join td2 td1]
if {$tcl_platform(platform) != "macintosh"} {
testchmod 555 [file join td2 td1]
}
file mkdir [file join td3 td4] [file join td4 td3]
file rename -force td3 td4
|
| ︙ | ︙ | |||
859 860 861 862 863 864 865 |
list [catch {file rename -force tf1 td1} msg] $msg
} [subst {1 {can't overwrite directory "[file join td1 tf1]" with file "tf1"}}]
test fCmd-10.1 {file copy: comprehensive: source doesn't exist} {notRoot} {
cleanup
list [catch {file copy tf1 tf2} msg] $msg
} {1 {error copying "tf1": no such file or directory}}
| | | | | | | 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 |
list [catch {file rename -force tf1 td1} msg] $msg
} [subst {1 {can't overwrite directory "[file join td1 tf1]" with file "tf1"}}]
test fCmd-10.1 {file copy: comprehensive: source doesn't exist} {notRoot} {
cleanup
list [catch {file copy tf1 tf2} msg] $msg
} {1 {error copying "tf1": no such file or directory}}
test fCmd-10.2 {file copy: comprehensive: file to new name} {notRoot testchmod} {
cleanup
createfile tf1 tf1
createfile tf2 tf2
testchmod 444 tf2
file copy tf1 tf3
file copy tf2 tf4
list [lsort [glob tf*]] [contents tf3] [contents tf4] [file writable tf3] [file writable tf4]
} {{tf1 tf2 tf3 tf4} tf1 tf2 1 0}
test fCmd-10.3 {file copy: comprehensive: dir to new name} {notRoot unixOrPc testchmod} {
cleanup
file mkdir [file join td1 tdx]
file mkdir [file join td2 tdy]
testchmod 555 td2
file copy td1 td3
file copy td2 td4
set msg [list [lsort [glob td*]] [glob -directory td3 t*] \
[glob -directory td4 t*] [file writable td3] [file writable td4]]
if {$tcl_platform(platform) != "macintosh"} {
testchmod 755 td2
testchmod 755 td4
}
set msg
} [subst {{td1 td2 td3 td4} [file join td3 tdx] [file join td4 tdy] 1 0}]
test fCmd-10.4 {file copy: comprehensive: file to existing file} {notRoot testchmod} {
cleanup
createfile tf1
createfile tf2
createfile tfs1
createfile tfs2
createfile tfs3
createfile tfs4
|
| ︙ | ︙ | |||
906 907 908 909 910 911 912 |
set msg [list [catch {file copy tf1 tf2} msg] $msg]
file copy -force tfs1 tfd1
file copy -force tfs2 tfd2
file copy -force tfs3 tfd3
file copy -force tfs4 tfd4
list [lsort [glob tf*]] $msg [file writable tfd1] [file writable tfd2] [file writable tfd3] [file writable tfd4]
} {{tf1 tf2 tfd1 tfd2 tfd3 tfd4 tfs1 tfs2 tfs3 tfs4} {1 {error copying "tf1" to "tf2": file already exists}} 1 1 0 0}
| | | 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 |
set msg [list [catch {file copy tf1 tf2} msg] $msg]
file copy -force tfs1 tfd1
file copy -force tfs2 tfd2
file copy -force tfs3 tfd3
file copy -force tfs4 tfd4
list [lsort [glob tf*]] $msg [file writable tfd1] [file writable tfd2] [file writable tfd3] [file writable tfd4]
} {{tf1 tf2 tfd1 tfd2 tfd3 tfd4 tfs1 tfs2 tfs3 tfs4} {1 {error copying "tf1" to "tf2": file already exists}} 1 1 0 0}
test fCmd-10.5 {file copy: comprehensive: dir to empty dir} {notRoot testchmod} {
cleanup
file mkdir td1
file mkdir [file join td2 td1]
file mkdir tds1
file mkdir tds2
file mkdir tds3
file mkdir tds4
|
| ︙ | ︙ | |||
932 933 934 935 936 937 938 |
set a2 [list [catch {file copy -force tds1 tdd1} msg] $msg]
set a3 [catch {file copy -force tds2 tdd2}]
set a4 [catch {file copy -force tds3 tdd3}]
set a5 [catch {file copy -force tds4 tdd4}]
list [lsort [glob td*]] $a1 $a2 $a3 $a4 $a5
} [subst {{td1 td2 tdd1 tdd2 tdd3 tdd4 tds1 tds2 tds3 tds4} {1 {error copying "td1" to "[file join td2 td1]": file already exists}} {1 {error copying "tds1" to "[file join tdd1 tds1]": file already exists}} 1 1 1}]
test fCmd-10.6 {file copy: comprehensive: dir to non-empty dir} \
| | | | | | | 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 |
set a2 [list [catch {file copy -force tds1 tdd1} msg] $msg]
set a3 [catch {file copy -force tds2 tdd2}]
set a4 [catch {file copy -force tds3 tdd3}]
set a5 [catch {file copy -force tds4 tdd4}]
list [lsort [glob td*]] $a1 $a2 $a3 $a4 $a5
} [subst {{td1 td2 tdd1 tdd2 tdd3 tdd4 tds1 tds2 tds3 tds4} {1 {error copying "td1" to "[file join td2 td1]": file already exists}} {1 {error copying "tds1" to "[file join tdd1 tds1]": file already exists}} 1 1 1}]
test fCmd-10.6 {file copy: comprehensive: dir to non-empty dir} \
{notRoot unixOrPc testchmod} {
cleanup
file mkdir tds1
file mkdir tds2
file mkdir [file join tdd1 tds1 xxx]
file mkdir [file join tdd2 tds2 xxx]
testchmod 555 tds2
set a1 [list [catch {file copy -force tds1 tdd1} msg] $msg]
set a2 [list [catch {file copy -force tds2 tdd2} msg] $msg]
list [lsort [glob td*]] $a1 $a2 [file writable tds1] [file writable tds2]
} [subst {{tdd1 tdd2 tds1 tds2} {1 {error copying "tds1" to "[file join tdd1 tds1]": file already exists}} {1 {error copying "tds2" to "[file join tdd2 tds2]": file already exists}} 1 0}]
test fCmd-10.7 {file rename: comprehensive: file to new name and dir} {notRoot testchmod} {
cleanup
createfile tf1
createfile tf2
file mkdir td1
testchmod 444 tf2
file copy tf1 [file join td1 tf3]
file copy tf2 [file join td1 tf4]
list [lsort [glob tf*]] [lsort [glob -directory td1 t*]] \
[file writable [file join td1 tf3]] [file writable [file join td1 tf4]]
} [subst {{tf1 tf2} {[file join td1 tf3] [file join td1 tf4]} 1 0}]
test fCmd-10.8 {file rename: comprehensive: dir to new name and dir} \
{notRoot unixOrPc testchmod} {
cleanup
file mkdir td1
file mkdir td2
file mkdir td3
testchmod 555 td2
file copy td1 [file join td3 td3]
file copy td2 [file join td3 td4]
list [lsort [glob td*]] [lsort [glob -directory td3 t*]] \
[file writable [file join td3 td3]] [file writable [file join td3 td4]]
} [subst {{td1 td2 td3} {[file join td3 td3] [file join td3 td4]} 1 0}]
test fCmd-10.9 {file copy: comprehensive: source and target incompatible} \
{notRoot} {
cleanup
file mkdir td1
createfile tf1
|
| ︙ | ︙ | |||
2107 2108 2109 2110 2111 2112 2113 |
set r1 [file exists tfad1]
set r2 [file exists tfad2]
set result [expr !$r1 && !$r2]
set result
} {1}
| | > | 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 |
set r1 [file exists tfad1]
set r2 [file exists tfad2]
set result [expr !$r1 && !$r2]
set result
} {1}
test fCmd-27.2 {TclFileAttrsCmd - Tcl_TranslateFileName fails} {testsetplatform} {
set platform [testgetplatform]
testsetplatform unix
list [catch {file attributes ~_totally_bogus_user} msg] $msg [testsetplatform $platform]
} {1 {user "_totally_bogus_user" doesn't exist} {}}
test fCmd-27.3 {TclFileAttrsCmd - all attributes} {
catch {file delete -force -- foo.tmp}
createfile foo.tmp
list [catch {file attributes foo.tmp} msg] [expr {[llength $msg] > 0}] [file delete -force -- foo.tmp]
|
| ︙ | ︙ |
Changes to tests/fileName.test.
1 2 3 4 5 6 7 8 9 10 11 12 | # This file tests the filename manipulation routines. # # This file contains a collection of tests for one or more of the Tcl # built-in commands. Sourcing this file into Tcl runs the tests and # generates output for errors. No output means no errors were found. # # Copyright (c) 1995-1996 Sun Microsystems, Inc. # Copyright (c) 1999 by Scriptics Corporation. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # | | | < < | < | < > | | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > > > > | < < < < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > | > | | | | | > | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 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 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 |
# This file tests the filename manipulation routines.
#
# This file contains a collection of tests for one or more of the Tcl
# built-in commands. Sourcing this file into Tcl runs the tests and
# generates output for errors. No output means no errors were found.
#
# Copyright (c) 1995-1996 Sun Microsystems, Inc.
# Copyright (c) 1999 by Scriptics Corporation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: fileName.test,v 1.11 2001/07/31 19:12:07 vincentdarley Exp $
if {[lsearch [namespace children] ::tcltest] == -1} {
package require tcltest
namespace import -force ::tcltest::*
}
tcltest::testConstraint testsetplatform [string equal testsetplatform [info commands testsetplatform]]
tcltest::testConstraint testtranslatefilename [string equal testtranslatefilename [info commands testtranslatefilename]]
global env
if {[tcltest::testConstraint testsetplatform]} {
set platform [testgetplatform]
}
test filename-1.1 {Tcl_GetPathType: unix} {testsetplatform} {
testsetplatform unix
file pathtype /
} absolute
test filename-1.2 {Tcl_GetPathType: unix} {testsetplatform} {
testsetplatform unix
file pathtype /foo
} absolute
test filename-1.3 {Tcl_GetPathType: unix} {testsetplatform} {
testsetplatform unix
file pathtype foo
} relative
test filename-1.4 {Tcl_GetPathType: unix} {testsetplatform} {
testsetplatform unix
file pathtype c:/foo
} relative
test filename-1.5 {Tcl_GetPathType: unix} {testsetplatform} {
testsetplatform unix
file pathtype ~
} absolute
test filename-1.6 {Tcl_GetPathType: unix} {testsetplatform} {
testsetplatform unix
file pathtype ~/foo
} absolute
test filename-1.7 {Tcl_GetPathType: unix} {testsetplatform} {
testsetplatform unix
file pathtype ~foo
} absolute
test filename-1.8 {Tcl_GetPathType: unix} {testsetplatform} {
testsetplatform unix
file pathtype ./~foo
} relative
test filename-2.1 {Tcl_GetPathType: mac, denerate names} {testsetplatform} {
testsetplatform mac
file pathtype /
} relative
test filename-2.2 {Tcl_GetPathType: mac, denerate names} {testsetplatform} {
testsetplatform mac
file pathtype /.
} relative
test filename-2.3 {Tcl_GetPathType: mac, denerate names} {testsetplatform} {
testsetplatform mac
file pathtype /..
} relative
test filename-2.4 {Tcl_GetPathType: mac, denerate names} {testsetplatform} {
testsetplatform mac
file pathtype //.//
} relative
test filename-2.5 {Tcl_GetPathType: mac, denerate names} {testsetplatform} {
testsetplatform mac
file pathtype //.//../.
} relative
test filename-2.6 {Tcl_GetPathType: mac, tilde names} {testsetplatform} {
testsetplatform mac
file pathtype ~
} absolute
test filename-2.7 {Tcl_GetPathType: mac, tilde names} {testsetplatform} {
testsetplatform mac
file pathtype ~:
} absolute
test filename-2.8 {Tcl_GetPathType: mac, tilde names} {testsetplatform} {
testsetplatform mac
file pathtype ~:foo
} absolute
test filename-2.9 {Tcl_GetPathType: mac, tilde names} {testsetplatform} {
testsetplatform mac
file pathtype ~/
} absolute
test filename-2.10 {Tcl_GetPathType: mac, tilde names} {testsetplatform} {
testsetplatform mac
file pathtype ~/foo
} absolute
test filename-2.11 {Tcl_GetPathType: mac, unix-style names} {testsetplatform} {
testsetplatform mac
file pathtype /foo
} absolute
test filename-2.12 {Tcl_GetPathType: mac, unix-style names} {testsetplatform} {
testsetplatform mac
file pathtype /./foo
} absolute
test filename-2.13 {Tcl_GetPathType: mac, unix-style names} {testsetplatform} {
testsetplatform mac
file pathtype /..//./foo
} absolute
test filename-2.14 {Tcl_GetPathType: mac, unix-style names} {testsetplatform} {
testsetplatform mac
file pathtype /foo/bar
} absolute
test filename-2.15 {Tcl_GetPathType: mac, unix-style names} {testsetplatform} {
testsetplatform mac
file pathtype foo/bar
} relative
test filename-2.16 {Tcl_GetPathType: mac, mac-style names} {testsetplatform} {
testsetplatform mac
file pathtype :
} relative
test filename-2.17 {Tcl_GetPathType: mac, mac-style names} {testsetplatform} {
testsetplatform mac
file pathtype :foo
} relative
test filename-2.18 {Tcl_GetPathType: mac, mac-style names} {testsetplatform} {
testsetplatform mac
file pathtype foo:
} absolute
test filename-2.19 {Tcl_GetPathType: mac, mac-style names} {testsetplatform} {
testsetplatform mac
file pathtype foo:bar
} absolute
test filename-2.20 {Tcl_GetPathType: mac, mac-style names} {testsetplatform} {
testsetplatform mac
file pathtype :foo:bar
} relative
test filename-2.21 {Tcl_GetPathType: mac, mac-style names} {testsetplatform} {
testsetplatform mac
file pathtype ::foo:bar
} relative
test filename-2.22 {Tcl_GetPathType: mac, mac-style names} {testsetplatform} {
testsetplatform mac
file pathtype ~foo
} absolute
test filename-2.23 {Tcl_GetPathType: mac, mac-style names} {testsetplatform} {
testsetplatform mac
file pathtype :~foo
} relative
test filename-2.24 {Tcl_GetPathType: mac, mac-style names} {testsetplatform} {
testsetplatform mac
file pathtype ~foo:
} absolute
test filename-2.25 {Tcl_GetPathType: mac, mac-style names} {testsetplatform} {
testsetplatform mac
file pathtype foo/bar:
} absolute
test filename-2.26 {Tcl_GetPathType: mac, mac-style names} {testsetplatform} {
testsetplatform mac
file pathtype /foo:
} absolute
test filename-2.27 {Tcl_GetPathType: mac, mac-style names} {testsetplatform} {
testsetplatform mac
file pathtype foo
} relative
test filename-3.1 {Tcl_GetPathType: windows} {testsetplatform} {
testsetplatform windows
file pathtype /
} volumerelative
test filename-3.2 {Tcl_GetPathType: windows} {testsetplatform} {
testsetplatform windows
file pathtype \\
} volumerelative
test filename-3.3 {Tcl_GetPathType: windows} {testsetplatform} {
testsetplatform windows
file pathtype /foo
} volumerelative
test filename-3.4 {Tcl_GetPathType: windows} {testsetplatform} {
testsetplatform windows
file pathtype \\foo
} volumerelative
test filename-3.5 {Tcl_GetPathType: windows} {testsetplatform} {
testsetplatform windows
file pathtype c:/
} absolute
test filename-3.6 {Tcl_GetPathType: windows} {testsetplatform} {
testsetplatform windows
file pathtype c:\\
} absolute
test filename-3.7 {Tcl_GetPathType: windows} {testsetplatform} {
testsetplatform windows
file pathtype c:/foo
} absolute
test filename-3.8 {Tcl_GetPathType: windows} {testsetplatform} {
testsetplatform windows
file pathtype c:\\foo
} absolute
test filename-3.9 {Tcl_GetPathType: windows} {testsetplatform} {
testsetplatform windows
file pathtype c:
} volumerelative
test filename-3.10 {Tcl_GetPathType: windows} {testsetplatform} {
testsetplatform windows
file pathtype c:foo
} volumerelative
test filename-3.11 {Tcl_GetPathType: windows} {testsetplatform} {
testsetplatform windows
file pathtype foo
} relative
test filename-3.12 {Tcl_GetPathType: windows} {testsetplatform} {
testsetplatform windows
file pathtype //foo/bar
} absolute
test filename-3.13 {Tcl_GetPathType: windows} {testsetplatform} {
testsetplatform windows
file pathtype ~foo
} absolute
test filename-3.14 {Tcl_GetPathType: windows} {testsetplatform} {
testsetplatform windows
file pathtype ~
} absolute
test filename-3.15 {Tcl_GetPathType: windows} {testsetplatform} {
testsetplatform windows
file pathtype ~/foo
} absolute
test filename-3.16 {Tcl_GetPathType: windows} {testsetplatform} {
testsetplatform windows
file pathtype ./~foo
} relative
test filename-4.1 {Tcl_SplitPath: unix} {testsetplatform} {
testsetplatform unix
file split /
} {/}
test filename-4.2 {Tcl_SplitPath: unix} {testsetplatform} {
testsetplatform unix
file split /foo
} {/ foo}
test filename-4.3 {Tcl_SplitPath: unix} {testsetplatform} {
testsetplatform unix
file split /foo/bar
} {/ foo bar}
test filename-4.4 {Tcl_SplitPath: unix} {testsetplatform} {
testsetplatform unix
file split /foo/bar/baz
} {/ foo bar baz}
test filename-4.5 {Tcl_SplitPath: unix} {testsetplatform} {
testsetplatform unix
file split foo/bar
} {foo bar}
test filename-4.6 {Tcl_SplitPath: unix} {testsetplatform} {
testsetplatform unix
file split ./foo/bar
} {. foo bar}
test filename-4.7 {Tcl_SplitPath: unix} {testsetplatform} {
testsetplatform unix
file split /foo/../././foo/bar
} {/ foo .. . . foo bar}
test filename-4.8 {Tcl_SplitPath: unix} {testsetplatform} {
testsetplatform unix
file split ../foo/bar
} {.. foo bar}
test filename-4.9 {Tcl_SplitPath: unix} {testsetplatform} {
testsetplatform unix
file split {}
} {}
test filename-4.10 {Tcl_SplitPath: unix} {testsetplatform} {
testsetplatform unix
file split .
} {.}
test filename-4.11 {Tcl_SplitPath: unix} {testsetplatform} {
testsetplatform unix
file split ../
} {..}
test filename-4.12 {Tcl_SplitPath: unix} {testsetplatform} {
testsetplatform unix
file split ../..
} {.. ..}
test filename-4.13 {Tcl_SplitPath: unix} {testsetplatform} {
testsetplatform unix
file split //foo
} {/ foo}
test filename-4.14 {Tcl_SplitPath: unix} {testsetplatform} {
testsetplatform unix
file split foo//bar
} {foo bar}
test filename-4.15 {Tcl_SplitPath: unix} {testsetplatform} {
testsetplatform unix
file split ~foo
} {~foo}
test filename-4.16 {Tcl_SplitPath: unix} {testsetplatform} {
testsetplatform unix
file split ~foo/~bar
} {~foo ./~bar}
test filename-4.17 {Tcl_SplitPath: unix} {testsetplatform} {
testsetplatform unix
file split ~foo/~bar/~baz
} {~foo ./~bar ./~baz}
test filename-4.18 {Tcl_SplitPath: unix} {testsetplatform} {
testsetplatform unix
file split foo/bar~/baz
} {foo bar~ baz}
test filename-5.1 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split a:b
} {a: b}
test filename-5.2 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split a:b:c
} {a: b c}
test filename-5.3 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split a:b:c:
} {a: b c}
test filename-5.4 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split a:
} {a:}
test filename-5.5 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split a::
} {a: ::}
test filename-5.6 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split a:::
} {a: :: ::}
test filename-5.7 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split :a
} {a}
test filename-5.8 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split :a::
} {a ::}
test filename-5.9 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split :
} {:}
test filename-5.10 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split ::
} {::}
test filename-5.11 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split :::
} {:: ::}
test filename-5.12 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split a:::b
} {a: :: :: b}
test filename-5.13 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split /a:b
} {/a: b}
test filename-5.14 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split ~:
} {~:}
test filename-5.15 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split ~/:
} {~/:}
test filename-5.16 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split ~:foo
} {~: foo}
test filename-5.17 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split ~/foo
} {~: foo}
test filename-5.18 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split ~foo:
} {~foo:}
test filename-5.19 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split a:~foo
} {a: :~foo}
test filename-5.20 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split /
} {:/}
test filename-5.21 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split a:b/c
} {a: :b/c}
test filename-5.22 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split /foo
} {foo:}
test filename-5.23 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split /a/b
} {a: b}
test filename-5.24 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split /a/b/foo
} {a: b foo}
test filename-5.25 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split a/b
} {a b}
test filename-5.26 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split ./foo/bar
} {: foo bar}
test filename-5.27 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split ../foo/bar
} {:: foo bar}
test filename-5.28 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split {}
} {}
test filename-5.29 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split .
} {:}
test filename-5.30 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split ././
} {: :}
test filename-5.31 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split ././.
} {: : :}
test filename-5.32 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split ../
} {::}
test filename-5.33 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split ..
} {::}
test filename-5.34 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split ../..
} {:: ::}
test filename-5.35 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split //foo
} {foo:}
test filename-5.36 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split foo//bar
} {foo bar}
test filename-5.37 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split ~foo
} {~foo:}
test filename-5.38 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split ~
} {~:}
test filename-5.39 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split foo
} {foo}
test filename-5.40 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split ~/
} {~:}
test filename-5.41 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split ~foo/~bar
} {~foo: :~bar}
test filename-5.42 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split ~foo/~bar/~baz
} {~foo: :~bar :~baz}
test filename-5.43 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split foo/bar~/baz
} {foo bar~ baz}
test filename-5.44 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split a/../b
} {a :: b}
test filename-5.45 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split a/../../b
} {a :: :: b}
test filename-5.46 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split a/.././../b
} {a :: : :: b}
test filename-5.47 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split /../bar
} {bar:}
test filename-5.48 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split /./bar
} {bar:}
test filename-5.49 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split //.//.././bar
} {bar:}
test filename-5.50 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split /..
} {:/..}
test filename-5.51 {Tcl_SplitPath: mac} {testsetplatform} {
testsetplatform mac
file split //.//.././
} {://.//.././}
test filename-6.1 {Tcl_SplitPath: win} {testsetplatform} {
testsetplatform win
file split /
} {/}
test filename-6.2 {Tcl_SplitPath: win} {testsetplatform} {
testsetplatform win
file split /foo
} {/ foo}
test filename-6.3 {Tcl_SplitPath: win} {testsetplatform} {
testsetplatform win
file split /foo/bar
} {/ foo bar}
test filename-6.4 {Tcl_SplitPath: win} {testsetplatform} {
testsetplatform win
file split /foo/bar/baz
} {/ foo bar baz}
test filename-6.5 {Tcl_SplitPath: win} {testsetplatform} {
testsetplatform win
file split foo/bar
} {foo bar}
test filename-6.6 {Tcl_SplitPath: win} {testsetplatform} {
testsetplatform win
file split ./foo/bar
} {. foo bar}
test filename-6.7 {Tcl_SplitPath: win} {testsetplatform} {
testsetplatform win
file split /foo/../././foo/bar
} {/ foo .. . . foo bar}
test filename-6.8 {Tcl_SplitPath: win} {testsetplatform} {
testsetplatform win
file split ../foo/bar
} {.. foo bar}
test filename-6.9 {Tcl_SplitPath: win} {testsetplatform} {
testsetplatform win
file split {}
} {}
test filename-6.10 {Tcl_SplitPath: win} {testsetplatform} {
testsetplatform win
file split .
} {.}
test filename-6.11 {Tcl_SplitPath: win} {testsetplatform} {
testsetplatform win
file split ../
} {..}
test filename-6.12 {Tcl_SplitPath: win} {testsetplatform} {
testsetplatform win
file split ../..
} {.. ..}
test filename-6.13 {Tcl_SplitPath: win} {testsetplatform} {
testsetplatform win
file split //foo
} {/ foo}
test filename-6.14 {Tcl_SplitPath: win} {testsetplatform} {
testsetplatform win
file split foo//bar
} {foo bar}
test filename-6.15 {Tcl_SplitPath: win} {testsetplatform} {
testsetplatform win
file split /\\/foo//bar
} {//foo/bar}
test filename-6.16 {Tcl_SplitPath: win} {testsetplatform} {
testsetplatform win
file split /\\/foo//bar
} {//foo/bar}
test filename-6.17 {Tcl_SplitPath: win} {testsetplatform} {
testsetplatform win
file split /\\/foo//bar
} {//foo/bar}
test filename-6.18 {Tcl_SplitPath: win} {testsetplatform} {
testsetplatform win
file split \\\\foo\\bar
} {//foo/bar}
test filename-6.19 {Tcl_SplitPath: win} {testsetplatform} {
testsetplatform win
file split \\\\foo\\bar/baz
} {//foo/bar baz}
test filename-6.20 {Tcl_SplitPath: win} {testsetplatform} {
testsetplatform win
file split c:/foo
} {c:/ foo}
test filename-6.21 {Tcl_SplitPath: win} {testsetplatform} {
testsetplatform win
file split c:foo
} {c: foo}
test filename-6.22 {Tcl_SplitPath: win} {testsetplatform} {
testsetplatform win
file split c:
} {c:}
test filename-6.23 {Tcl_SplitPath: win} {testsetplatform} {
testsetplatform win
file split c:\\
} {c:/}
test filename-6.24 {Tcl_SplitPath: win} {testsetplatform} {
testsetplatform win
file split c:/
} {c:/}
test filename-6.25 {Tcl_SplitPath: win} {testsetplatform} {
testsetplatform win
file split c:/./..
} {c:/ . ..}
test filename-6.26 {Tcl_SplitPath: win} {testsetplatform} {
testsetplatform win
file split ~foo
} {~foo}
test filename-6.27 {Tcl_SplitPath: win} {testsetplatform} {
testsetplatform win
file split ~foo/~bar
} {~foo ./~bar}
test filename-6.28 {Tcl_SplitPath: win} {testsetplatform} {
testsetplatform win
file split ~foo/~bar/~baz
} {~foo ./~bar ./~baz}
test filename-6.29 {Tcl_SplitPath: win} {testsetplatform} {
testsetplatform win
file split foo/bar~/baz
} {foo bar~ baz}
test filename-6.30 {Tcl_SplitPath: win} {testsetplatform} {
testsetplatform win
file split c:~foo
} {c: ./~foo}
test filename-7.1 {Tcl_JoinPath: unix} {testsetplatform} {
testsetplatform unix
file join / a
} {/a}
test filename-7.2 {Tcl_JoinPath: unix} {testsetplatform} {
testsetplatform unix
file join a b
} {a/b}
test filename-7.3 {Tcl_JoinPath: unix} {testsetplatform} {
testsetplatform unix
file join /a c /b d
} {/b/d}
test filename-7.4 {Tcl_JoinPath: unix} {testsetplatform} {
testsetplatform unix
file join /
} {/}
test filename-7.5 {Tcl_JoinPath: unix} {testsetplatform} {
testsetplatform unix
file join a
} {a}
test filename-7.6 {Tcl_JoinPath: unix} {testsetplatform} {
testsetplatform unix
file join {}
} {}
test filename-7.7 {Tcl_JoinPath: unix} {testsetplatform} {
testsetplatform unix
file join /a/ b
} {/a/b}
test filename-7.8 {Tcl_JoinPath: unix} {testsetplatform} {
testsetplatform unix
file join /a// b
} {/a/b}
test filename-7.9 {Tcl_JoinPath: unix} {testsetplatform} {
testsetplatform unix
file join /a/./../. b
} {/a/./.././b}
test filename-7.10 {Tcl_JoinPath: unix} {testsetplatform} {
testsetplatform unix
file join ~ a
} {~/a}
test filename-7.11 {Tcl_JoinPath: unix} {testsetplatform} {
testsetplatform unix
file join ~a ~b
} {~b}
test filename-7.12 {Tcl_JoinPath: unix} {testsetplatform} {
testsetplatform unix
file join ./~a b
} {./~a/b}
test filename-7.13 {Tcl_JoinPath: unix} {testsetplatform} {
testsetplatform unix
file join ./~a ~b
} {~b}
test filename-7.14 {Tcl_JoinPath: unix} {testsetplatform} {
testsetplatform unix
file join ./~a ./~b
} {./~a/~b}
test filename-7.15 {Tcl_JoinPath: unix} {testsetplatform} {
testsetplatform unix
file join a . b
} {a/./b}
test filename-7.16 {Tcl_JoinPath: unix} {testsetplatform} {
testsetplatform unix
file join a . ./~b
} {a/./~b}
test filename-7.17 {Tcl_JoinPath: unix} {testsetplatform} {
testsetplatform unix
file join //a b
} {/a/b}
test filename-7.18 {Tcl_JoinPath: unix} {testsetplatform} {
testsetplatform unix
file join /// a b
} {/a/b}
test filename-8.1 {Tcl_JoinPath: mac} {testsetplatform} {
testsetplatform mac
file join a b
} {:a:b}
test filename-8.2 {Tcl_JoinPath: mac} {testsetplatform} {
testsetplatform mac
file join :a b
} {:a:b}
test filename-8.3 {Tcl_JoinPath: mac} {testsetplatform} {
testsetplatform mac
file join a b:
} {b:}
test filename-8.4 {Tcl_JoinPath: mac} {testsetplatform} {
testsetplatform mac
file join a: :b
} {a:b}
test filename-8.5 {Tcl_JoinPath: mac} {testsetplatform} {
testsetplatform mac
file join a: :b:
} {a:b}
test filename-8.6 {Tcl_JoinPath: mac} {testsetplatform} {
testsetplatform mac
file join a :: b
} {:a::b}
test filename-8.7 {Tcl_JoinPath: mac} {testsetplatform} {
testsetplatform mac
file join a :: :: b
} {:a:::b}
test filename-8.8 {Tcl_JoinPath: mac} {testsetplatform} {
testsetplatform mac
file join a ::: b
} {:a:::b}
test filename-8.9 {Tcl_JoinPath: mac} {testsetplatform} {
testsetplatform mac
file join a: b:
} {b:}
test filename-8.10 {Tcl_JoinPath: mac} {testsetplatform} {
testsetplatform mac
file join /a/b
} {a:b}
test filename-8.11 {Tcl_JoinPath: mac} {testsetplatform} {
testsetplatform mac
file join /a/b c/d
} {a:b:c:d}
test filename-8.12 {Tcl_JoinPath: mac} {testsetplatform} {
testsetplatform mac
file join /a/b :c:d
} {a:b:c:d}
test filename-8.13 {Tcl_JoinPath: mac} {testsetplatform} {
testsetplatform mac
file join ~ foo
} {~:foo}
test filename-8.14 {Tcl_JoinPath: mac} {testsetplatform} {
testsetplatform mac
file join :: ::
} {:::}
test filename-8.15 {Tcl_JoinPath: mac} {testsetplatform} {
testsetplatform mac
file join a: ::
} {a::}
test filename-8.16 {Tcl_JoinPath: mac} {testsetplatform} {
testsetplatform mac
file join a {} b
} {:a:b}
test filename-8.17 {Tcl_JoinPath: mac} {testsetplatform} {
testsetplatform mac
file join a::: b
} {a:::b}
test filename-8.18 {Tcl_JoinPath: mac} {testsetplatform} {
testsetplatform mac
file join a : : :
} {:a}
test filename-8.19 {Tcl_JoinPath: mac} {testsetplatform} {
testsetplatform mac
file join :
} {:}
test filename-8.20 {Tcl_JoinPath: mac} {testsetplatform} {
testsetplatform mac
file join : a
} {:a}
test filename-8.21 {Tcl_JoinPath: mac} {testsetplatform} {
testsetplatform mac
file join a: :b/c
} {a:b/c}
test filename-8.22 {Tcl_JoinPath: mac} {testsetplatform} {
testsetplatform mac
file join :a :b/c
} {:a:b/c}
test filename-9.1 {Tcl_JoinPath: win} {testsetplatform} {
testsetplatform win
file join a b
} {a/b}
test filename-9.2 {Tcl_JoinPath: win} {testsetplatform} {
testsetplatform win
file join /a b
} {/a/b}
test filename-9.3 {Tcl_JoinPath: win} {testsetplatform} {
testsetplatform win
file join /a /b
} {/b}
test filename-9.4 {Tcl_JoinPath: win} {testsetplatform} {
testsetplatform win
file join c: foo
} {c:foo}
test filename-9.5 {Tcl_JoinPath: win} {testsetplatform} {
testsetplatform win
file join c:/ foo
} {c:/foo}
test filename-9.6 {Tcl_JoinPath: win} {testsetplatform} {
testsetplatform win
file join c:\\bar foo
} {c:/bar/foo}
test filename-9.7 {Tcl_JoinPath: win} {testsetplatform} {
testsetplatform win
file join /foo c:bar
} {c:bar}
test filename-9.8 {Tcl_JoinPath: win} {testsetplatform} {
testsetplatform win
file join ///host//share dir
} {//host/share/dir}
test filename-9.9 {Tcl_JoinPath: win} {testsetplatform} {
testsetplatform win
file join ~ foo
} {~/foo}
test filename-9.10 {Tcl_JoinPath: win} {testsetplatform} {
testsetplatform win
file join ~/~foo
} {~/~foo}
test filename-9.11 {Tcl_JoinPath: win} {testsetplatform} {
testsetplatform win
file join ~ ./~foo
} {~/~foo}
test filename-9.12 {Tcl_JoinPath: win} {testsetplatform} {
testsetplatform win
file join / ~foo
} {~foo}
test filename-9.13 {Tcl_JoinPath: win} {testsetplatform} {
testsetplatform win
file join ./a/ b c
} {./a/b/c}
test filename-9.14 {Tcl_JoinPath: win} {testsetplatform} {
testsetplatform win
file join ./~a/ b c
} {./~a/b/c}
test filename-9.15 {Tcl_JoinPath: win} {testsetplatform} {
testsetplatform win
file join // host share path
} {/host/share/path}
test filename-9.16 {Tcl_JoinPath: win} {testsetplatform} {
testsetplatform win
file join foo . bar
} {foo/./bar}
test filename-9.17 {Tcl_JoinPath: win} {testsetplatform} {
testsetplatform win
file join foo .. bar
} {foo/../bar}
test filename-9.18 {Tcl_JoinPath: win} {testsetplatform} {
testsetplatform win
file join foo/./bar
} {foo/./bar}
test filename-10.1 {Tcl_TranslateFileName} {testsetplatform} {
testsetplatform unix
list [catch {testtranslatefilename foo} msg] $msg
} {0 foo}
test filename-10.2 {Tcl_TranslateFileName} {testsetplatform} {
testsetplatform windows
list [catch {testtranslatefilename {c:/foo}} msg] $msg
} {0 {c:\foo}}
test filename-10.3 {Tcl_TranslateFileName} {testsetplatform} {
testsetplatform windows
list [catch {testtranslatefilename {c:/\\foo/}} msg] $msg
} {0 {c:\foo}}
test filename-10.4 {Tcl_TranslateFileName} {testsetplatform} {
testsetplatform mac
list [catch {testtranslatefilename foo} msg] $msg
} {0 :foo}
test filename-10.5 {Tcl_TranslateFileName} {testsetplatform} {
testsetplatform mac
list [catch {testtranslatefilename :~foo} msg] $msg
} {0 :~foo}
test filename-10.6 {Tcl_TranslateFileName} {testsetplatform} {
global env
set temp $env(HOME)
set env(HOME) "/home/test"
testsetplatform unix
set result [list [catch {testtranslatefilename ~/foo} msg] $msg]
set env(HOME) $temp
set result
} {0 /home/test/foo}
test filename-10.7 {Tcl_TranslateFileName} {testsetplatform} {
global env
set temp $env(HOME)
unset env(HOME)
testsetplatform unix
set result [list [catch {testtranslatefilename ~/foo} msg] $msg]
set env(HOME) $temp
set result
} {1 {couldn't find HOME environment variable to expand path}}
test filename-10.8 {Tcl_TranslateFileName} {testsetplatform} {
global env
set temp $env(HOME)
set env(HOME) "/home/test"
testsetplatform unix
set result [list [catch {testtranslatefilename ~} msg] $msg]
set env(HOME) $temp
set result
} {0 /home/test}
test filename-10.9 {Tcl_TranslateFileName} {testsetplatform} {
global env
set temp $env(HOME)
set env(HOME) "/home/test/"
testsetplatform unix
set result [list [catch {testtranslatefilename ~} msg] $msg]
set env(HOME) $temp
set result
} {0 /home/test}
test filename-10.10 {Tcl_TranslateFileName} {testsetplatform} {
global env
set temp $env(HOME)
set env(HOME) "/home/test/"
testsetplatform unix
set result [list [catch {testtranslatefilename ~/foo} msg] $msg]
set env(HOME) $temp
set result
} {0 /home/test/foo}
test filename-10.11 {Tcl_TranslateFileName} {testsetplatform} {
global env
set temp $env(HOME)
set env(HOME) "Root:"
testsetplatform mac
set result [list [catch {testtranslatefilename ~/foo} msg] $msg]
set env(HOME) $temp
set result
} {0 Root:foo}
test filename-10.12 {Tcl_TranslateFileName} {testsetplatform} {
global env
set temp $env(HOME)
set env(HOME) "Root:home"
testsetplatform mac
set result [list [catch {testtranslatefilename ~/foo} msg] $msg]
set env(HOME) $temp
set result
} {0 Root:home:foo}
test filename-10.13 {Tcl_TranslateFileName} {testsetplatform} {
global env
set temp $env(HOME)
set env(HOME) "Root:home"
testsetplatform mac
set result [list [catch {testtranslatefilename ~::foo} msg] $msg]
set env(HOME) $temp
set result
} {0 Root:home::foo}
test filename-10.14 {Tcl_TranslateFileName} {testsetplatform} {
global env
set temp $env(HOME)
set env(HOME) "Root:home"
testsetplatform mac
set result [list [catch {testtranslatefilename ~} msg] $msg]
set env(HOME) $temp
set result
} {0 Root:home}
test filename-10.15 {Tcl_TranslateFileName} {testsetplatform} {
global env
set temp $env(HOME)
set env(HOME) "Root:home:"
testsetplatform mac
set result [list [catch {testtranslatefilename ~::foo} msg] $msg]
set env(HOME) $temp
set result
} {0 Root:home::foo}
test filename-10.16 {Tcl_TranslateFileName} {testsetplatform} {
global env
set temp $env(HOME)
set env(HOME) "Root:home::"
testsetplatform mac
set result [list [catch {testtranslatefilename ~::foo} msg] $msg]
set env(HOME) $temp
set result
} {0 Root:home:::foo}
test filename-10.17 {Tcl_TranslateFileName} {testsetplatform} {
global env
set temp $env(HOME)
set env(HOME) "\\home\\"
testsetplatform windows
set result [list [catch {testtranslatefilename ~/foo} msg] $msg]
set env(HOME) $temp
set result
} {0 {\home\foo}}
test filename-10.18 {Tcl_TranslateFileName} {testsetplatform} {
global env
set temp $env(HOME)
set env(HOME) "\\home\\"
testsetplatform windows
set result [list [catch {testtranslatefilename ~/foo\\bar} msg] $msg]
set env(HOME) $temp
set result
} {0 {\home\foo\bar}}
test filename-10.19 {Tcl_TranslateFileName} {testsetplatform} {
global env
set temp $env(HOME)
set env(HOME) "c:"
testsetplatform windows
set result [list [catch {testtranslatefilename ~/foo} msg] $msg]
set env(HOME) $temp
set result
} {0 c:foo}
test filename-10.20 {Tcl_TranslateFileName} {testtranslatefilename} {
list [catch {testtranslatefilename ~blorp/foo} msg] $msg
} {1 {user "blorp" doesn't exist}}
test filename-10.21 {Tcl_TranslateFileName} {testsetplatform} {
global env
set temp $env(HOME)
set env(HOME) "c:\\"
testsetplatform windows
set result [list [catch {testtranslatefilename ~/foo} msg] $msg]
set env(HOME) $temp
set result
} {0 {c:\foo}}
test filename-10.22 {Tcl_TranslateFileName} {testsetplatform} {
testsetplatform windows
list [catch {testtranslatefilename foo//bar} msg] $msg
} {0 {foo\bar}}
if {[tcltest::testConstraint testsetplatform]} {
testsetplatform $platform
}
test filename-10.23 {Tcl_TranslateFileName} {unixOnly nonPortable} {
# this test fails if ~ouster is not /home/ouster
list [catch {testtranslatefilename ~ouster} msg] $msg
} {0 /home/ouster}
test filename-10.24 {Tcl_TranslateFileName} {unixOnly nonPortable} {
# this test fails if ~ouster is not /home/ouster
list [catch {testtranslatefilename ~ouster/foo} msg] $msg
} {0 /home/ouster/foo}
test filename-11.1 {Tcl_GlobCmd} {
list [catch {glob} msg] $msg
} {1 {wrong # args: should be "glob ?switches? name ?name ...?"}}
test filename-11.2 {Tcl_GlobCmd} {
list [catch {glob -gorp} msg] $msg
} {1 {bad option "-gorp": must be -directory, -join, -nocomplain, -path, -tails, -types, or --}}
test filename-11.3 {Tcl_GlobCmd} {
list [catch {glob -nocomplai} msg] $msg
} {1 {wrong # args: should be "glob ?switches? name ?name ...?"}}
test filename-11.4 {Tcl_GlobCmd} {
list [catch {glob -nocomplain} msg] $msg
} {1 {wrong # args: should be "glob ?switches? name ?name ...?"}}
test filename-11.5 {Tcl_GlobCmd} {
list [catch {glob -nocomplain ~xyqrszzz} msg] $msg
} {0 {}}
test filename-11.6 {Tcl_GlobCmd} {
list [catch {glob ~xyqrszzz} msg] $msg
} {1 {user "xyqrszzz" doesn't exist}}
test filename-11.7 {Tcl_GlobCmd} {
list [catch {glob -- -nocomplain} msg] $msg
} {1 {no files matched glob pattern "-nocomplain"}}
test filename-11.8 {Tcl_GlobCmd} {
list [catch {glob -nocomplain -- -nocomplain} msg] $msg
} {0 {}}
test filename-11.9 {Tcl_GlobCmd} {testsetplatform} {
testsetplatform unix
list [catch {glob ~\\xyqrszzz/bar} msg] $msg
} {1 {user "\xyqrszzz" doesn't exist}}
test filename-11.10 {Tcl_GlobCmd} {testsetplatform} {
testsetplatform unix
list [catch {glob -nocomplain ~\\xyqrszzz/bar} msg] $msg
} {0 {}}
test filename-11.11 {Tcl_GlobCmd} {testsetplatform} {
testsetplatform unix
list [catch {glob ~xyqrszzz\\/\\bar} msg] $msg
} {1 {user "xyqrszzz" doesn't exist}}
test filename-11.12 {Tcl_GlobCmd} {testsetplatform} {
testsetplatform unix
set home $env(HOME)
unset env(HOME)
set x [list [catch {glob ~/*} msg] $msg]
set env(HOME) $home
set x
} {1 {couldn't find HOME environment variable to expand path}}
if {[tcltest::testConstraint testsetplatform]} {
testsetplatform $platform
}
test filename-11.13 {Tcl_GlobCmd} {
list [catch {file join [lindex [glob ~] 0]} msg] $msg
} [list 0 [file join $env(HOME)]]
set oldhome $env(HOME)
set env(HOME) [pwd]
|
| ︙ | ︙ | |||
1120 1121 1122 1123 1124 1125 1126 |
test filename-11.16 {Tcl_GlobCmd} {
list [catch {glob globTest} msg] $msg
} {0 globTest}
set globname "globTest"
set horribleglobname "glob\[\{Test"
| | > > > > > > > > > > > > > > > > > | > > > > > > > > > > | > | > > > > > > > > > > > > > > > > > > > > > > > > > > | | > | > | 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 |
test filename-11.16 {Tcl_GlobCmd} {
list [catch {glob globTest} msg] $msg
} {0 globTest}
set globname "globTest"
set horribleglobname "glob\[\{Test"
test filename-11.17 {Tcl_GlobCmd} {unixOnly} {
list [catch {lsort [glob -directory $globname *]} msg] $msg
} [list 0 [lsort [list [file join $globname a1] [file join $globname a2]\
[file join $globname a3]\
[file join $globname "weird name.c"]\
[file join $globname x,z1.c]\
[file join $globname x1.c]\
[file join $globname y1.c] [file join $globname z1.c]]]]
test filename-11.17.1 {Tcl_GlobCmd} {pcOnly macOnly} {
list [catch {lsort [glob -directory $globname *]} msg] $msg
} [list 0 [lsort [list [file join $globname a1] [file join $globname a2]\
[file join $globname .1]\
[file join $globname a3]\
[file join $globname "weird name.c"]\
[file join $globname x,z1.c]\
[file join $globname x1.c]\
[file join $globname y1.c] [file join $globname z1.c]]]]
test filename-11.18 {Tcl_GlobCmd} {unixOnly} {
list [catch {lsort [glob -path $globname/ *]} msg] $msg
} [list 0 [lsort [list [file join $globname a1] [file join $globname a2]\
[file join $globname a3]\
[file join $globname "weird name.c"]\
[file join $globname x,z1.c]\
[file join $globname x1.c]\
[file join $globname y1.c] [file join $globname z1.c]]]]
test filename-11.18.1 {Tcl_GlobCmd} {pcOnly macOnly} {
list [catch {lsort [glob -path $globname/ *]} msg] $msg
} [list 0 [lsort [list [file join $globname a1] [file join $globname a2]\
[file join $globname .1]\
[file join $globname a3]\
[file join $globname "weird name.c"]\
[file join $globname x,z1.c]\
[file join $globname x1.c]\
[file join $globname y1.c] [file join $globname z1.c]]]]
test filename-11.19 {Tcl_GlobCmd} {unixOnly} {
list [catch {lsort [glob -join -path \
[string range $globname 0 5] * *]} msg] $msg
} [list 0 [lsort [list [file join $globname a1] [file join $globname a2]\
[file join $globname a3]\
[file join $globname "weird name.c"]\
[file join $globname x,z1.c]\
[file join $globname x1.c]\
[file join $globname y1.c] [file join $globname z1.c]]]]
test filename-11.19.1 {Tcl_GlobCmd} {pcOnly macOnly} {
list [catch {lsort [glob -join -path \
[string range $globname 0 5] * *]} msg] $msg
} [list 0 [lsort [list [file join $globname a1] [file join $globname a2]\
[file join $globname .1]\
[file join $globname a3]\
[file join $globname "weird name.c"]\
[file join $globname x,z1.c]\
[file join $globname x1.c]\
[file join $globname y1.c] [file join $globname z1.c]]]]
test filename-11.20 {Tcl_GlobCmd} {
list [catch {lsort [glob -type d -dir $globname *]} msg] $msg
} [list 0 [lsort [list [file join $globname a1]\
[file join $globname a2]\
[file join $globname a3]]]]
test filename-11.21 {Tcl_GlobCmd} {
list [catch {lsort [glob -type d -path $globname *]} msg] $msg
} [list 0 [lsort [list $globname]]]
file rename globTest $horribleglobname
set globname $horribleglobname
test filename-11.22 {Tcl_GlobCmd} {unixOnly} {
list [catch {lsort [glob -dir $globname *]} msg] $msg
} [list 0 [lsort [list [file join $globname a1] [file join $globname a2]\
[file join $globname a3]\
[file join $globname "weird name.c"]\
[file join $globname x,z1.c]\
[file join $globname x1.c]\
[file join $globname y1.c] [file join $globname z1.c]]]]
test filename-11.22.1 {Tcl_GlobCmd} {pcOnly macOnly} {
list [catch {lsort [glob -dir $globname *]} msg] $msg
} [list 0 [lsort [list [file join $globname a1] [file join $globname a2]\
[file join $globname .1]\
[file join $globname a3]\
[file join $globname "weird name.c"]\
[file join $globname x,z1.c]\
[file join $globname x1.c]\
[file join $globname y1.c] [file join $globname z1.c]]]]
test filename-11.23 {Tcl_GlobCmd} {unixOnly} {
list [catch {lsort [glob -path $globname/ *]} msg] $msg
} [list 0 [lsort [list [file join $globname a1] [file join $globname a2]\
[file join $globname a3]\
[file join $globname "weird name.c"]\
[file join $globname x,z1.c]\
[file join $globname x1.c]\
[file join $globname y1.c] [file join $globname z1.c]]]]
test filename-11.23.1 {Tcl_GlobCmd} {pcOnly macOnly} {
list [catch {lsort [glob -path $globname/ *]} msg] $msg
} [list 0 [lsort [list [file join $globname a1] [file join $globname a2]\
[file join $globname .1]\
[file join $globname a3]\
[file join $globname "weird name.c"]\
[file join $globname x,z1.c]\
[file join $globname x1.c]\
[file join $globname y1.c] [file join $globname z1.c]]]]
test filename-11.24 {Tcl_GlobCmd} {unixOnly} {
list [catch {lsort [glob -join -path \
[string range $globname 0 5] * *]} msg] $msg
} [list 0 [lsort [list [file join $globname a1] [file join $globname a2]\
[file join $globname a3]\
[file join $globname "weird name.c"]\
[file join $globname x,z1.c]\
[file join $globname x1.c]\
[file join $globname y1.c] [file join $globname z1.c]]]]
test filename-11.24.1 {Tcl_GlobCmd} {pcOnly macOnly} {
list [catch {lsort [glob -join -path \
[string range $globname 0 5] * *]} msg] $msg
} [list 0 [lsort [list [file join $globname a1] [file join $globname a2]\
[file join $globname .1]\
[file join $globname a3]\
[file join $globname "weird name.c"]\
[file join $globname x,z1.c]\
[file join $globname x1.c]\
[file join $globname y1.c] [file join $globname z1.c]]]]
test filename-11.25 {Tcl_GlobCmd} {
list [catch {lsort [glob -type d -dir $globname *]} msg] $msg
|
| ︙ | ︙ | |||
1217 1218 1219 1220 1221 1222 1223 |
list [catch {glob -path} msg] $msg
} {1 {missing argument to "-path"}}
test filename-11.34 {Tcl_GlobCmd} {
list [catch {glob -direct} msg] $msg
} {1 {missing argument to "-directory"}}
test filename-11.35 {Tcl_GlobCmd} {
list [catch {glob -paths *} msg] $msg
| | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 |
list [catch {glob -path} msg] $msg
} {1 {missing argument to "-path"}}
test filename-11.34 {Tcl_GlobCmd} {
list [catch {glob -direct} msg] $msg
} {1 {missing argument to "-directory"}}
test filename-11.35 {Tcl_GlobCmd} {
list [catch {glob -paths *} msg] $msg
} {1 {bad option "-paths": must be -directory, -join, -nocomplain, -path, -tails, -types, or --}}
# Test '-tails' flag to glob.
test filename-11.36 {Tcl_GlobCmd} {
list [catch {glob -tails *} msg] $msg
} {1 {"-tails" must be used with either "-directory" or "-path"}}
test filename-11.37 {Tcl_GlobCmd} {
list [catch {glob -type d -tails -path $globname *} msg] $msg
} [list 0 [list $globname]]
test filename-11.38 {Tcl_GlobCmd} {
list [catch {glob -tails -path $globname *} msg] $msg
} [list 0 [list $globname]]
test filename-11.39 {Tcl_GlobCmd} {
list [catch {glob -tails -join -path $globname *} msg] $msg
} [list 0 [list $globname]]
test filename-11.40 {Tcl_GlobCmd} {
expr {[glob -dir [pwd] -tails *] == [glob *]}
} {1}
test filename-11.41 {Tcl_GlobCmd} {
expr {[glob -dir [pwd] -tails *] != [glob -dir [pwd] *]}
} {1}
test filename-11.42 {Tcl_GlobCmd} {
set res [list]
foreach f [glob -dir [pwd] *] {
lappend res [file tail $f]
}
expr {$res == [glob *]}
} {1}
test filename-11.43 {Tcl_GlobCmd} {
list [catch {glob -t *} msg] $msg
} {1 {ambiguous option "-t": must be -directory, -join, -nocomplain, -path, -tails, -types, or --}}
test filename-11.44 {Tcl_GlobCmd} {
list [catch {glob -tails -path hello -directory hello *} msg] $msg
} {1 {"-directory" cannot be used with "-path"}}
file rename $horribleglobname globTest
set globname globTest
unset horribleglobname
test filename-12.1 {simple globbing} {unixOrPc} {
list [catch {glob {}} msg] $msg
|
| ︙ | ︙ | |||
1335 1336 1337 1338 1339 1340 1341 |
} {:globTest:x1.c :globTest:y1.c :globTest:z1.c}
test filename-14.5 {asterisks, question marks, and brackets} {unixOrPc} {
lsort [glob */*/*/*.c]
} {globTest/a1/b1/x2.c globTest/a1/b2/y2.c}
test filename-14.6 {asterisks, question marks, and brackets} {macOnly} {
lsort [glob */*/*/*.c]
} {:globTest:a1:b1:x2.c :globTest:a1:b2:y2.c}
| | > > > | 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 |
} {:globTest:x1.c :globTest:y1.c :globTest:z1.c}
test filename-14.5 {asterisks, question marks, and brackets} {unixOrPc} {
lsort [glob */*/*/*.c]
} {globTest/a1/b1/x2.c globTest/a1/b2/y2.c}
test filename-14.6 {asterisks, question marks, and brackets} {macOnly} {
lsort [glob */*/*/*.c]
} {:globTest:a1:b1:x2.c :globTest:a1:b2:y2.c}
test filename-14.7 {asterisks, question marks, and brackets} {unixOnly} {
lsort [glob globTest/*]
} {globTest/a1 globTest/a2 globTest/a3 {globTest/weird name.c} globTest/x,z1.c globTest/x1.c globTest/y1.c globTest/z1.c}
test filename-14.7.1 {asterisks, question marks, and brackets} {pcOnly} {
lsort [glob globTest/*]
} {globTest/.1 globTest/a1 globTest/a2 globTest/a3 {globTest/weird name.c} globTest/x,z1.c globTest/x1.c globTest/y1.c globTest/z1.c}
test filename-14.8 {asterisks, question marks, and brackets} {macOnly} {
lsort [glob globTest/*]
} {:globTest:.1 :globTest:a1 :globTest:a2 :globTest:a3 {:globTest:weird name.c} :globTest:x,z1.c :globTest:x1.c :globTest:y1.c :globTest:z1.c}
test filename-14.9 {asterisks, question marks, and brackets} {unixOrPc} {
lsort [glob globTest/.*]
} {globTest/. globTest/.. globTest/.1}
test filename-14.10 {asterisks, question marks, and brackets} {macOnly} {
|
| ︙ | ︙ | |||
1394 1395 1396 1397 1398 1399 1400 |
} {1 {no files matched glob patterns "goo/* x*z foo?q"}}
test filename-14.23 {slash globbing} {unixOrPc} {
glob /
} /
test filename-14.24 {slash globbing} {pcOnly} {
glob {\\}
} /
| | > > > > > > > > | 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 |
} {1 {no files matched glob patterns "goo/* x*z foo?q"}}
test filename-14.23 {slash globbing} {unixOrPc} {
glob /
} /
test filename-14.24 {slash globbing} {pcOnly} {
glob {\\}
} /
test filename-14.25 {type specific globbing} {unixOnly} {
list [catch {lsort [glob -dir globTest -types f *]} msg] $msg
} [list 0 [lsort [list \
[file join $globname "weird name.c"]\
[file join $globname x,z1.c]\
[file join $globname x1.c]\
[file join $globname y1.c] [file join $globname z1.c]]]]
test filename-14.25.1 {type specific globbing} {pcOnly macOnly} {
list [catch {lsort [glob -dir globTest -types f *]} msg] $msg
} [list 0 [lsort [list \
[file join $globname .1]\
[file join $globname "weird name.c"]\
[file join $globname x,z1.c]\
[file join $globname x1.c]\
[file join $globname y1.c] [file join $globname z1.c]]]]
test filename-14.26 {type specific globbing} {
list [catch {glob -nocomplain -dir globTest -types {readonly} *} msg] $msg
} [list 0 {}]
|
| ︙ | ︙ | |||
1514 1515 1516 1517 1518 1519 1520 | } //[info hostname]/c/globTest # cleanup file delete -force C:/globTest cd $oldDir file delete -force globTest set env(HOME) $oldhome | > | > > | | 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 |
} //[info hostname]/c/globTest
# cleanup
file delete -force C:/globTest
cd $oldDir
file delete -force globTest
set env(HOME) $oldhome
if {[tcltest::testConstraint testsetplatform]} {
testsetplatform $platform
catch {unset platform}
}
catch {unset oldhome temp result}
::tcltest::cleanupTests
return
|
Changes to tests/io.test.
| ︙ | ︙ | |||
8 9 10 11 12 13 14 | # Copyright (c) 1991-1994 The Regents of the University of California. # Copyright (c) 1994-1997 Sun Microsystems, Inc. # Copyright (c) 1998-1999 by Scriptics Corporation. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # | | | < < < < | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# Copyright (c) 1991-1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: io.test,v 1.20 2001/07/31 19:12:07 vincentdarley Exp $
if {[lsearch [namespace children] ::tcltest] == -1} {
package require tcltest
namespace import -force ::tcltest::*
}
tcltest::testConstraint testchannel [string equal testchannel [info commands testchannel]]
::tcltest::saveState
removeFile test1
removeFile pipe
catch {unset u}
|
| ︙ | ︙ | |||
626 627 628 629 630 631 632 |
close $f
set f [open test1]
fconfigure $f -translation crlf
set x [list [gets $f line] $line [gets $f line] $line [gets $f line] $line]
close $f
set x
} [list 14 "abcd\nefgh\rijkl" 4 "mnop" -1 ""]
| | | | | 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 |
close $f
set f [open test1]
fconfigure $f -translation crlf
set x [list [gets $f line] $line [gets $f line] $line [gets $f line] $line]
close $f
set x
} [list 14 "abcd\nefgh\rijkl" 4 "mnop" -1 ""]
test io-6.30 {Tcl_GetsObj: crlf mode: buffer exhausted} {testchannel} {
# if (eol >= dstEnd)
set f [open test1 w]
fconfigure $f -translation lf
puts -nonewline $f "123456789012345\r\nabcdefghijklmnoprstuvwxyz"
close $f
set f [open test1]
fconfigure $f -translation crlf -buffersize 16
set x [list [gets $f line] $line [testchannel inputbuffered $f]]
close $f
set x
} [list 15 "123456789012345" 15]
test io-6.31 {Tcl_GetsObj: crlf mode: buffer exhausted, blocked} {stdio testchannel} {
# (FilterInputBytes() != 0)
set f [open "|[list $::tcltest::tcltest cat]" w+]
fconfigure $f -translation {crlf lf} -buffering none
puts -nonewline $f "bbbbbbbbbbbbbb\r\n123456789012345\r"
fconfigure $f -buffersize 16
set x [gets $f]
fconfigure $f -blocking 0
lappend x [gets $f line] $line [fblocked $f] [testchannel inputbuffered $f]
close $f
set x
} [list "bbbbbbbbbbbbbb" -1 "" 1 16]
test io-6.32 {Tcl_GetsObj: crlf mode: buffer exhausted, more data} {testchannel} {
# not (FilterInputBytes() != 0)
set f [open test1 w]
fconfigure $f -translation lf
puts -nonewline $f "123456789012345\r\n123"
close $f
set f [open test1]
|
| ︙ | ︙ | |||
778 779 780 781 782 783 784 |
set f [open test1]
fconfigure $f -translation auto
set x [list [gets $f line] $line [gets $f line] $line]
lappend x [gets $f line] $line [gets $f line] $line [gets $f line] $line
close $f
set x
} [list 4 "abcd" 4 "efgh" 4 "ijkl" 4 "mnop" -1 ""]
| | | | | | | | | | 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 |
set f [open test1]
fconfigure $f -translation auto
set x [list [gets $f line] $line [gets $f line] $line]
lappend x [gets $f line] $line [gets $f line] $line [gets $f line] $line
close $f
set x
} [list 4 "abcd" 4 "efgh" 4 "ijkl" 4 "mnop" -1 ""]
test io-6.43 {Tcl_GetsObj: input saw cr} {stdio testchannel} {
# if (chanPtr->flags & INPUT_SAW_CR)
set f [open "|[list $::tcltest::tcltest cat]" w+]
fconfigure $f -translation {auto lf} -buffering none
puts -nonewline $f "bbbbbbbbbbbbbbb\n123456789abcdef\r"
fconfigure $f -buffersize 16
set x [list [gets $f]]
fconfigure $f -blocking 0
lappend x [gets $f line] $line [testchannel queuedcr $f]
fconfigure $f -blocking 1
puts -nonewline $f "\nabcd\refg\x1a"
lappend x [gets $f line] $line [testchannel queuedcr $f]
lappend x [gets $f line] $line
close $f
set x
} [list "bbbbbbbbbbbbbbb" 15 "123456789abcdef" 1 4 "abcd" 0 3 "efg"]
test io-6.44 {Tcl_GetsObj: input saw cr, not followed by cr} {stdio testchannel} {
# not (*eol == '\n')
set f [open "|[list $::tcltest::tcltest cat]" w+]
fconfigure $f -translation {auto lf} -buffering none
puts -nonewline $f "bbbbbbbbbbbbbbb\n123456789abcdef\r"
fconfigure $f -buffersize 16
set x [list [gets $f]]
fconfigure $f -blocking 0
lappend x [gets $f line] $line [testchannel queuedcr $f]
fconfigure $f -blocking 1
puts -nonewline $f "abcd\refg\x1a"
lappend x [gets $f line] $line [testchannel queuedcr $f]
lappend x [gets $f line] $line
close $f
set x
} [list "bbbbbbbbbbbbbbb" 15 "123456789abcdef" 1 4 "abcd" 0 3 "efg"]
test io-6.45 {Tcl_GetsObj: input saw cr, skip right number of bytes} {stdio testchannel} {
# Tcl_ExternalToUtf()
set f [open "|[list $::tcltest::tcltest cat]" w+]
fconfigure $f -translation {auto lf} -buffering none
fconfigure $f -encoding unicode
puts -nonewline $f "bbbbbbbbbbbbbbb\n123456789abcdef\r"
fconfigure $f -buffersize 16
gets $f
fconfigure $f -blocking 0
set x [list [gets $f line] $line [testchannel queuedcr $f]]
fconfigure $f -blocking 1
puts -nonewline $f "\nabcd\refg"
lappend x [gets $f line] $line [testchannel queuedcr $f]
close $f
set x
} [list 15 "123456789abcdef" 1 4 "abcd" 0]
test io-6.46 {Tcl_GetsObj: input saw cr, followed by just \n should give eof} {stdio testchannel} {
# memmove()
set f [open "|[list $::tcltest::tcltest cat]" w+]
fconfigure $f -translation {auto lf} -buffering none
puts -nonewline $f "bbbbbbbbbbbbbbb\n123456789abcdef\r"
fconfigure $f -buffersize 16
gets $f
fconfigure $f -blocking 0
set x [list [gets $f line] $line [testchannel queuedcr $f]]
fconfigure $f -blocking 1
puts -nonewline $f "\n\x1a"
lappend x [gets $f line] $line [testchannel queuedcr $f]
close $f
set x
} [list 15 "123456789abcdef" 1 -1 "" 0]
test io-6.47 {Tcl_GetsObj: auto mode: \r at end of buffer, peek for \n} {testchannel} {
# (eol == dstEnd)
set f [open test1 w]
fconfigure $f -translation lf
puts -nonewline $f "123456789012345\r\nabcdefghijklmnopq"
close $f
set f [open test1]
fconfigure $f -translation auto -buffersize 16
set x [list [gets $f] [testchannel inputbuffered $f]]
close $f
set x
} [list "123456789012345" 15]
test io-6.48 {Tcl_GetsObj: auto mode: \r at end of buffer, no more avail} {testchannel} {
# PeekAhead() did not get any, so (eol >= dstEnd)
set f [open test1 w]
fconfigure $f -translation lf
puts -nonewline $f "123456789012345\r"
close $f
set f [open test1]
fconfigure $f -translation auto -buffersize 16
set x [list [gets $f] [testchannel queuedcr $f]]
close $f
set x
} [list "123456789012345" 1]
test io-6.49 {Tcl_GetsObj: auto mode: \r followed by \n} {testchannel} {
# if (*eol == '\n') {skip++}
set f [open test1 w]
fconfigure $f -translation lf
puts -nonewline $f "123456\r\n78901"
close $f
set f [open test1]
set x [list [gets $f] [testchannel queuedcr $f] [tell $f] [gets $f]]
close $f
set x
} [list "123456" 0 8 "78901"]
test io-6.50 {Tcl_GetsObj: auto mode: \r not followed by \n} {testchannel} {
# not (*eol == '\n')
set f [open test1 w]
fconfigure $f -translation lf
puts -nonewline $f "123456\r78901"
close $f
set f [open test1]
|
| ︙ | ︙ | |||
907 908 909 910 911 912 913 |
puts -nonewline $f "123456\n78901"
close $f
set f [open test1]
set x [list [gets $f] [tell $f] [gets $f]]
close $f
set x
} [list "123456" 7 "78901"]
| | | 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 |
puts -nonewline $f "123456\n78901"
close $f
set f [open test1]
set x [list [gets $f] [tell $f] [gets $f]]
close $f
set x
} [list "123456" 7 "78901"]
test io-6.52 {Tcl_GetsObj: saw EOF character} {testchannel} {
# if (eof != NULL)
set f [open test1 w]
fconfigure $f -translation lf
puts -nonewline $f "123456\x1ak9012345\r"
close $f
set f [open test1]
|
| ︙ | ︙ | |||
1001 1002 1003 1004 1005 1006 1007 |
close $f
set f [open test1]
fconfigure $f -encoding shiftjis
set x [list [gets $f line] $line [eof $f]]
close $f
set x
} [list 10 "1234567890" 0]
| | | 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 |
close $f
set f [open test1]
fconfigure $f -encoding shiftjis
set x [list [gets $f line] $line [eof $f]]
close $f
set x
} [list 10 "1234567890" 0]
test io-7.3 {FilterInputBytes: split up character at EOF} {testchannel} {
set f [open test1 w]
fconfigure $f -encoding binary
puts -nonewline $f "1234567890123\x82\x4f\x82\x50\x82"
close $f
set f [open test1]
fconfigure $f -encoding shiftjis
set x [list [gets $f line] $line]
|
| ︙ | ︙ | |||
1033 1034 1035 1036 1037 1038 1039 |
puts $f "\x51\x82\x52"
fconfigure $f -encoding shiftjis
vwait x
close $f
set x
} [list -1 "" 1 17 "1234567890123\uff10\uff11\uff12\uff13" 0]
| | | | | 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 |
puts $f "\x51\x82\x52"
fconfigure $f -encoding shiftjis
vwait x
close $f
set x
} [list -1 "" 1 17 "1234567890123\uff10\uff11\uff12\uff13" 0]
test io-8.1 {PeekAhead: only go to device if no more cached data} {testchannel} {
# (bufPtr->nextPtr == NULL)
set f [open "test1" w]
fconfigure $f -encoding ascii -translation lf
puts -nonewline $f "123456789012345\r\n2345678"
close $f
set f [open "test1"]
fconfigure $f -encoding ascii -translation auto -buffersize 16
# here
gets $f
set x [testchannel inputbuffered $f]
close $f
set x
} "7"
test io-8.2 {PeekAhead: only go to device if no more cached data} {stdio testchannel} {
# not (bufPtr->nextPtr == NULL)
set f [open "|[list $::tcltest::tcltest cat]" w+]
fconfigure $f -translation lf -encoding ascii -buffering none
puts -nonewline $f "123456789012345\r\nbcdefghijklmnopqrstuvwxyz"
set x {}
fileevent $f read "ready $f"
proc ready {f} {
lappend ::x [gets $f line] $line [testchannel inputbuffered $f]
}
fconfigure $f -encoding unicode -buffersize 16 -blocking 0
vwait x
fconfigure $f -translation auto -encoding ascii -blocking 1
# here
vwait x
close $f
set x
} [list -1 "" 42 15 "123456789012345" 25]
test io-8.3 {PeekAhead: no cached data available} {stdio testchannel} {
# (bytesLeft == 0)
set f [open "|[list $::tcltest::tcltest cat]" w+]
fconfigure $f -translation {auto binary}
puts -nonewline $f "abcdefghijklmno\r"
flush $f
set x [list [gets $f line] $line [testchannel queuedcr $f]]
|
| ︙ | ︙ | |||
1100 1101 1102 1103 1104 1105 1106 |
# that cached data is available in buffer w/o having to call driver.
set x [gets $f]
close $f
set x
} $a
unset a
| | | | | 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 |
# that cached data is available in buffer w/o having to call driver.
set x [gets $f]
close $f
set x
} $a
unset a
test io-8.5 {PeekAhead: don't peek if last read was short} {stdio testchannel} {
# (bufPtr->nextAdded < bufPtr->length)
set f [open "|[list $::tcltest::tcltest cat]" w+]
fconfigure $f -translation {auto binary}
puts -nonewline $f "abcdefghijklmno\r"
flush $f
# here
set x [list [gets $f line] $line [testchannel queuedcr $f]]
close $f
set x
} {15 abcdefghijklmno 1}
test io-8.6 {PeekAhead: change to non-blocking mode} {stdio testchannel} {
# ((chanPtr->flags & CHANNEL_NONBLOCKING) == 0)
set f [open "|[list $::tcltest::tcltest cat]" w+]
fconfigure $f -translation {auto binary} -buffersize 16
puts -nonewline $f "abcdefghijklmno\r"
flush $f
# here
set x [list [gets $f line] $line [testchannel queuedcr $f]]
close $f
set x
} {15 abcdefghijklmno 1}
test io-8.7 {PeekAhead: cleanup} {stdio testchannel} {
# Make sure bytes are removed from buffer.
set f [open "|[list $::tcltest::tcltest cat]" w+]
fconfigure $f -translation {auto binary} -buffering none
puts -nonewline $f "abcdefghijklmno\r"
# here
set x [list [gets $f line] $line [testchannel queuedcr $f]]
|
| ︙ | ︙ | |||
1290 1291 1292 1293 1294 1295 1296 |
set f [open "test1"]
fconfigure $f -buffersize 16
# here
set x [read $f]
close $f
set x
} {abcdefghijklmnopqrstuvwxyz}
| | | 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 |
set f [open "test1"]
fconfigure $f -buffersize 16
# here
set x [read $f]
close $f
set x
} {abcdefghijklmnopqrstuvwxyz}
test io-12.4 {ReadChars: split-up char} {stdio testchannel} {
# (srcRead == 0)
set f [open "|[list $::tcltest::tcltest cat]" w+]
fconfigure $f -encoding binary -buffering none -buffersize 16
puts -nonewline $f "123456789012345\x96"
fconfigure $f -encoding shiftjis -blocking 0
|
| ︙ | ︙ | |||
1409 1410 1411 1412 1413 1414 1415 |
close $f
set f [open test1]
fconfigure $f -translation crlf
set x [read $f]
close $f
set x
} "abcd\ndef\nfgh"
| | | 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 |
close $f
set f [open test1]
fconfigure $f -translation crlf
set x [read $f]
close $f
set x
} "abcd\ndef\nfgh"
test io-13.6 {TranslateInputEOL: auto mode: saw cr in last segment} {stdio testchannel} {
# (chanPtr->flags & INPUT_SAW_CR)
# This test may fail on slower machines.
set f [open "|[list $::tcltest::tcltest cat]" w+]
fconfigure $f -blocking 0 -buffering none -translation {auto lf}
fileevent $f read "ready $f"
|
| ︙ | ︙ | |||
1433 1434 1435 1436 1437 1438 1439 |
puts -nonewline $f "\n01234"
after 500 {set y ok}
vwait y
close $f
set x
} [list "abcdefghj\n" 1 "01234" 0]
| | | 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 |
puts -nonewline $f "\n01234"
after 500 {set y ok}
vwait y
close $f
set x
} [list "abcdefghj\n" 1 "01234" 0]
test io-13.7 {TranslateInputEOL: auto mode: naked \r} {testchannel} {
# (src >= srcMax)
set f [open test1 w]
fconfigure $f -translation lf
puts -nonewline $f "abcd\r"
close $f
set f [open test1]
|
| ︙ | ︙ | |||
1514 1515 1516 1517 1518 1519 1520 |
set x
} "\n\n\nab\n\nd"
# Test standard handle management. The functions tested are
# Tcl_SetStdChannel and Tcl_GetStdChannel. Incidentally we are
# also testing channel table management.
| > | | | | | > > > > > | | 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 |
set x
} "\n\n\nab\n\nd"
# Test standard handle management. The functions tested are
# Tcl_SetStdChannel and Tcl_GetStdChannel. Incidentally we are
# also testing channel table management.
if {[info commands testchannel] != ""} {
if {$tcl_platform(platform) == "macintosh"} {
set consoleFileNames [list console0 console1 console2]
} else {
set consoleFileNames [lsort [testchannel open]]
}
} else {
# just to avoid an error
set consoleFileNames [list]
}
test io-14.1 {Tcl_SetStdChannel and Tcl_GetStdChannel} {testchannel} {
set l ""
lappend l [fconfigure stdin -buffering]
lappend l [fconfigure stdout -buffering]
lappend l [fconfigure stderr -buffering]
lappend l [lsort [testchannel open]]
set l
} [list line line none $consoleFileNames]
|
| ︙ | ︙ | |||
1673 1674 1675 1676 1677 1678 1679 | # Test channel table management. The functions tested are # GetChannelTable, DeleteChannelTable, Tcl_RegisterChannel, # Tcl_UnregisterChannel, Tcl_GetChannel and Tcl_CreateChannel. # # These functions use "eof stdin" to ensure that the standard # channels are added to the channel table of the interpreter. | | | | | | | | 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 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 1758 1759 1760 1761 |
# Test channel table management. The functions tested are
# GetChannelTable, DeleteChannelTable, Tcl_RegisterChannel,
# Tcl_UnregisterChannel, Tcl_GetChannel and Tcl_CreateChannel.
#
# These functions use "eof stdin" to ensure that the standard
# channels are added to the channel table of the interpreter.
test io-17.1 {GetChannelTable, DeleteChannelTable on std handles} {testchannel} {
set l1 [testchannel refcount stdin]
eof stdin
interp create x
set l ""
lappend l [expr [testchannel refcount stdin] - $l1]
x eval {eof stdin}
lappend l [expr [testchannel refcount stdin] - $l1]
interp delete x
lappend l [expr [testchannel refcount stdin] - $l1]
set l
} {0 1 0}
test io-17.2 {GetChannelTable, DeleteChannelTable on std handles} {testchannel} {
set l1 [testchannel refcount stdout]
eof stdin
interp create x
set l ""
lappend l [expr [testchannel refcount stdout] - $l1]
x eval {eof stdout}
lappend l [expr [testchannel refcount stdout] - $l1]
interp delete x
lappend l [expr [testchannel refcount stdout] - $l1]
set l
} {0 1 0}
test io-17.3 {GetChannelTable, DeleteChannelTable on std handles} {testchannel} {
set l1 [testchannel refcount stderr]
eof stdin
interp create x
set l ""
lappend l [expr [testchannel refcount stderr] - $l1]
x eval {eof stderr}
lappend l [expr [testchannel refcount stderr] - $l1]
interp delete x
lappend l [expr [testchannel refcount stderr] - $l1]
set l
} {0 1 0}
test io-18.1 {Tcl_RegisterChannel, Tcl_UnregisterChannel} {testchannel} {
removeFile test1
set l ""
set f [open test1 w]
lappend l [lindex [testchannel info $f] 15]
close $f
if {[catch {lindex [testchannel info $f] 15} msg]} {
lappend l $msg
} else {
lappend l "very broken: $f found after being closed"
}
string compare [string tolower $l] \
[list 1 [format "can not find channel named \"%s\"" $f]]
} 0
test io-18.2 {Tcl_RegisterChannel, Tcl_UnregisterChannel} {testchannel} {
removeFile test1
set l ""
set f [open test1 w]
lappend l [lindex [testchannel info $f] 15]
interp create x
interp share "" $f x
lappend l [lindex [testchannel info $f] 15]
x eval close $f
lappend l [lindex [testchannel info $f] 15]
interp delete x
lappend l [lindex [testchannel info $f] 15]
close $f
if {[catch {lindex [testchannel info $f] 15} msg]} {
lappend l $msg
} else {
lappend l "very broken: $f found after being closed"
}
string compare [string tolower $l] \
[list 1 2 1 1 [format "can not find channel named \"%s\"" $f]]
} 0
test io-18.3 {Tcl_RegisterChannel, Tcl_UnregisterChannel} {testchannel} {
removeFile test1
set l ""
set f [open test1 w]
lappend l [lindex [testchannel info $f] 15]
interp create x
interp share "" $f x
lappend l [lindex [testchannel info $f] 15]
|
| ︙ | ︙ | |||
1778 1779 1780 1781 1782 1783 1784 |
set x [eof $f]
close $f
set x
} 0
test io-19.3 {Tcl_GetChannel, channel not found} {
list [catch {eof file34} msg] $msg
} {1 {can not find channel named "file34"}}
| | | 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 |
set x [eof $f]
close $f
set x
} 0
test io-19.3 {Tcl_GetChannel, channel not found} {
list [catch {eof file34} msg] $msg
} {1 {can not find channel named "file34"}}
test io-19.4 {Tcl_CreateChannel, insertion into channel table} {testchannel} {
removeFile test1
set f [open test1 w]
set l ""
lappend l [eof $f]
close $f
if {[catch {lindex [testchannel info $f] 15} msg]} {
lappend l $msg
|
| ︙ | ︙ | |||
1849 1850 1851 1852 1853 1854 1855 |
# Tcl_GetChannelType and Tcl_GetChannelFile. Tcl_GetChannelInstanceData
# not tested because files do not use the instance data.
test io-22.1 {Tcl_GetChannelMode} {
# Not used anywhere in Tcl.
} {}
| | | | | | 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 |
# Tcl_GetChannelType and Tcl_GetChannelFile. Tcl_GetChannelInstanceData
# not tested because files do not use the instance data.
test io-22.1 {Tcl_GetChannelMode} {
# Not used anywhere in Tcl.
} {}
test io-23.1 {Tcl_GetChannelName} {testchannel} {
removeFile test1
set f [open test1 w]
set n [testchannel name $f]
close $f
string compare $n $f
} 0
test io-24.1 {Tcl_GetChannelType} {testchannel} {
removeFile test1
set f [open test1 w]
set t [testchannel type $f]
close $f
string compare $t file
} 0
test io-25.1 {Tcl_GetChannelHandle, input} {testchannel} {
set f [open test1 w]
fconfigure $f -translation lf -eofchar {}
puts $f "1234567890\n098765432"
close $f
set f [open test1 r]
gets $f
set l ""
lappend l [testchannel inputbuffered $f]
lappend l [tell $f]
close $f
set l
} {10 11}
test io-25.2 {Tcl_GetChannelHandle, output} {testchannel} {
removeFile test1
set f [open test1 w]
fconfigure $f -translation lf
puts $f hello
set l ""
lappend l [testchannel outputbuffered $f]
lappend l [tell $f]
|
| ︙ | ︙ | |||
2008 2009 2010 2011 2012 2013 2014 |
} else {
set result ok
}
} ok
# Tests closing a channel. The functions tested are CloseChannel and Tcl_Close.
| | | 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 |
} else {
set result ok
}
} ok
# Tests closing a channel. The functions tested are CloseChannel and Tcl_Close.
test io-28.1 {CloseChannel called when all references are dropped} {testchannel} {
removeFile test1
set f [open test1 w]
interp create x
interp share "" $f x
set l ""
lappend l [testchannel refcount $f]
x eval close $f
|
| ︙ | ︙ | |||
2082 2083 2084 2085 2086 2087 2088 |
}
if {$counter == 1000} {
set result probably_broken
} else {
set result ok
}
} ok
| | | | 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 |
}
if {$counter == 1000} {
set result probably_broken
} else {
set result ok
}
} ok
test io-28.4 {Tcl_Close} {testchannel} {
removeFile test1
set l ""
lappend l [lsort [testchannel open]]
set f [open test1 w]
lappend l [lsort [testchannel open]]
close $f
lappend l [lsort [testchannel open]]
set x [list $consoleFileNames \
[lsort [eval list $consoleFileNames $f]] \
$consoleFileNames]
string compare $l $x
} 0
test io-28.5 {Tcl_Close vs standard handles} {stdio unixOnly testchannel} {
removeFile script
set f [open script w]
puts $f {
close stdin
puts [testchannel open]
}
close $f
|
| ︙ | ︙ | |||
2128 2129 2130 2131 2132 2133 2134 |
removeFile test1
set f [open test1 w]
fconfigure $f -eofchar {}
puts -nonewline $f hello
close $f
file size test1
} 5
| | | | | | | 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 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 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 |
removeFile test1
set f [open test1 w]
fconfigure $f -eofchar {}
puts -nonewline $f hello
close $f
file size test1
} 5
test io-29.4 {Tcl_WriteChars, buffering in full buffering mode} {testchannel} {
removeFile test1
set f [open test1 w]
fconfigure $f -translation lf -buffering full -eofchar {}
puts $f hello
set l ""
lappend l [testchannel outputbuffered $f]
lappend l [file size test1]
flush $f
lappend l [testchannel outputbuffered $f]
lappend l [file size test1]
close $f
set l
} {6 0 0 6}
test io-29.5 {Tcl_WriteChars, buffering in line buffering mode} {testchannel} {
removeFile test1
set f [open test1 w]
fconfigure $f -translation lf -buffering line -eofchar {}
puts -nonewline $f hello
set l ""
lappend l [testchannel outputbuffered $f]
lappend l [file size test1]
puts $f hello
lappend l [testchannel outputbuffered $f]
lappend l [file size test1]
close $f
set l
} {5 0 0 11}
test io-29.6 {Tcl_WriteChars, buffering in no buffering mode} {testchannel} {
removeFile test1
set f [open test1 w]
fconfigure $f -translation lf -buffering none -eofchar {}
puts -nonewline $f hello
set l ""
lappend l [testchannel outputbuffered $f]
lappend l [file size test1]
puts $f hello
lappend l [testchannel outputbuffered $f]
lappend l [file size test1]
close $f
set l
} {0 5 0 11}
test io-29.7 {Tcl_Flush, full buffering} {testchannel} {
removeFile test1
set f [open test1 w]
fconfigure $f -translation lf -buffering full -eofchar {}
puts -nonewline $f hello
set l ""
lappend l [testchannel outputbuffered $f]
lappend l [file size test1]
puts $f hello
lappend l [testchannel outputbuffered $f]
lappend l [file size test1]
flush $f
lappend l [testchannel outputbuffered $f]
lappend l [file size test1]
close $f
set l
} {5 0 11 0 0 11}
test io-29.8 {Tcl_Flush, full buffering} {testchannel} {
removeFile test1
set f [open test1 w]
fconfigure $f -translation lf -buffering line
puts -nonewline $f hello
set l ""
lappend l [testchannel outputbuffered $f]
lappend l [file size test1]
|
| ︙ | ︙ | |||
4667 4668 4669 4670 4671 4672 4673 |
vwait x
set l
} {abc def ghi jkl mno {p
} eof}
# Test Tcl_InputBuffered
| | | | 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 |
vwait x
set l
} {abc def ghi jkl mno {p
} eof}
# Test Tcl_InputBuffered
test io-37.1 {Tcl_InputBuffered} {testchannel} {
set f [open longfile r]
fconfigure $f -buffersize 4096
read $f 3
set l ""
lappend l [testchannel inputbuffered $f]
lappend l [tell $f]
close $f
set l
} {4093 3}
test io-37.2 {Tcl_InputBuffered, test input flushing on seek} {testchannel} {
set f [open longfile r]
fconfigure $f -buffersize 4096
read $f 3
set l ""
lappend l [testchannel inputbuffered $f]
lappend l [tell $f]
seek $f 0 current
|
| ︙ | ︙ | |||
5093 5094 5095 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106 |
test io-40.6 {POSIX open access modes: EXCL} {
removeFile test3
set f [open test3 w]
puts $f xyzzy
close $f
set msg [list [catch {open test3 {WRONLY CREAT EXCL}} msg] $msg]
regsub " already " $msg " " msg
string tolower $msg
} {1 {couldn't open "test3": file exists}}
test io-40.7 {POSIX open access modes: EXCL} {
removeFile test3
set f [open test3 {WRONLY CREAT EXCL}]
fconfigure $f -eofchar {}
puts $f "A test line"
| > | 5095 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 5108 5109 |
test io-40.6 {POSIX open access modes: EXCL} {
removeFile test3
set f [open test3 w]
puts $f xyzzy
close $f
set msg [list [catch {open test3 {WRONLY CREAT EXCL}} msg] $msg]
regsub " already " $msg " " msg
regsub [file join {} test3] $msg "test3" msg
string tolower $msg
} {1 {couldn't open "test3": file exists}}
test io-40.7 {POSIX open access modes: EXCL} {
removeFile test3
set f [open test3 {WRONLY CREAT EXCL}]
fconfigure $f -eofchar {}
puts $f "A test line"
|
| ︙ | ︙ | |||
5140 5141 5142 5143 5144 5145 5146 |
close $f
string compare [string tolower $x] \
[list {two lines: this one} 1 \
[format "channel \"%s\" wasn't opened for writing" $f]]
} 0
test io-40.11 {POSIX open access modes: RDONLY} {
removeFile test3
| | > > | > > | > > | 5143 5144 5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182 5183 |
close $f
string compare [string tolower $x] \
[list {two lines: this one} 1 \
[format "channel \"%s\" wasn't opened for writing" $f]]
} 0
test io-40.11 {POSIX open access modes: RDONLY} {
removeFile test3
set msg [list [catch {open test3 RDONLY} msg] $msg]
regsub [file join {} test3] $msg "test3" msg
string tolower $msg
} {1 {couldn't open "test3": no such file or directory}}
test io-40.12 {POSIX open access modes: WRONLY} {
removeFile test3
set msg [list [catch {open test3 WRONLY} msg] $msg]
regsub [file join {} test3] $msg "test3" msg
string tolower $msg
} {1 {couldn't open "test3": no such file or directory}}
test io-40.13 {POSIX open access modes: WRONLY} {
makeFile xyzzy test3
set f [open test3 WRONLY]
fconfigure $f -eofchar {}
puts -nonewline $f "ab"
seek $f 0 current
set x [list [catch {gets $f} msg] $msg]
close $f
lappend x [viewFile test3]
string compare [string tolower $x] \
[list 1 "channel \"$f\" wasn't opened for reading" abzzy]
} 0
test io-40.14 {POSIX open access modes: RDWR} {
removeFile test3
set msg [list [catch {open test3 RDWR} msg] $msg]
regsub [file join {} test3] $msg "test3" msg
string tolower $msg
} {1 {couldn't open "test3": no such file or directory}}
test io-40.15 {POSIX open access modes: RDWR} {
makeFile xyzzy test3
set f [open test3 RDWR]
puts -nonewline $f "ab"
seek $f 0 current
set x [gets $f]
|
| ︙ | ︙ | |||
6050 6051 6052 6053 6054 6055 6056 |
lappend l [gets $f]
lappend l [tell $f]
lappend l [eof $f]
close $f
set l
} [list 7 a\rb\rc 7 {} 7 1]
| | | | | 6059 6060 6061 6062 6063 6064 6065 6066 6067 6068 6069 6070 6071 6072 6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085 6086 6087 6088 6089 6090 6091 6092 6093 6094 6095 6096 6097 6098 6099 6100 6101 6102 6103 6104 6105 6106 6107 |
lappend l [gets $f]
lappend l [tell $f]
lappend l [eof $f]
close $f
set l
} [list 7 a\rb\rc 7 {} 7 1]
test io-50.1 {testing handler deletion} {testchannel} {
removeFile test1
set f [open test1 w]
close $f
set f [open test1 r]
testchannelevent $f add readable [list delhandler $f]
proc delhandler {f} {
global z
set z called
testchannelevent $f delete 0
}
set z not_called
update
close $f
set z
} called
test io-50.2 {testing handler deletion with multiple handlers} {testchannel} {
removeFile test1
set f [open test1 w]
close $f
set f [open test1 r]
testchannelevent $f add readable [list delhandler $f 1]
testchannelevent $f add readable [list delhandler $f 0]
proc delhandler {f i} {
global z
lappend z "called delhandler $f $i"
testchannelevent $f delete 0
}
set z ""
update
close $f
string compare [string tolower $z] \
[list [list called delhandler $f 0] [list called delhandler $f 1]]
} 0
test io-50.3 {testing handler deletion with multiple handlers} {testchannel} {
removeFile test1
set f [open test1 w]
close $f
set f [open test1 r]
testchannelevent $f add readable [list notcalled $f 1]
testchannelevent $f add readable [list delhandler $f 0]
set z ""
|
| ︙ | ︙ | |||
6110 6111 6112 6113 6114 6115 6116 |
set z ""
update
close $f
string compare [string tolower $z] \
[list [list delhandler $f 0 called] \
[list delhandler $f 0 deleted myself]]
} 0
| | | 6119 6120 6121 6122 6123 6124 6125 6126 6127 6128 6129 6130 6131 6132 6133 |
set z ""
update
close $f
string compare [string tolower $z] \
[list [list delhandler $f 0 called] \
[list delhandler $f 0 deleted myself]]
} 0
test io-50.4 {testing handler deletion vs reentrant calls} {testchannel} {
removeFile test1
set f [open test1 w]
close $f
set f [open test1 r]
testchannelevent $f add readable [list delrecursive $f]
proc delrecursive {f} {
global z u
|
| ︙ | ︙ | |||
6134 6135 6136 6137 6138 6139 6140 |
set u toplevel
set z ""
update
close $f
string compare [string tolower $z] \
{{delrecursive calling recursive} {delrecursive deleting recursive}}
} 0
| | | 6143 6144 6145 6146 6147 6148 6149 6150 6151 6152 6153 6154 6155 6156 6157 |
set u toplevel
set z ""
update
close $f
string compare [string tolower $z] \
{{delrecursive calling recursive} {delrecursive deleting recursive}}
} 0
test io-50.5 {testing handler deletion vs reentrant calls} {testchannel} {
removeFile test1
set f [open test1 w]
close $f
set f [open test1 r]
testchannelevent $f add readable [list notcalled $f]
testchannelevent $f add readable [list del $f]
proc notcalled {f} {
|
| ︙ | ︙ | |||
6167 6168 6169 6170 6171 6172 6173 |
set u toplevel
update
close $f
string compare [string tolower $z] \
[list {del calling recursive} {del deleted notcalled} \
{del deleted myself} {del after update}]
} 0
| | | 6176 6177 6178 6179 6180 6181 6182 6183 6184 6185 6186 6187 6188 6189 6190 |
set u toplevel
update
close $f
string compare [string tolower $z] \
[list {del calling recursive} {del deleted notcalled} \
{del deleted myself} {del after update}]
} 0
test io-50.6 {testing handler deletion vs reentrant calls} {testchannel} {
removeFile test1
set f [open test1 w]
close $f
set f [open test1 r]
testchannelevent $f add readable [list second $f]
testchannelevent $f add readable [list first $f]
proc first {f} {
|
| ︙ | ︙ | |||
6719 6720 6721 6722 6723 6724 6725 |
set f [open fooBar w]
fileevent $f writable [list eventScript $f]
set x not_done
vwait x
set x
} {got_error}
| | | 6728 6729 6730 6731 6732 6733 6734 6735 6736 6737 6738 6739 6740 6741 6742 |
set f [open fooBar w]
fileevent $f writable [list eventScript $f]
set x not_done
vwait x
set x
} {got_error}
test io-56.1 {ChannelTimerProc} {testchannel} {
set f [open fooBar w]
puts $f "this is a test"
close $f
set f [open fooBar r]
testchannelevent $f add readable {
read $f 1
incr x
|
| ︙ | ︙ |
Changes to tests/ioCmd.test.
| ︙ | ︙ | |||
8 9 10 11 12 13 14 | # Copyright (c) 1991-1994 The Regents of the University of California. # Copyright (c) 1994-1996 Sun Microsystems, Inc. # Copyright (c) 1998-1999 by Scriptics Corporation. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# Copyright (c) 1991-1994 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: ioCmd.test,v 1.9 2001/07/31 19:12:07 vincentdarley Exp $
if {[lsearch [namespace children] ::tcltest] == -1} {
package require tcltest
namespace import -force ::tcltest::*
}
removeFile test1
|
| ︙ | ︙ | |||
357 358 359 360 361 362 363 |
set x [list [gets $f] [catch {puts $f Test} msg] $msg]
close $f
string compare $x \
"{Two lines: this one} 1 [list [format "channel \"%s\" wasn't opened for writing" $f]]"
} 0
test iocmd-12.2 {POSIX open access modes: RDONLY} {
removeFile test3
| | > > | > > | 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 |
set x [list [gets $f] [catch {puts $f Test} msg] $msg]
close $f
string compare $x \
"{Two lines: this one} 1 [list [format "channel \"%s\" wasn't opened for writing" $f]]"
} 0
test iocmd-12.2 {POSIX open access modes: RDONLY} {
removeFile test3
set msg [list [catch {open test3 RDONLY} msg] $msg]
regsub [file join {} test3] $msg "test3" msg
string tolower $msg
} {1 {couldn't open "test3": no such file or directory}}
test iocmd-12.3 {POSIX open access modes: WRONLY} {
removeFile test3
set msg [list [catch {open test3 WRONLY} msg] $msg]
regsub [file join {} test3] $msg "test3" msg
string tolower $msg
} {1 {couldn't open "test3": no such file or directory}}
#
# Test 13.4 relies on assigning the same channel name twice.
#
test iocmd-12.4 {POSIX open access modes: WRONLY} {unixOnly} {
removeFile test3
set f [open test3 w]
|
| ︙ | ︙ | |||
387 388 389 390 391 392 393 |
lappend x [gets $f]
close $f
set y [list 1 [format "channel \"%s\" wasn't opened for reading" $f] abzzy]
string compare $x $y
} 0
test iocmd-12.5 {POSIX open access modes: RDWR} {
removeFile test3
| | > > | 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 |
lappend x [gets $f]
close $f
set y [list 1 [format "channel \"%s\" wasn't opened for reading" $f] abzzy]
string compare $x $y
} 0
test iocmd-12.5 {POSIX open access modes: RDWR} {
removeFile test3
set msg [list [catch {open test3 RDWR} msg] $msg]
regsub [file join {} test3] $msg "test3" msg
string tolower $msg
} {1 {couldn't open "test3": no such file or directory}}
test iocmd-12.6 {POSIX open access modes: errors} {
concat [catch {open test3 "FOO \{BAR BAZ"} msg] $msg\n$errorInfo
} "1 unmatched open brace in list
unmatched open brace in list
while processing open access modes \"FOO {BAR BAZ\"
invoked from within
|
| ︙ | ︙ | |||
419 420 421 422 423 424 425 |
test iocmd-13.4 {errors in open command} {
list [catch {open test1 rw} msg] $msg
} {1 {illegal access mode "rw"}}
test iocmd-13.5 {errors in open command} {
list [catch {open test1 r+1} msg] $msg
} {1 {illegal access mode "r+1"}}
test iocmd-13.6 {errors in open command} {
| | > > | 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 |
test iocmd-13.4 {errors in open command} {
list [catch {open test1 rw} msg] $msg
} {1 {illegal access mode "rw"}}
test iocmd-13.5 {errors in open command} {
list [catch {open test1 r+1} msg] $msg
} {1 {illegal access mode "r+1"}}
test iocmd-13.6 {errors in open command} {
set msg [list [catch {open _non_existent_} msg] $msg $errorCode]
regsub [file join {} _non_existent_] $msg "_non_existent_" msg
string tolower $msg
} {1 {couldn't open "_non_existent_": no such file or directory} {posix enoent {no such file or directory}}}
test iocmd-14.1 {file id parsing errors} {
list [catch {eof gorp} msg] $msg $errorCode
} {1 {can not find channel named "gorp"} NONE}
test iocmd-14.2 {file id parsing errors} {
list [catch {eof filex} msg] $msg
|
| ︙ | ︙ |
Changes to tests/proc-old.test.
| ︙ | ︙ | |||
10 11 12 13 14 15 16 | # Copyright (c) 1991-1993 The Regents of the University of California. # Copyright (c) 1994-1997 Sun Microsystems, Inc. # Copyright (c) 1998-1999 by Scriptics Corporation. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# Copyright (c) 1991-1993 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: proc-old.test,v 1.8 2001/07/31 19:12:07 vincentdarley Exp $
if {[lsearch [namespace children] ::tcltest] == -1} {
package require tcltest
namespace import -force ::tcltest::*
}
catch {rename t1 ""}
|
| ︙ | ︙ | |||
429 430 431 432 433 434 435 |
} {1 {}}
test proc-old-7.11 {return with special completion code} {
proc tproc2 {} {
global errorCode errorInfo
catch {open _bad_file_name r} msg
return -code error -errorinfo $errorInfo -errorcode $errorCode $msg
}
| | > > | > > | > > | > > | 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 472 473 474 475 476 477 478 479 480 481 482 483 484 485 |
} {1 {}}
test proc-old-7.11 {return with special completion code} {
proc tproc2 {} {
global errorCode errorInfo
catch {open _bad_file_name r} msg
return -code error -errorinfo $errorInfo -errorcode $errorCode $msg
}
set msg [list [catch tproc2 msg] $msg $errorInfo $errorCode]
regsub -all [file join {} _bad_file_name] $msg "_bad_file_name" msg
normalizeMsg $msg
} {1 {couldn't open "_bad_file_name": no such file or directory} {couldn't open "_bad_file_name": no such file or directory
while executing
"open _bad_file_name r"
invoked from within
"tproc2"} {posix enoent {no such file or directory}}}
test proc-old-7.12 {return with special completion code} {
proc tproc2 {} {
global errorCode errorInfo
catch {open _bad_file_name r} msg
return -code error -errorcode $errorCode $msg
}
set msg [list [catch tproc2 msg] $msg $errorInfo $errorCode]
regsub -all [file join {} _bad_file_name] $msg "_bad_file_name" msg
normalizeMsg $msg
} {1 {couldn't open "_bad_file_name": no such file or directory} {couldn't open "_bad_file_name": no such file or directory
while executing
"tproc2"} {posix enoent {no such file or directory}}}
test proc-old-7.13 {return with special completion code} {
proc tproc2 {} {
global errorCode errorInfo
catch {open _bad_file_name r} msg
return -code error -errorinfo $errorInfo $msg
}
set msg [list [catch tproc2 msg] $msg $errorInfo $errorCode]
regsub -all [file join {} _bad_file_name] $msg "_bad_file_name" msg
normalizeMsg $msg
} {1 {couldn't open "_bad_file_name": no such file or directory} {couldn't open "_bad_file_name": no such file or directory
while executing
"open _bad_file_name r"
invoked from within
"tproc2"} none}
test proc-old-7.14 {return with special completion code} {
proc tproc2 {} {
global errorCode errorInfo
catch {open _bad_file_name r} msg
return -code error $msg
}
set msg [list [catch tproc2 msg] $msg $errorInfo $errorCode]
regsub -all [file join {} _bad_file_name] $msg "_bad_file_name" msg
normalizeMsg $msg
} {1 {couldn't open "_bad_file_name": no such file or directory} {couldn't open "_bad_file_name": no such file or directory
while executing
"tproc2"} none}
test proc-old-7.14 {return with special completion code} {
list [catch {return -badOption foo message} msg] $msg
} {1 {bad option "-badOption": must be -code, -errorcode, or -errorinfo}}
|
| ︙ | ︙ |
Changes to tests/registry.test.
1 2 3 4 5 6 7 8 9 10 11 12 | # registry.test -- # # This file contains a collection of tests for the registry command. # Sourcing this file into Tcl runs the tests and generates output for # errors. No output means no errors were found. # # In order for these tests to run, the registry package must be on the # auto_path or the registry package must have been loaded already. # # Copyright (c) 1997 by Sun Microsystems, Inc. All rights reserved. # Copyright (c) 1998-1999 by Scriptics Corporation. # | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# registry.test --
#
# This file contains a collection of tests for the registry command.
# Sourcing this file into Tcl runs the tests and generates output for
# errors. No output means no errors were found.
#
# In order for these tests to run, the registry package must be on the
# auto_path or the registry package must have been loaded already.
#
# Copyright (c) 1997 by Sun Microsystems, Inc. All rights reserved.
# Copyright (c) 1998-1999 by Scriptics Corporation.
#
# RCS: @(#) $Id: registry.test,v 1.11 2001/07/31 19:12:07 vincentdarley Exp $
if {[lsearch [namespace children] ::tcltest] == -1} {
package require tcltest
namespace import -force ::tcltest::*
}
if {$tcl_platform(platform) == "windows"} {
if [catch {
set lib [lindex [glob -directory [file join [pwd] [file dirname \
[info nameofexecutable]]] tclreg*.dll] 0]
load $lib registry
}] {
puts "Unable to find the registry package. Skipping registry tests."
return
}
}
|
| ︙ | ︙ |
Changes to tests/unixFCmd.test.
1 2 3 4 5 6 7 8 9 10 11 | # This file tests the tclUnixFCmd.c file. # # This file contains a collection of tests for one or more of the Tcl # built-in commands. Sourcing this file into Tcl runs the tests and # generates output for errors. No output means no errors were found. # # Copyright (c) 1996 Sun Microsystems, Inc. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# This file tests the tclUnixFCmd.c file.
#
# This file contains a collection of tests for one or more of the Tcl
# built-in commands. Sourcing this file into Tcl runs the tests and
# generates output for errors. No output means no errors were found.
#
# Copyright (c) 1996 Sun Microsystems, Inc.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: unixFCmd.test,v 1.12 2001/07/31 19:12:07 vincentdarley Exp $
if {[lsearch [namespace children] ::tcltest] == -1} {
package require tcltest
namespace import -force ::tcltest::*
}
# Several tests require need to match results against the unix username
|
| ︙ | ︙ | |||
28 29 30 31 32 33 34 |
}
}
proc openup {path} {
testchmod 777 $path
if {[file isdirectory $path]} {
catch {
| | | | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
}
}
proc openup {path} {
testchmod 777 $path
if {[file isdirectory $path]} {
catch {
foreach p [glob -directory $path *] {
openup $p
}
}
}
}
proc cleanup {args} {
foreach p ". $args" {
set x ""
catch {
set x [glob -directory $p tf* td*]
}
foreach file $x {
if {[catch {file delete -force -- $file}]} {
openup $file
file delete -force -- $file
}
}
|
| ︙ | ︙ |
Changes to tests/winDde.test.
1 2 3 4 5 6 7 8 9 10 11 | # This file tests the tclWinDde.c file. # # This file contains a collection of tests for one or more of the Tcl # built-in commands. Sourcing this file into Tcl runs the tests and # generates output for errors. No output means no errors were found. # # Copyright (c) 1999 by Scriptics Corporation. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# This file tests the tclWinDde.c file.
#
# This file contains a collection of tests for one or more of the Tcl
# built-in commands. Sourcing this file into Tcl runs the tests and
# generates output for errors. No output means no errors were found.
#
# Copyright (c) 1999 by Scriptics Corporation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: winDde.test,v 1.10 2001/07/31 19:12:07 vincentdarley Exp $
if {[lsearch [namespace children] ::tcltest] == -1} {
package require tcltest
namespace import -force ::tcltest::*
}
if {$tcl_platform(platform) == "windows"} {
if [catch {
set lib [lindex [glob -directory [file join [pwd] [file dirname \
[info nameofexecutable]]] tcldde*.dll] 0]
load $lib dde
}] {
puts "Unable to find the dde package. Skipping dde tests."
::tcltest::cleanupTests
return
}
}
set scriptName script1.tcl
proc createChildProcess { ddeServerName } {
file delete -force $::scriptName
set f [open $::scriptName w+]
puts $f {
if [catch {
set lib [lindex [glob -directory [file join [pwd] [file dirname \
[info nameofexecutable]]] tcldde*.dll] 0]
load $lib dde
}] {
puts "Unable to find the dde package. Skipping dde tests."
::tcltest::cleanupTests
return
}
}
puts $f "dde servername $ddeServerName"
puts $f {
puts ready
|
| ︙ | ︙ |
Changes to tests/winFCmd.test.
1 2 3 4 5 6 7 8 9 10 11 12 | # This file tests the tclWinFCmd.c file. # # This file contains a collection of tests for one or more of the Tcl # built-in commands. Sourcing this file into Tcl runs the tests and # generates output for errors. No output means no errors were found. # # Copyright (c) 1996-1997 Sun Microsystems, Inc. # Copyright (c) 1998-1999 by Scriptics Corporation. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# This file tests the tclWinFCmd.c file.
#
# This file contains a collection of tests for one or more of the Tcl
# built-in commands. Sourcing this file into Tcl runs the tests and
# generates output for errors. No output means no errors were found.
#
# Copyright (c) 1996-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: winFCmd.test,v 1.10 2001/07/31 19:12:07 vincentdarley Exp $
#
if {[lsearch [namespace children] ::tcltest] == -1} {
package require tcltest
namespace import -force ::tcltest::*
}
|
| ︙ | ︙ | |||
32 33 34 35 36 37 38 |
set r
}
proc cleanup {args} {
foreach p ". $args" {
set x ""
catch {
| | | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
set r
}
proc cleanup {args} {
foreach p ". $args" {
set x ""
catch {
set x [glob -directory $p tf* td*]
}
if {$x != ""} {
catch {eval file delete -force -- $x}
}
}
}
|
| ︙ | ︙ |
Changes to unix/mkLinks.
| ︙ | ︙ | |||
438 439 440 441 442 443 444 445 446 447 448 449 450 451 |
rm -f Tcl_ExprBooleanObj.3
rm -f Tcl_ExprObj.3
ln ExprLongObj.3 Tcl_ExprLongObj.3
ln ExprLongObj.3 Tcl_ExprDoubleObj.3
ln ExprLongObj.3 Tcl_ExprBooleanObj.3
ln ExprLongObj.3 Tcl_ExprObj.3
fi
if test -r FindExec.3; then
rm -f Tcl_FindExecutable.3
rm -f Tcl_GetNameOfExecutable.3
ln FindExec.3 Tcl_FindExecutable.3
ln FindExec.3 Tcl_GetNameOfExecutable.3
fi
if test -r GetCwd.3; then
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 |
rm -f Tcl_ExprBooleanObj.3
rm -f Tcl_ExprObj.3
ln ExprLongObj.3 Tcl_ExprLongObj.3
ln ExprLongObj.3 Tcl_ExprDoubleObj.3
ln ExprLongObj.3 Tcl_ExprBooleanObj.3
ln ExprLongObj.3 Tcl_ExprObj.3
fi
if test -r FileSystem.3; then
rm -f Tcl_FSCopyFile.3
rm -f Tcl_FSCopyDirectory.3
rm -f Tcl_FSCreateDirectory.3
rm -f Tcl_FSDeleteFile.3
rm -f Tcl_FSRemoveDirectory.3
rm -f Tcl_FSRenameFile.3
rm -f Tcl_FSListVolumes.3
rm -f Tcl_FSEvalFile.3
rm -f Tcl_FSLoadFile.3
rm -f Tcl_FSMatchInDirectory.3
rm -f Tcl_FSReadlink.3
rm -f Tcl_FSLstat.3
rm -f Tcl_FSUtime.3
rm -f Tcl_FSFileAttrsGet.3
rm -f Tcl_FSFileAttrsSet.3
rm -f Tcl_FSFileAttrStrings.3
rm -f Tcl_FSStat.3
rm -f Tcl_FSAccess.3
rm -f Tcl_FSOpenFileChannel.3
rm -f Tcl_FSGetCwd.3
rm -f Tcl_FSChdir.3
rm -f Tcl_FSPathSeparator.3
rm -f Tcl_FSJoinPath.3
rm -f Tcl_FSSplitPath.3
rm -f Tcl_FSEqualPaths.3
rm -f Tcl_FSGetNormalizedPath.3
rm -f Tcl_FSJoinToPath.3
rm -f Tcl_FSConvertToPathType.3
rm -f Tcl_FSGetInternalRep.3
rm -f Tcl_FSGetTranslatedPath.3
rm -f Tcl_FSNewNativePath.3
rm -f Tcl_FSGetNativePath.3
rm -f Tcl_FSFileSystemInfo.3
ln FileSystem.3 Tcl_FSCopyFile.3
ln FileSystem.3 Tcl_FSCopyDirectory.3
ln FileSystem.3 Tcl_FSCreateDirectory.3
ln FileSystem.3 Tcl_FSDeleteFile.3
ln FileSystem.3 Tcl_FSRemoveDirectory.3
ln FileSystem.3 Tcl_FSRenameFile.3
ln FileSystem.3 Tcl_FSListVolumes.3
ln FileSystem.3 Tcl_FSEvalFile.3
ln FileSystem.3 Tcl_FSLoadFile.3
ln FileSystem.3 Tcl_FSMatchInDirectory.3
ln FileSystem.3 Tcl_FSReadlink.3
ln FileSystem.3 Tcl_FSLstat.3
ln FileSystem.3 Tcl_FSUtime.3
ln FileSystem.3 Tcl_FSFileAttrsGet.3
ln FileSystem.3 Tcl_FSFileAttrsSet.3
ln FileSystem.3 Tcl_FSFileAttrStrings.3
ln FileSystem.3 Tcl_FSStat.3
ln FileSystem.3 Tcl_FSAccess.3
ln FileSystem.3 Tcl_FSOpenFileChannel.3
ln FileSystem.3 Tcl_FSGetCwd.3
ln FileSystem.3 Tcl_FSChdir.3
ln FileSystem.3 Tcl_FSPathSeparator.3
ln FileSystem.3 Tcl_FSJoinPath.3
ln FileSystem.3 Tcl_FSSplitPath.3
ln FileSystem.3 Tcl_FSEqualPaths.3
ln FileSystem.3 Tcl_FSGetNormalizedPath.3
ln FileSystem.3 Tcl_FSJoinToPath.3
ln FileSystem.3 Tcl_FSConvertToPathType.3
ln FileSystem.3 Tcl_FSGetInternalRep.3
ln FileSystem.3 Tcl_FSGetTranslatedPath.3
ln FileSystem.3 Tcl_FSNewNativePath.3
ln FileSystem.3 Tcl_FSGetNativePath.3
ln FileSystem.3 Tcl_FSFileSystemInfo.3
fi
if test -r FindExec.3; then
rm -f Tcl_FindExecutable.3
rm -f Tcl_GetNameOfExecutable.3
ln FindExec.3 Tcl_FindExecutable.3
ln FindExec.3 Tcl_GetNameOfExecutable.3
fi
if test -r GetCwd.3; then
|
| ︙ | ︙ | |||
647 648 649 650 651 652 653 654 655 656 657 658 659 660 |
rm -f Tcl_OpenCommandChannel.3
rm -f Tcl_MakeFileChannel.3
rm -f Tcl_GetChannel.3
rm -f Tcl_GetChannelNames.3
rm -f Tcl_GetChannelNamesEx.3
rm -f Tcl_RegisterChannel.3
rm -f Tcl_UnregisterChannel.3
rm -f Tcl_Close.3
rm -f Tcl_ReadChars.3
rm -f Tcl_Read.3
rm -f Tcl_GetsObj.3
rm -f Tcl_Gets.3
rm -f Tcl_WriteObj.3
rm -f Tcl_WriteChars.3
| > > | 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 |
rm -f Tcl_OpenCommandChannel.3
rm -f Tcl_MakeFileChannel.3
rm -f Tcl_GetChannel.3
rm -f Tcl_GetChannelNames.3
rm -f Tcl_GetChannelNamesEx.3
rm -f Tcl_RegisterChannel.3
rm -f Tcl_UnregisterChannel.3
rm -f Tcl_DetachChannel.3
rm -f Tcl_IsStandardChannel.3
rm -f Tcl_Close.3
rm -f Tcl_ReadChars.3
rm -f Tcl_Read.3
rm -f Tcl_GetsObj.3
rm -f Tcl_Gets.3
rm -f Tcl_WriteObj.3
rm -f Tcl_WriteChars.3
|
| ︙ | ︙ | |||
672 673 674 675 676 677 678 679 680 681 682 683 684 685 |
ln OpenFileChnl.3 Tcl_OpenCommandChannel.3
ln OpenFileChnl.3 Tcl_MakeFileChannel.3
ln OpenFileChnl.3 Tcl_GetChannel.3
ln OpenFileChnl.3 Tcl_GetChannelNames.3
ln OpenFileChnl.3 Tcl_GetChannelNamesEx.3
ln OpenFileChnl.3 Tcl_RegisterChannel.3
ln OpenFileChnl.3 Tcl_UnregisterChannel.3
ln OpenFileChnl.3 Tcl_Close.3
ln OpenFileChnl.3 Tcl_ReadChars.3
ln OpenFileChnl.3 Tcl_Read.3
ln OpenFileChnl.3 Tcl_GetsObj.3
ln OpenFileChnl.3 Tcl_Gets.3
ln OpenFileChnl.3 Tcl_WriteObj.3
ln OpenFileChnl.3 Tcl_WriteChars.3
| > > | 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 |
ln OpenFileChnl.3 Tcl_OpenCommandChannel.3
ln OpenFileChnl.3 Tcl_MakeFileChannel.3
ln OpenFileChnl.3 Tcl_GetChannel.3
ln OpenFileChnl.3 Tcl_GetChannelNames.3
ln OpenFileChnl.3 Tcl_GetChannelNamesEx.3
ln OpenFileChnl.3 Tcl_RegisterChannel.3
ln OpenFileChnl.3 Tcl_UnregisterChannel.3
ln OpenFileChnl.3 Tcl_DetachChannel.3
ln OpenFileChnl.3 Tcl_IsStandardChannel.3
ln OpenFileChnl.3 Tcl_Close.3
ln OpenFileChnl.3 Tcl_ReadChars.3
ln OpenFileChnl.3 Tcl_Read.3
ln OpenFileChnl.3 Tcl_GetsObj.3
ln OpenFileChnl.3 Tcl_Gets.3
ln OpenFileChnl.3 Tcl_WriteObj.3
ln OpenFileChnl.3 Tcl_WriteChars.3
|
| ︙ | ︙ |
Changes to unix/tclUnixFCmd.c.
1 2 3 4 5 6 7 8 9 10 11 12 | /* * tclUnixFCmd.c * * This file implements the unix specific portion of file manipulation * subcommands of the "file" command. All filename arguments should * already be translated to native format. * * Copyright (c) 1996-1998 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | /* * tclUnixFCmd.c * * This file implements the unix specific portion of file manipulation * subcommands of the "file" command. All filename arguments should * already be translated to native format. * * Copyright (c) 1996-1998 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclUnixFCmd.c,v 1.7 2001/07/31 19:12:07 vincentdarley Exp $ * * Portions of this code were derived from NetBSD source code which has * the following copyright notice: * * Copyright (c) 1988, 1993, 1994 * The Regents of the University of California. All rights reserved. * |
| ︙ | ︙ | |||
145 146 147 148 149 150 151 152 153 154 155 156 157 158 | static int TraversalDelete _ANSI_ARGS_((Tcl_DString *srcPtr, Tcl_DString *dstPtr, CONST struct stat *statBufPtr, int type, Tcl_DString *errorPtr)); static int TraverseUnixTree _ANSI_ARGS_(( TraversalProc *traversalProc, Tcl_DString *sourcePtr, Tcl_DString *destPtr, Tcl_DString *errorPtr)); /* *--------------------------------------------------------------------------- * * TclpRenameFile, DoRenameFile -- * * Changes the name of an existing file or directory, from src to dst. | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
static int TraversalDelete _ANSI_ARGS_((Tcl_DString *srcPtr,
Tcl_DString *dstPtr, CONST struct stat *statBufPtr,
int type, Tcl_DString *errorPtr));
static int TraverseUnixTree _ANSI_ARGS_((
TraversalProc *traversalProc,
Tcl_DString *sourcePtr, Tcl_DString *destPtr,
Tcl_DString *errorPtr));
int
TclpObjCreateDirectory(pathPtr)
Tcl_Obj *pathPtr;
{
return TclpCreateDirectory(Tcl_FSGetTranslatedPath(NULL, pathPtr));
}
int
TclpObjDeleteFile(pathPtr)
Tcl_Obj *pathPtr;
{
return TclpDeleteFile(Tcl_FSGetTranslatedPath(NULL, pathPtr));
}
int
TclpObjCopyDirectory(srcPathPtr, destPathPtr, errorPtr)
Tcl_Obj *srcPathPtr;
Tcl_Obj *destPathPtr;
Tcl_Obj **errorPtr;
{
Tcl_DString ds;
int ret;
ret = TclpCopyDirectory(Tcl_FSGetTranslatedPath(NULL,srcPathPtr),
Tcl_FSGetTranslatedPath(NULL,destPathPtr), &ds);
if (ret != TCL_OK) {
*errorPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds), -1);
Tcl_DStringFree(&ds);
Tcl_IncrRefCount(*errorPtr);
}
return ret;
}
int
TclpObjCopyFile(srcPathPtr, destPathPtr)
Tcl_Obj *srcPathPtr;
Tcl_Obj *destPathPtr;
{
return TclpCopyFile(Tcl_FSGetTranslatedPath(NULL,srcPathPtr),
Tcl_FSGetTranslatedPath(NULL,destPathPtr));
}
int
TclpObjRemoveDirectory(pathPtr, recursive, errorPtr)
Tcl_Obj *pathPtr;
int recursive;
Tcl_Obj **errorPtr;
{
Tcl_DString ds;
int ret;
ret = TclpRemoveDirectory(Tcl_FSGetTranslatedPath(NULL, pathPtr),recursive, &ds);
if (ret != TCL_OK) {
*errorPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds), -1);
Tcl_DStringFree(&ds);
Tcl_IncrRefCount(*errorPtr);
}
return ret;
}
int
TclpObjRenameFile(srcPathPtr, destPathPtr)
Tcl_Obj *srcPathPtr;
Tcl_Obj *destPathPtr;
{
return TclpRenameFile(Tcl_FSGetTranslatedPath(NULL,srcPathPtr),
Tcl_FSGetTranslatedPath(NULL,destPathPtr));
}
/*
*---------------------------------------------------------------------------
*
* TclpRenameFile, DoRenameFile --
*
* Changes the name of an existing file or directory, from src to dst.
|
| ︙ | ︙ | |||
1605 1606 1607 1608 1609 1610 1611 |
case 3 :
*modePtr = (oldMode & ~who) | (who & what);
continue;
}
}
return TCL_OK;
}
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 1724 1725 1726 1727 |
case 3 :
*modePtr = (oldMode & ~who) | (who & what);
continue;
}
}
return TCL_OK;
}
/*
*---------------------------------------------------------------------------
*
* TclpObjNormalizePath --
*
* This function scans through a path specification and replaces
* it, in place, with a normalized version. On unix, this simply
* ascertains where the valid path ends, and makes no change in
* place.
*
* Results:
* The new 'nextCheckpoint' value, giving as far as we could
* understand in the path.
*
* Side effects:
* The pathPtr string, which must contain a valid path, is
* not modified (unlike Windows, MacOS versions).
*
*---------------------------------------------------------------------------
*/
int
TclpObjNormalizePath(interp, pathPtr, nextCheckpoint)
Tcl_Interp *interp;
Tcl_Obj *pathPtr;
int nextCheckpoint;
{
char *path = Tcl_GetString(pathPtr);
while (1) {
char cur = path[nextCheckpoint];
if (cur == 0) {
break;
}
if (cur == '/') {
int access;
path[nextCheckpoint] = 0;
access = TclpAccess(path, F_OK);
path[nextCheckpoint] = '/';
if (access != 0) {
/* File doesn't exist */
break;
}
}
nextCheckpoint++;
}
return nextCheckpoint;
}
|
Changes to unix/tclUnixFile.c.
1 2 3 4 5 6 7 8 9 10 11 | /* * tclUnixFile.c -- * * This file contains wrappers around UNIX file handling functions. * These wrappers mask differences between Windows and UNIX. * * Copyright (c) 1995-1998 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | /* * tclUnixFile.c -- * * This file contains wrappers around UNIX file handling functions. * These wrappers mask differences between Windows and UNIX. * * Copyright (c) 1995-1998 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclUnixFile.c,v 1.10 2001/07/31 19:12:07 vincentdarley Exp $ */ #include "tclInt.h" #include "tclPort.h" char * TclpGetCwd _ANSI_ARGS_((Tcl_Interp *interp, Tcl_DString *bufferPtr)); /* *--------------------------------------------------------------------------- * * TclpFindExecutable -- * |
| ︙ | ︙ | |||
172 173 174 175 176 177 178 |
Tcl_DStringFree(&buffer);
return tclNativeExecutableName;
}
/*
*----------------------------------------------------------------------
*
| | < < < | | > | < | | | | < < < | | > | < > > | | > > > | > > > > | | > > > > > > > | 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 |
Tcl_DStringFree(&buffer);
return tclNativeExecutableName;
}
/*
*----------------------------------------------------------------------
*
* TclpMatchInDirectory --
*
* This routine is used by the globbing code to search a
* directory for all files which match a given pattern.
*
* Results:
* The return value is a standard Tcl result indicating whether an
* error occurred in globbing. Errors are left in interp, good
* results are lappended to resultPtr (which must be a valid object)
*
* Side effects:
* None.
*
*---------------------------------------------------------------------- */
int
TclpMatchInDirectory(interp, resultPtr, pathPtr, pattern, types)
Tcl_Interp *interp; /* Interpreter to receive errors. */
Tcl_Obj *resultPtr; /* List object to lappend results. */
Tcl_Obj *pathPtr; /* Contains path to directory to search. */
char *pattern; /* Pattern to match against. */
Tcl_GlobTypeData *types; /* Object containing list of acceptable types.
* May be NULL. In particular the directory
* flag is very important. */
{
char *native, *fname, *dirName;
DIR *d;
Tcl_DString ds;
struct stat statBuf;
int matchHidden;
int result = TCL_OK;
Tcl_DString dsOrig;
char *fileName;
int baseLength;
fileName = Tcl_FSGetTranslatedPath(interp, pathPtr);
if (fileName == NULL) {
return TCL_ERROR;
}
Tcl_DStringInit(&dsOrig);
Tcl_DStringAppend(&dsOrig, fileName, -1);
baseLength = Tcl_DStringLength(&dsOrig);
/*
* Make sure that the directory part of the name really is a
* directory. If the directory name is "", use the name "."
* instead, because some UNIX systems don't treat "" like "."
* automatically. Keep the "" for use in generating file names,
* otherwise "glob foo.c" would return "./foo.c".
*/
if (baseLength == 0) {
dirName = ".";
} else {
dirName = Tcl_DStringValue(&dsOrig);
/* Make sure we have a trailing directory delimiter */
if (dirName[baseLength-1] != '/') {
Tcl_DStringAppend(&dsOrig, "/", 1);
dirName = Tcl_DStringValue(&dsOrig);
baseLength++;
}
}
if ((TclpStat(dirName, &statBuf) != 0) /* INTL: UTF-8. */
|| !S_ISDIR(statBuf.st_mode)) {
Tcl_DStringFree(&dsOrig);
return TCL_OK;
}
/*
* Check to see if the pattern needs to compare with hidden files.
*/
|
| ︙ | ︙ | |||
250 251 252 253 254 255 256 257 258 259 260 261 262 263 |
* Now open the directory for reading and iterate over the contents.
*/
native = Tcl_UtfToExternalDString(NULL, dirName, -1, &ds);
d = opendir(native); /* INTL: Native. */
Tcl_DStringFree(&ds);
if (d == NULL) {
Tcl_ResetResult(interp);
/*
* Strip off a trailing '/' if necessary, before reporting the error.
*/
if (baseLength > 0) {
| > | | | | > < < < < < < < < < < < < < < < < < < < | 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 |
* Now open the directory for reading and iterate over the contents.
*/
native = Tcl_UtfToExternalDString(NULL, dirName, -1, &ds);
d = opendir(native); /* INTL: Native. */
Tcl_DStringFree(&ds);
if (d == NULL) {
char savedChar = '\0';
Tcl_ResetResult(interp);
/*
* Strip off a trailing '/' if necessary, before reporting the error.
*/
if (baseLength > 0) {
savedChar = (Tcl_DStringValue(&dsOrig))[baseLength-1];
if (savedChar == '/') {
(Tcl_DStringValue(&dsOrig))[baseLength-1] = '\0';
}
}
Tcl_AppendResult(interp, "couldn't read directory \"",
Tcl_DStringValue(&dsOrig), "\": ",
Tcl_PosixError(interp), (char *) NULL);
if (baseLength > 0) {
(Tcl_DStringValue(&dsOrig))[baseLength-1] = savedChar;
}
Tcl_DStringFree(&dsOrig);
return TCL_ERROR;
}
while (1) {
char *utf;
struct dirent *entryPtr;
entryPtr = readdir(d); /* INTL: Native. */
if (entryPtr == NULL) {
break;
|
| ︙ | ︙ | |||
324 325 326 327 328 329 330 |
* characters to be processed, then ensure matching files are
* directories before calling TclDoGlob. Otherwise, just add
* the file to the result.
*/
utf = Tcl_ExternalToUtfDString(NULL, entryPtr->d_name, -1, &ds);
if (Tcl_StringMatch(utf, pattern) != 0) {
| > > | | | < < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < | < < < < < < < | < < < > < < < < < < < < < < < < < < < < < < < | 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 |
* characters to be processed, then ensure matching files are
* directories before calling TclDoGlob. Otherwise, just add
* the file to the result.
*/
utf = Tcl_ExternalToUtfDString(NULL, entryPtr->d_name, -1, &ds);
if (Tcl_StringMatch(utf, pattern) != 0) {
int typeOk = 1;
Tcl_DStringSetLength(&dsOrig, baseLength);
Tcl_DStringAppend(&dsOrig, utf, -1);
fname = Tcl_DStringValue(&dsOrig);
if (types != NULL) {
if (types->perm != 0) {
struct stat buf;
if (TclpStat(fname, &buf) != 0) {
panic("stat failed on known file");
}
/*
* readonly means that there are NO write permissions
* (even for user), but execute is OK for anybody
*/
if (
((types->perm & TCL_GLOB_PERM_RONLY) &&
(buf.st_mode & (S_IWOTH|S_IWGRP|S_IWUSR))) ||
((types->perm & TCL_GLOB_PERM_R) &&
(TclpAccess(fname, R_OK) != 0)) ||
((types->perm & TCL_GLOB_PERM_W) &&
(TclpAccess(fname, W_OK) != 0)) ||
((types->perm & TCL_GLOB_PERM_X) &&
(TclpAccess(fname, X_OK) != 0))
) {
typeOk = 0;
}
}
if (typeOk && (types->type != 0)) {
struct stat buf;
/*
* We must match at least one flag to be listed
*/
typeOk = 0;
if (TclpLstat(fname, &buf) >= 0) {
/*
* In order bcdpfls as in 'find -t'
*/
if (
((types->type & TCL_GLOB_TYPE_BLOCK) &&
S_ISBLK(buf.st_mode)) ||
((types->type & TCL_GLOB_TYPE_CHAR) &&
S_ISCHR(buf.st_mode)) ||
((types->type & TCL_GLOB_TYPE_DIR) &&
S_ISDIR(buf.st_mode)) ||
((types->type & TCL_GLOB_TYPE_PIPE) &&
S_ISFIFO(buf.st_mode)) ||
((types->type & TCL_GLOB_TYPE_FILE) &&
S_ISREG(buf.st_mode))
#ifdef S_ISLNK
|| ((types->type & TCL_GLOB_TYPE_LINK) &&
S_ISLNK(buf.st_mode))
#endif
#ifdef S_ISSOCK
|| ((types->type & TCL_GLOB_TYPE_SOCK) &&
S_ISSOCK(buf.st_mode))
#endif
) {
typeOk = 1;
}
} else {
/* Posix error occurred */
}
}
}
if (typeOk) {
Tcl_ListObjAppendElement(interp, resultPtr,
Tcl_NewStringObj(fname, Tcl_DStringLength(&dsOrig)));
}
}
Tcl_DStringFree(&ds);
}
closedir(d);
Tcl_DStringFree(&dsOrig);
return result;
}
/*
*---------------------------------------------------------------------------
*
* TclpGetUserHome --
*
|
| ︙ | ︙ | |||
689 690 691 692 693 694 695 |
native = Tcl_UtfToExternalDString(NULL, path, -1, &ds);
result = stat(native, bufPtr); /* INTL: Native. */
Tcl_DStringFree(&ds);
return result;
}
| | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 |
native = Tcl_UtfToExternalDString(NULL, path, -1, &ds);
result = stat(native, bufPtr); /* INTL: Native. */
Tcl_DStringFree(&ds);
return result;
}
int
TclpObjLstat(pathPtr, buf)
Tcl_Obj *pathPtr;
struct stat *buf;
{
char *path = Tcl_FSGetNativePath(pathPtr);
if (path == NULL) {
return -1;
} else {
return lstat(path, buf);
}
}
int
TclpObjStat(pathPtr, buf)
Tcl_Obj *pathPtr;
struct stat *buf;
{
char *path = Tcl_FSGetNativePath(pathPtr);
if (path == NULL) {
return -1;
} else {
return stat(path, buf);
}
}
Tcl_Obj*
TclpObjGetCwd(interp)
Tcl_Interp *interp;
{
Tcl_DString ds;
if (TclpGetCwd(interp, &ds) != NULL) {
Tcl_Obj *cwdPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds), -1);
Tcl_IncrRefCount(cwdPtr);
Tcl_DStringFree(&ds);
return cwdPtr;
} else {
return NULL;
}
}
int
TclpObjChdir(pathPtr)
Tcl_Obj *pathPtr;
{
char *path = Tcl_FSGetNativePath(pathPtr);
if (path == NULL) {
return -1;
} else {
return chdir(path);
}
}
int
TclpObjAccess(pathPtr, mode)
Tcl_Obj *pathPtr;
int mode;
{
char *path = Tcl_FSGetNativePath(pathPtr);
if (path == NULL) {
return -1;
} else {
return access(path, mode);
}
}
#ifdef S_IFLNK
Tcl_Obj*
TclpObjReadlink(pathPtr)
Tcl_Obj *pathPtr;
{
char link[MAXPATHLEN];
int length;
char *native;
Tcl_Obj* linkPtr;
if (Tcl_FSGetTranslatedPath(NULL, pathPtr) == NULL) {
return NULL;
}
length = readlink(Tcl_FSGetNativePath(pathPtr), link, sizeof(link));
if (length < 0) {
return NULL;
}
/*
* Allocate and copy the name, taking care since the
* name need not be null terminated.
*/
native = (char*)ckalloc((unsigned)(1+length));
strncpy(native, link, (unsigned)length);
native[length] = '\0';
linkPtr = Tcl_FSNewNativePath(pathPtr, native);
Tcl_IncrRefCount(linkPtr);
return linkPtr;
}
#endif
|
Changes to unix/tclUnixInit.c.
1 2 3 4 5 6 7 8 9 | /* * tclUnixInit.c -- * * Contains the Unix-specific interpreter initialization functions. * * Copyright (c) 1995-1997 Sun Microsystems, Inc. * Copyright (c) 1999 by Scriptics Corporation. * All rights reserved. * | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | /* * tclUnixInit.c -- * * Contains the Unix-specific interpreter initialization functions. * * Copyright (c) 1995-1997 Sun Microsystems, Inc. * Copyright (c) 1999 by Scriptics Corporation. * All rights reserved. * * RCS: @(#) $Id: tclUnixInit.c,v 1.23 2001/07/31 19:12:08 vincentdarley Exp $ */ #include "tclInt.h" #include "tclPort.h" #include <locale.h> #if defined(__FreeBSD__) # include <floatingpoint.h> |
| ︙ | ︙ | |||
25 26 27 28 29 30 31 32 33 34 35 36 37 38 | /* * The Init script (common to Windows and Unix platforms) is * defined in tkInitScript.h */ #include "tclInitScript.h" /* * Default directory in which to look for Tcl library scripts. The * symbol is defined by Makefile. */ static char defaultLibraryDir[sizeof(TCL_LIBRARY)+200] = TCL_LIBRARY; | > > > > | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | /* * The Init script (common to Windows and Unix platforms) is * defined in tkInitScript.h */ #include "tclInitScript.h" /* Used to store the encoding used for binary files */ static Tcl_Encoding binaryEncoding = NULL; /* Has the basic library path encoding issue been fixed */ static int libraryPathEncodingFixed = 0; /* * Default directory in which to look for Tcl library scripts. The * symbol is defined by Makefile. */ static char defaultLibraryDir[sizeof(TCL_LIBRARY)+200] = TCL_LIBRARY; |
| ︙ | ︙ | |||
366 367 368 369 370 371 372 | *--------------------------------------------------------------------------- * * TclpSetInitialEncodings -- * * Based on the locale, determine the encoding of the operating * system and the default encoding for newly opened files. * | | > > > | > > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > > > > > | | | | > | < | 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 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 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 |
*---------------------------------------------------------------------------
*
* TclpSetInitialEncodings --
*
* Based on the locale, determine the encoding of the operating
* system and the default encoding for newly opened files.
*
* Called at process initialization time, and part way through
* startup, we verify that the initial encodings were correctly
* setup. Depending on Tcl's environment, there may not have been
* enough information first time through (above).
*
* Results:
* None.
*
* Side effects:
* The Tcl library path is converted from native encoding to UTF-8,
* on the first call, and the encodings may be changed on first or
* second call.
*
*---------------------------------------------------------------------------
*/
void
TclpSetInitialEncodings()
{
if (libraryPathEncodingFixed == 0) {
CONST char *encoding;
int i;
Tcl_Obj *pathPtr;
char *langEnv;
/*
* Determine the current encoding from the LC_* or LANG environment
* variables. We previously used setlocale() to determine the locale,
* but this does not work on some systems (e.g. Linux/i386 RH 5.0).
*/
langEnv = getenv("LC_ALL");
if (langEnv == NULL || langEnv[0] == '\0') {
langEnv = getenv("LC_CTYPE");
}
if (langEnv == NULL || langEnv[0] == '\0') {
langEnv = getenv("LANG");
}
if (langEnv == NULL || langEnv[0] == '\0') {
langEnv = NULL;
}
encoding = NULL;
if (langEnv != NULL) {
for (i = 0; localeTable[i].lang != NULL; i++) {
if (strcmp(localeTable[i].lang, langEnv) == 0) {
encoding = localeTable[i].encoding;
break;
}
}
/*
* There was no mapping in the locale table. If there is an
* encoding subfield, we can try to guess from that.
*/
if (encoding == NULL) {
char *p;
for (p = langEnv; *p != '\0'; p++) {
if (*p == '.') {
p++;
break;
}
}
if (*p != '\0') {
Tcl_DString ds;
Tcl_DStringInit(&ds);
Tcl_DStringAppend(&ds, p, -1);
encoding = Tcl_DStringValue(&ds);
Tcl_UtfToLower(Tcl_DStringValue(&ds));
if (Tcl_SetSystemEncoding(NULL, encoding) == TCL_OK) {
Tcl_DStringFree(&ds);
goto resetPath;
}
Tcl_DStringFree(&ds);
encoding = NULL;
}
}
}
if (encoding == NULL) {
encoding = "iso8859-1";
}
Tcl_SetSystemEncoding(NULL, encoding);
resetPath:
/*
* Initialize the C library's locale subsystem. This is required
* for input methods to work properly on X11. We only do this for
* LC_CTYPE because that's the necessary one, and we don't want to
* affect LC_TIME here. The side effect of setting the default locale
* should be to load any locale specific modules that are needed by X.
* [BUG: 5422 3345 4236 2522 2521].
*/
setlocale(LC_CTYPE, "");
/*
* In case the initial locale is not "C", ensure that the numeric
* processing is done in "C" locale regardless. This is needed because
* Tcl relies on routines like strtod, but should not have locale
* dependent behavior.
*/
setlocale(LC_NUMERIC, "C");
/*
* Until the system encoding was actually set, the library path was
* actually in the native multi-byte encoding, and not really UTF-8
* as advertised. We cheated as follows:
*
* 1. It was safe to allow the Tcl_SetSystemEncoding() call to
* append the ASCII chars that make up the encoding's filename to
* the names (in the native encoding) of directories in the library
* path, since all Unix multi-byte encodings have ASCII in the
* beginning.
*
* 2. To open the encoding file, the native bytes in the file name
* were passed to the OS, without translating from UTF-8 to native,
* because the name was already in the native encoding.
*
* Now that the system encoding was actually successfully set,
* translate all the names in the library path to UTF-8. That way,
* next time we search the library path, we'll translate the names
* from UTF-8 to the system encoding which will be the native
* encoding.
*/
pathPtr = TclGetLibraryPath();
if (pathPtr != NULL) {
int objc;
Tcl_Obj **objv;
objc = 0;
Tcl_ListObjGetElements(NULL, pathPtr, &objc, &objv);
for (i = 0; i < objc; i++) {
int length;
char *string;
Tcl_DString ds;
string = Tcl_GetStringFromObj(objv[i], &length);
Tcl_ExternalToUtfDString(NULL, string, length, &ds);
Tcl_SetStringObj(objv[i], Tcl_DStringValue(&ds),
Tcl_DStringLength(&ds));
Tcl_DStringFree(&ds);
}
}
libraryPathEncodingFixed = 1;
}
/* This is only ever called from the startup thread */
if (binaryEncoding == NULL) {
/*
* Keep the iso8859-1 encoding preloaded. The IO package uses
* it for gets on a binary channel.
*/
binaryEncoding = Tcl_GetEncoding(NULL, "iso8859-1");
}
}
/*
*---------------------------------------------------------------------------
*
* TclpSetVariables --
*
|
| ︙ | ︙ |
Changes to unix/tclUnixPipe.c.
1 2 3 4 5 6 7 8 9 10 11 12 | /* * tclUnixPipe.c -- * * This file implements the UNIX-specific exec pipeline functions, * the "pipe" channel driver, and the "pid" Tcl command. * * Copyright (c) 1991-1994 The Regents of the University of California. * Copyright (c) 1994-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | /* * tclUnixPipe.c -- * * This file implements the UNIX-specific exec pipeline functions, * the "pipe" channel driver, and the "pid" Tcl command. * * Copyright (c) 1991-1994 The Regents of the University of California. * Copyright (c) 1994-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclUnixPipe.c,v 1.13 2001/07/31 19:12:08 vincentdarley Exp $ */ #include "tclInt.h" #include "tclPort.h" /* * The following macros convert between TclFile's and fd's. The conversion |
| ︙ | ︙ | |||
213 214 215 216 217 218 219 220 221 222 223 224 225 226 |
return NULL;
}
Tcl_DStringFree(&dstring);
lseek(fd, (off_t) 0, SEEK_SET);
}
return MakeFile(fd);
}
/*
*----------------------------------------------------------------------
*
* TclpCreatePipe --
*
* Creates a pipe - simply calls the pipe() function.
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 |
return NULL;
}
Tcl_DStringFree(&dstring);
lseek(fd, (off_t) 0, SEEK_SET);
}
return MakeFile(fd);
}
/*
*----------------------------------------------------------------------
*
* TclpTempFileName --
*
* This function returns unique filename.
*
* Results:
* Returns a valid Tcl_Obj* with refCount 0, or NULL on failure.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
Tcl_Obj*
TclpTempFileName()
{
char fileName[L_tmpnam];
if (tmpnam(fileName) == NULL) { /* INTL: Native. */
return NULL;
}
return TclpNativeToNormalized((ClientData) fileName);
}
/*
*----------------------------------------------------------------------
*
* TclpCreatePipe --
*
* Creates a pipe - simply calls the pipe() function.
|
| ︙ | ︙ |
Changes to win/tclWinFCmd.c.
1 2 3 4 5 6 7 8 9 10 11 | /* * tclWinFCmd.c * * This file implements the Windows specific portion of file manipulation * subcommands of the "file" command. * * Copyright (c) 1996-1998 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /* * tclWinFCmd.c * * This file implements the Windows specific portion of file manipulation * subcommands of the "file" command. * * Copyright (c) 1996-1998 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclWinFCmd.c,v 1.9 2001/07/31 19:12:08 vincentdarley Exp $ */ #include "tclWinInt.h" /* * The following constants specify the type of callback when * TraverseWinTree() calls the traverseProc() |
| ︙ | ︙ | |||
98 99 100 101 102 103 104 105 106 107 108 109 110 111 | int type, Tcl_DString *errorPtr); static int TraversalDelete(Tcl_DString *srcPtr, Tcl_DString *dstPtr, int type, Tcl_DString *errorPtr); static int TraverseWinTree(TraversalProc *traverseProc, Tcl_DString *sourcePtr, Tcl_DString *dstPtr, Tcl_DString *errorPtr); /* *--------------------------------------------------------------------------- * * TclpRenameFile, DoRenameFile -- * * Changes the name of an existing file or directory, from src to dst. | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
int type, Tcl_DString *errorPtr);
static int TraversalDelete(Tcl_DString *srcPtr, Tcl_DString *dstPtr,
int type, Tcl_DString *errorPtr);
static int TraverseWinTree(TraversalProc *traverseProc,
Tcl_DString *sourcePtr, Tcl_DString *dstPtr,
Tcl_DString *errorPtr);
int
TclpObjCreateDirectory(pathPtr)
Tcl_Obj *pathPtr;
{
return TclpCreateDirectory(Tcl_FSGetTranslatedPath(NULL, pathPtr));
}
int
TclpObjDeleteFile(pathPtr)
Tcl_Obj *pathPtr;
{
return TclpDeleteFile(Tcl_FSGetTranslatedPath(NULL, pathPtr));
}
int
TclpObjCopyDirectory(srcPathPtr, destPathPtr, errorPtr)
Tcl_Obj *srcPathPtr;
Tcl_Obj *destPathPtr;
Tcl_Obj **errorPtr;
{
Tcl_DString ds;
int ret;
ret = TclpCopyDirectory(Tcl_FSGetTranslatedPath(NULL,srcPathPtr),
Tcl_FSGetTranslatedPath(NULL,destPathPtr), &ds);
if (ret != TCL_OK) {
*errorPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds), -1);
Tcl_DStringFree(&ds);
Tcl_IncrRefCount(*errorPtr);
}
return ret;
}
int
TclpObjCopyFile(srcPathPtr, destPathPtr)
Tcl_Obj *srcPathPtr;
Tcl_Obj *destPathPtr;
{
return TclpCopyFile(Tcl_FSGetTranslatedPath(NULL,srcPathPtr),
Tcl_FSGetTranslatedPath(NULL,destPathPtr));
}
int
TclpObjRemoveDirectory(pathPtr, recursive, errorPtr)
Tcl_Obj *pathPtr;
int recursive;
Tcl_Obj **errorPtr;
{
Tcl_DString ds;
int ret;
ret = TclpRemoveDirectory(Tcl_FSGetTranslatedPath(NULL, pathPtr),recursive, &ds);
if (ret != TCL_OK) {
*errorPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds), -1);
Tcl_DStringFree(&ds);
Tcl_IncrRefCount(*errorPtr);
}
return ret;
}
int
TclpObjRenameFile(srcPathPtr, destPathPtr)
Tcl_Obj *srcPathPtr;
Tcl_Obj *destPathPtr;
{
return TclpRenameFile(Tcl_FSGetTranslatedPath(NULL,srcPathPtr),
Tcl_FSGetTranslatedPath(NULL,destPathPtr));
}
/*
*---------------------------------------------------------------------------
*
* TclpRenameFile, DoRenameFile --
*
* Changes the name of an existing file or directory, from src to dst.
|
| ︙ | ︙ | |||
1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 |
StatError(interp, fileName);
return TCL_ERROR;
}
*attributePtrPtr = Tcl_NewBooleanObj((int) (result & attributeArray[objIndex]));
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
* ConvertFileNameFormat --
*
* Returns a Tcl_Obj containing either the long or short version of the
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 |
StatError(interp, fileName);
return TCL_ERROR;
}
*attributePtrPtr = Tcl_NewBooleanObj((int) (result & attributeArray[objIndex]));
return TCL_OK;
}
/*
*---------------------------------------------------------------------------
*
* TclpNormalizePath --
*
* This function scans through a path specification and replaces
* it, in place, with a normalized version. On windows this
* means using the 'longname'.
*
* Results:
* The new 'nextCheckpoint' value, giving as far as we could
* understand in the path.
*
* Side effects:
* The pathPtr string, which must contain a valid path, is
* possibly modified in place.
*
*---------------------------------------------------------------------------
*/
int
TclpNormalizePath(interp, pathPtr, nextCheckpoint)
Tcl_Interp *interp;
Tcl_DString *pathPtr;
int nextCheckpoint;
{
char *currentPathEndPosition;
char *lastValidPathEnd = NULL;
char *path = Tcl_DStringValue(pathPtr);
currentPathEndPosition = path + nextCheckpoint;
while (1) {
char cur = *currentPathEndPosition;
if (cur == '/' || cur == 0) {
/* Reached directory separator, or end of string */
Tcl_DString ds;
DWORD attr;
char * nativePath;
nativePath = Tcl_WinUtfToTChar(path, currentPathEndPosition - path, &ds);
attr = (*tclWinProcs->getFileAttributesProc)(nativePath);
Tcl_DStringFree(&ds);
if (attr == 0xffffffff) {
/* File doesn't exist */
break;
}
lastValidPathEnd = currentPathEndPosition;
/* File does exist */
if (cur == 0) {
break;
}
}
currentPathEndPosition++;
}
nextCheckpoint = currentPathEndPosition - path;
if (lastValidPathEnd != NULL) {
/*
* The leading end of the path description was acceptable to
* us. We therefore convert it to its long form, and return
* that.
*/
Tcl_Obj* objPtr = NULL;
int endOfString;
int useLength = lastValidPathEnd - path;
if (*lastValidPathEnd == 0) {
endOfString = 1;
} else {
endOfString = 0;
path[useLength] = 0;
}
/*
* If this returns an error, we have a strange situation; the
* file exists, but we can't get its long name. We will have
* to assume the name we have is ok.
*/
if (ConvertFileNameFormat(interp, 0, path, 1, &objPtr) == TCL_OK) {
/* objPtr now has a refCount of 0 */
int len;
(void) Tcl_GetStringFromObj(objPtr,&len);
if (!endOfString) {
/* Be nice and fix the string before we clear it */
path[useLength] = '/';
Tcl_AppendToObj(objPtr, lastValidPathEnd, -1);
}
nextCheckpoint += (len - useLength);
Tcl_DStringSetLength(pathPtr,0);
path = Tcl_GetStringFromObj(objPtr,&len);
Tcl_DStringAppend(pathPtr,path,len);
/* Free up the objPtr */
Tcl_DecrRefCount(objPtr);
} else {
if (!endOfString) {
path[useLength] = '/';
}
}
}
return nextCheckpoint;
}
/*
*----------------------------------------------------------------------
*
* ConvertFileNameFormat --
*
* Returns a Tcl_Obj containing either the long or short version of the
|
| ︙ | ︙ | |||
1445 1446 1447 1448 1449 1450 1451 | } /* *---------------------------------------------------------------------- * * GetWinFileLongName -- * | | | 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 | } /* *---------------------------------------------------------------------- * * GetWinFileLongName -- * * Returns a Tcl_Obj containing the long version of the file * name. * * Results: * Standard Tcl result and a Tcl_Obj in attributePtrPtr. The object * will have ref count 0. If the return value is not TCL_OK, * attributePtrPtr is not touched. * |
| ︙ | ︙ | |||
1658 1659 1660 1661 1662 1663 1664 |
p[2] = '/';
elemPtr = Tcl_NewStringObj(p, -1);
Tcl_ListObjAppendElement(NULL, resultPtr, elemPtr);
}
}
return TCL_OK;
}
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 |
p[2] = '/';
elemPtr = Tcl_NewStringObj(p, -1);
Tcl_ListObjAppendElement(NULL, resultPtr, elemPtr);
}
}
return TCL_OK;
}
/*
*---------------------------------------------------------------------------
*
* TclpObjNormalizePath --
*
* This function scans through a path specification and replaces
* it, in place, with a normalized version. On windows this
* means using the 'longname'.
*
* Results:
* The new 'nextCheckpoint' value, giving as far as we could
* understand in the path.
*
* Side effects:
* The pathPtr string, which must contain a valid path, is
* possibly modified in place.
*
*---------------------------------------------------------------------------
*/
int
TclpObjNormalizePath(interp, pathPtr, nextCheckpoint)
Tcl_Interp *interp;
Tcl_Obj *pathPtr;
int nextCheckpoint;
{
char *currentPathEndPosition;
char *lastValidPathEnd = NULL;
char *path = Tcl_GetString(pathPtr);
currentPathEndPosition = path + nextCheckpoint;
while (1) {
char cur = *currentPathEndPosition;
if (cur == '/' || cur == 0) {
/* Reached directory separator, or end of string */
Tcl_DString ds;
DWORD attr;
char * nativePath;
nativePath = Tcl_WinUtfToTChar(path, currentPathEndPosition - path, &ds);
attr = (*tclWinProcs->getFileAttributesProc)(nativePath);
Tcl_DStringFree(&ds);
if (attr == 0xffffffff) {
/* File doesn't exist */
break;
}
lastValidPathEnd = currentPathEndPosition;
/* File does exist */
if (cur == 0) {
break;
}
}
currentPathEndPosition++;
}
nextCheckpoint = currentPathEndPosition - path;
if (lastValidPathEnd != NULL) {
/*
* The leading end of the path description was acceptable to
* us. We therefore convert it to its long form, and return
* that.
*/
Tcl_Obj* objPtr = NULL;
int endOfString;
int useLength = lastValidPathEnd - path;
if (*lastValidPathEnd == 0) {
endOfString = 1;
} else {
endOfString = 0;
path[useLength] = 0;
}
/*
* If this returns an error, we have a strange situation; the
* file exists, but we can't get its long name. We will have
* to assume the name we have is ok.
*/
if (ConvertFileNameFormat(interp, 0, path, 1, &objPtr) == TCL_OK) {
int len;
(void) Tcl_GetStringFromObj(objPtr,&len);
if (!endOfString) {
/* Be nice and fix the string before we clear it */
path[useLength] = '/';
Tcl_AppendToObj(objPtr, lastValidPathEnd, -1);
}
nextCheckpoint += (len - useLength);
path = Tcl_GetStringFromObj(objPtr,&len);
Tcl_SetStringObj(pathPtr,path, len);
Tcl_DecrRefCount(objPtr);
} else {
if (!endOfString) {
path[useLength] = '/';
}
}
}
return nextCheckpoint;
}
|
Changes to win/tclWinFile.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* * tclWinFile.c -- * * This file contains temporary wrappers around UNIX file handling * functions. These wrappers map the UNIX functions to Win32 HANDLE-style * files, which can be manipulated through the Win32 console redirection * interfaces. * * Copyright (c) 1995-1998 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* * tclWinFile.c -- * * This file contains temporary wrappers around UNIX file handling * functions. These wrappers map the UNIX functions to Win32 HANDLE-style * files, which can be manipulated through the Win32 console redirection * interfaces. * * Copyright (c) 1995-1998 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclWinFile.c,v 1.11 2001/07/31 19:12:08 vincentdarley Exp $ */ #include "tclWinInt.h" #include <sys/stat.h> #include <shlobj.h> #include <lmaccess.h> /* For TclpGetUserHome(). */ |
| ︙ | ︙ | |||
85 86 87 88 89 90 91 |
TclWinNoBackslash(tclNativeExecutableName);
return tclNativeExecutableName;
}
/*
*----------------------------------------------------------------------
*
| | < < < > | | > | | | | | < < < | | > | < | | > > < > | > > > > > > > | | | > > > | 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
TclWinNoBackslash(tclNativeExecutableName);
return tclNativeExecutableName;
}
/*
*----------------------------------------------------------------------
*
* TclpMatchInDirectory --
*
* This routine is used by the globbing code to search a
* directory for all files which match a given pattern.
*
* Results:
*
* The return value is a standard Tcl result indicating whether an
* error occurred in globbing. Errors are left in interp, good
* results are lappended to resultPtr (which must be a valid object)
*
* Side effects:
* None.
*
*---------------------------------------------------------------------- */
int
TclpMatchInDirectory(interp, resultPtr, pathPtr, pattern, types)
Tcl_Interp *interp; /* Interpreter to receive errors. */
Tcl_Obj *resultPtr; /* List object to lappend results. */
Tcl_Obj *pathPtr; /* Contains path to directory to search. */
char *pattern; /* Pattern to match against. */
Tcl_GlobTypeData *types; /* Object containing list of acceptable types.
* May be NULL. In particular the directory
* flag is very important. */
{
char drivePat[] = "?:\\";
const char *message;
char *dir, *root;
int dirLength;
Tcl_DString dirString;
DWORD attr, volFlags;
HANDLE handle;
WIN32_FIND_DATAT data;
BOOL found;
Tcl_DString ds;
Tcl_DString dsOrig;
char *fileName;
TCHAR *nativeName;
int matchSpecialDots;
/*
* Convert the path to normalized form since some interfaces only
* accept backslashes. Also, ensure that the directory ends with a
* separator character.
*/
fileName = Tcl_FSGetTranslatedPath(interp, pathPtr);
if (fileName == NULL) {
return TCL_ERROR;
}
Tcl_DStringInit(&dsOrig);
Tcl_DStringAppend(&dsOrig, fileName, -1);
dirLength = Tcl_DStringLength(&dsOrig);
Tcl_DStringInit(&dirString);
if (dirLength == 0) {
Tcl_DStringAppend(&dirString, ".\\", 2);
} else {
char *p;
Tcl_DStringAppend(&dirString, Tcl_DStringValue(&dsOrig),
Tcl_DStringLength(&dsOrig));
for (p = Tcl_DStringValue(&dirString); *p != '\0'; p++) {
if (*p == '/') {
*p = '\\';
}
}
p--;
/* Make sure we have a trailing directory delimiter */
if ((*p != '\\') && (*p != ':')) {
Tcl_DStringAppend(&dirString, "\\", 1);
Tcl_DStringAppend(&dsOrig, "/", 1);
dirLength++;
}
}
dir = Tcl_DStringValue(&dirString);
/*
* First verify that the specified path is actually a directory.
*/
|
| ︙ | ︙ | |||
216 217 218 219 220 221 222 |
if (found == 0) {
message = "couldn't read volume information for \"";
goto error;
}
/*
| | | | > > > | < | > > > > < < < < < < < < < < < < < < < < < < < < < < < < < < > > > > > > > > > > | < < < < < < | | < < | | | | > > > > > > > | | > > > | > | > > > | > > > | < | | | < < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < < < < < < < < < < | | | | > < < < < < < < < < < < < < < < < < < < | 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 |
if (found == 0) {
message = "couldn't read volume information for \"";
goto error;
}
/*
* Check to see if the pattern should match the special
* . and .. names, referring to the current directory,
* or the directory above. We need a special check for
* this because paths beginning with a dot are not considered
* hidden on Windows, and so otherwise a relative glob like
* 'glob -join * *' will actually return './. ../..' etc.
*/
if ((pattern[0] == '.')
|| ((pattern[0] == '\\') && (pattern[1] == '.'))) {
matchSpecialDots = 1;
} else {
matchSpecialDots = 0;
}
/*
* We need to check all files in the directory, so append a *.*
* to the path.
*/
dir = Tcl_DStringAppend(&dirString, "*.*", 3);
nativeName = Tcl_WinUtfToTChar(dir, -1, &ds);
handle = (*tclWinProcs->findFirstFileProc)(nativeName, &data);
Tcl_DStringFree(&ds);
if (handle == INVALID_HANDLE_VALUE) {
message = "couldn't read directory \"";
goto error;
}
/*
* Now iterate over all of the files in the directory.
*/
for (found = 1; found != 0;
found = (*tclWinProcs->findNextFileProc)(handle, &data)) {
TCHAR *nativeMatchResult;
char *name, *fname;
int typeOk = 1;
if (tclWinProcs->useWide) {
nativeName = (TCHAR *) data.w.cFileName;
} else {
nativeName = (TCHAR *) data.a.cFileName;
}
name = Tcl_WinTCharToUtf(nativeName, -1, &ds);
if (!matchSpecialDots) {
/* If it is exactly '.' or '..' then we ignore it */
if (name[0] == '.') {
if (name[1] == '\0' || (name[1] == '.' && name[2] == '\0')) {
continue;
}
}
}
/*
* Check to see if the file matches the pattern. Note that we
* are ignoring the case sensitivity flag because Windows doesn't honor
* case even if the volume is case sensitive. If the volume also
* doesn't preserve case, then we previously returned the lower case
* form of the name. This didn't seem quite right since there are
* non-case-preserving volumes that actually return mixed case. So now
* we are returning exactly what we get from the system.
*/
nativeMatchResult = NULL;
if (Tcl_StringCaseMatch(name, pattern, 1) != 0) {
nativeMatchResult = nativeName;
}
Tcl_DStringFree(&ds);
if (nativeMatchResult == NULL) {
continue;
}
/*
* If the file matches, then we need to process the remainder of the
* path.
*/
name = Tcl_WinTCharToUtf(nativeMatchResult, -1, &ds);
Tcl_DStringAppend(&dsOrig, name, -1);
Tcl_DStringFree(&ds);
fname = Tcl_DStringValue(&dsOrig);
nativeName = Tcl_WinUtfToTChar(fname, Tcl_DStringLength(&dsOrig), &ds);
/*
* 'attr' represents the attributes of the file, but we only
* want to retrieve this info if it is absolutely necessary
* because it is an expensive call. Unfortunately, to deal
* with hidden files properly, we must always retrieve it.
* There are more modern Win32 APIs available which we should
* look into.
*/
attr = (*tclWinProcs->getFileAttributesProc)(nativeName);
if (types == NULL) {
/* If invisible, don't return the file */
if (attr & FILE_ATTRIBUTE_HIDDEN) {
typeOk = 0;
}
} else {
if (attr & FILE_ATTRIBUTE_HIDDEN) {
/* If invisible */
if ((types->perm == 0) ||
!(types->perm & TCL_GLOB_PERM_HIDDEN)) {
typeOk = 0;
}
} else {
/* Visible */
if (types->perm & TCL_GLOB_PERM_HIDDEN) {
typeOk = 0;
}
}
if (typeOk == 1 && types->perm != 0) {
if (
((types->perm & TCL_GLOB_PERM_RONLY) &&
!(attr & FILE_ATTRIBUTE_READONLY)) ||
((types->perm & TCL_GLOB_PERM_R) &&
(TclpAccess(fname, R_OK) != 0)) ||
((types->perm & TCL_GLOB_PERM_W) &&
(TclpAccess(fname, W_OK) != 0)) ||
((types->perm & TCL_GLOB_PERM_X) &&
(TclpAccess(fname, X_OK) != 0))
) {
typeOk = 0;
}
}
if (typeOk && types->type != 0) {
struct stat buf;
/*
* We must match at least one flag to be listed
*/
typeOk = 0;
if (TclpLstat(fname, &buf) >= 0) {
/*
* In order bcdpfls as in 'find -t'
*/
if (
((types->type & TCL_GLOB_TYPE_BLOCK) &&
S_ISBLK(buf.st_mode)) ||
((types->type & TCL_GLOB_TYPE_CHAR) &&
S_ISCHR(buf.st_mode)) ||
((types->type & TCL_GLOB_TYPE_DIR) &&
S_ISDIR(buf.st_mode)) ||
((types->type & TCL_GLOB_TYPE_PIPE) &&
S_ISFIFO(buf.st_mode)) ||
((types->type & TCL_GLOB_TYPE_FILE) &&
S_ISREG(buf.st_mode))
#ifdef S_ISLNK
|| ((types->type & TCL_GLOB_TYPE_LINK) &&
S_ISLNK(buf.st_mode))
#endif
#ifdef S_ISSOCK
|| ((types->type & TCL_GLOB_TYPE_SOCK) &&
S_ISSOCK(buf.st_mode))
#endif
) {
typeOk = 1;
}
} else {
/* Posix error occurred */
}
}
}
if (typeOk) {
Tcl_ListObjAppendElement(interp, resultPtr,
Tcl_NewStringObj(fname, Tcl_DStringLength(&dsOrig)));
}
/*
* Free ds here to ensure that nativeName is valid above.
*/
Tcl_DStringFree(&ds);
Tcl_DStringSetLength(&dsOrig, dirLength);
}
FindClose(handle);
Tcl_DStringFree(&dirString);
Tcl_DStringFree(&dsOrig);
return TCL_OK;
error:
Tcl_DStringFree(&dirString);
TclWinConvertError(GetLastError());
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, message, Tcl_DStringValue(&dsOrig), "\": ",
Tcl_PosixError(interp), (char *) NULL);
Tcl_DStringFree(&dsOrig);
return TCL_ERROR;
}
/*
*----------------------------------------------------------------------
*
* TclpGetUserHome --
*
* This function takes the passed in user name and finds the
|
| ︙ | ︙ | |||
569 570 571 572 573 574 575 576 577 578 579 580 581 582 |
result = Tcl_DStringValue(bufferPtr);
}
}
}
return result;
}
/*
*---------------------------------------------------------------------------
*
* TclpAccess --
*
* This function replaces the library version of access(), fixing the
| > | 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 |
result = Tcl_DStringValue(bufferPtr);
}
}
}
return result;
}
/*
*---------------------------------------------------------------------------
*
* TclpAccess --
*
* This function replaces the library version of access(), fixing the
|
| ︙ | ︙ | |||
809 810 811 812 813 814 815 |
}
return Tcl_DStringValue(bufferPtr);
}
/*
*----------------------------------------------------------------------
*
| | | | | | | | < < | 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 |
}
return Tcl_DStringValue(bufferPtr);
}
/*
*----------------------------------------------------------------------
*
* TclpObjStat --
*
* This function replaces the library version of stat(), fixing
* the following bugs:
*
* 1. stat("c:") returns an error.
* 2. Borland stat() return time in GMT instead of localtime.
* 3. stat("\\server\mount") would return error.
* 4. Accepts slashes or backslashes.
* 5. st_dev and st_rdev were wrong for UNC paths.
*
* Results:
* See stat documentation.
*
* Side effects:
* See stat documentation.
*
*----------------------------------------------------------------------
*/
int
TclpObjStat(pathPtr, statPtr)
Tcl_Obj *pathPtr; /* Path of file to stat */
struct stat *statPtr; /* Filled with results of stat call. */
{
Tcl_DString ds;
TCHAR *nativePath;
WIN32_FIND_DATAT data;
HANDLE handle;
DWORD attr;
WCHAR nativeFullPath[MAX_PATH];
TCHAR *nativePart;
char *p, *fullPath;
int dev, mode;
/*
* Eliminate file names containing wildcard characters, or subsequent
* call to FindFirstFile() will expand them, matching some other file.
*/
if (strpbrk(Tcl_FSGetTranslatedPath(NULL, pathPtr), "?*") != NULL) {
Tcl_SetErrno(ENOENT);
return -1;
}
nativePath = (TCHAR *) Tcl_FSGetNativePath(pathPtr);
handle = (*tclWinProcs->findFirstFileProc)(nativePath, &data);
if (handle == INVALID_HANDLE_VALUE) {
/*
* FindFirstFile() doesn't work on root directories, so call
* GetFileAttributes() to see if the specified file exists.
*/
attr = (*tclWinProcs->getFileAttributesProc)(nativePath);
if (attr == 0xffffffff) {
Tcl_SetErrno(ENOENT);
return -1;
}
/*
* Make up some fake information for this file. It has the
* correct file attributes and a time of 0.
*/
memset(&data, 0, sizeof(data));
data.a.dwFileAttributes = attr;
} else {
FindClose(handle);
}
(*tclWinProcs->getFullPathNameProc)(nativePath, MAX_PATH, nativeFullPath,
&nativePart);
fullPath = Tcl_WinTCharToUtf((TCHAR *) nativeFullPath, -1, &ds);
dev = -1;
if ((fullPath[0] == '\\') && (fullPath[1] == '\\')) {
char *p;
DWORD dw;
TCHAR *nativeVol;
|
| ︙ | ︙ | |||
928 929 930 931 932 933 934 |
dev = Tcl_UniCharToLower(fullPath[0]) - 'a';
}
Tcl_DStringFree(&ds);
attr = data.a.dwFileAttributes;
mode = (attr & FILE_ATTRIBUTE_DIRECTORY) ? S_IFDIR | S_IEXEC : S_IFREG;
mode |= (attr & FILE_ATTRIBUTE_READONLY) ? S_IREAD : S_IREAD | S_IWRITE;
| | | 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 |
dev = Tcl_UniCharToLower(fullPath[0]) - 'a';
}
Tcl_DStringFree(&ds);
attr = data.a.dwFileAttributes;
mode = (attr & FILE_ATTRIBUTE_DIRECTORY) ? S_IFDIR | S_IEXEC : S_IFREG;
mode |= (attr & FILE_ATTRIBUTE_READONLY) ? S_IREAD : S_IREAD | S_IWRITE;
p = strrchr(Tcl_FSGetTranslatedPath(NULL, pathPtr), '.');
if (p != NULL) {
if ((lstrcmpiA(p, ".exe") == 0)
|| (lstrcmpiA(p, ".com") == 0)
|| (lstrcmpiA(p, ".bat") == 0)
|| (lstrcmpiA(p, ".pif") == 0)) {
mode |= S_IEXEC;
}
|
| ︙ | ︙ | |||
1089 1090 1091 1092 1093 1094 1095 |
Tcl_DStringSetLength(bufferPtr, 0);
Tcl_DStringAppend(bufferPtr, realFileName, -1);
return 1;
}
return 0;
}
#endif
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 |
Tcl_DStringSetLength(bufferPtr, 0);
Tcl_DStringAppend(bufferPtr, realFileName, -1);
return 1;
}
return 0;
}
#endif
Tcl_Obj*
TclpObjGetCwd(interp)
Tcl_Interp *interp;
{
Tcl_DString ds;
if (TclpGetCwd(interp, &ds) != NULL) {
Tcl_Obj *cwdPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds), -1);
Tcl_IncrRefCount(cwdPtr);
Tcl_DStringFree(&ds);
return cwdPtr;
} else {
return NULL;
}
}
int
TclpObjChdir(pathPtr)
Tcl_Obj *pathPtr;
{
int result;
TCHAR *nativePath;
nativePath = (TCHAR *) Tcl_FSGetNativePath(pathPtr);
result = (*tclWinProcs->setCurrentDirectoryProc)(nativePath);
if (result == 0) {
TclWinConvertError(GetLastError());
return -1;
}
return 0;
}
int
TclpObjAccess(pathPtr, mode)
Tcl_Obj *pathPtr;
int mode;
{
TCHAR *nativePath;
DWORD attr;
nativePath = (TCHAR *) Tcl_FSGetNativePath(pathPtr);
attr = (*tclWinProcs->getFileAttributesProc)(nativePath);
if (attr == 0xffffffff) {
/*
* File doesn't exist.
*/
TclWinConvertError(GetLastError());
return -1;
}
if ((mode & W_OK) && (attr & FILE_ATTRIBUTE_READONLY)) {
/*
* File is not writable.
*/
Tcl_SetErrno(EACCES);
return -1;
}
if (mode & X_OK) {
CONST char *p;
if (attr & FILE_ATTRIBUTE_DIRECTORY) {
/*
* Directories are always executable.
*/
return 0;
}
p = strrchr(Tcl_FSGetTranslatedPath(NULL, pathPtr), '.');
if (p != NULL) {
p++;
if ((stricmp(p, "exe") == 0)
|| (stricmp(p, "com") == 0)
|| (stricmp(p, "bat") == 0)) {
/*
* File that ends with .exe, .com, or .bat is executable.
*/
return 0;
}
}
Tcl_SetErrno(EACCES);
return -1;
}
return 0;
}
int
TclpObjLstat(pathPtr, buf)
Tcl_Obj *pathPtr;
struct stat *buf; {
return TclpObjStat(pathPtr,buf);
}
#ifdef S_IFLNK
Tcl_Obj*
TclpObjReadlink(pathPtr)
Tcl_Obj *pathPtr;
{
Tcl_DString ds;
Tcl_Obj* link = NULL;
if (TclpReadlink(Tcl_FSGetTranslatedPath(NULL, pathPtr), &ds) != NULL) {
link = Tcl_NewStringObj(Tcl_DStringValue(&ds), -1);
Tcl_IncrRefCount(link);
Tcl_DStringFree(&ds);
}
return link;
}
#endif
/* Obsolete, only called from test suite */
int
TclpStat(path, statPtr)
CONST char *path; /* Path of file to stat (UTF-8). */
struct stat *statPtr; /* Filled with results of stat call. */
{
int retVal;
Tcl_Obj *pathPtr = Tcl_NewStringObj(path,-1);
Tcl_IncrRefCount(pathPtr);
retVal = TclpObjStat(pathPtr, statPtr);
Tcl_DecrRefCount(pathPtr);
return retVal;
}
|
Changes to win/tclWinInit.c.
1 2 3 4 5 6 7 8 9 | /* * tclWinInit.c -- * * Contains the Windows-specific interpreter initialization functions. * * Copyright (c) 1994-1997 Sun Microsystems, Inc. * Copyright (c) 1998-1999 by Scriptics Corporation. * All rights reserved. * | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | /* * tclWinInit.c -- * * Contains the Windows-specific interpreter initialization functions. * * Copyright (c) 1994-1997 Sun Microsystems, Inc. * Copyright (c) 1998-1999 by Scriptics Corporation. * All rights reserved. * * RCS: @(#) $Id: tclWinInit.c,v 1.27 2001/07/31 19:12:08 vincentdarley Exp $ */ #include "tclWinInt.h" #include <winreg.h> #include <winnt.h> #include <winbase.h> |
| ︙ | ︙ | |||
67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
"Win32s", "Windows 95", "Windows NT"
};
#define NUMPROCESSORS 4
static char* processors[NUMPROCESSORS] = {
"intel", "mips", "alpha", "ppc"
};
/*
* The Init script (common to Windows and Unix platforms) is
* defined in tkInitScript.h
*/
#include "tclInitScript.h"
| > > > > > | 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
"Win32s", "Windows 95", "Windows NT"
};
#define NUMPROCESSORS 4
static char* processors[NUMPROCESSORS] = {
"intel", "mips", "alpha", "ppc"
};
/* Used to store the encoding used for binary files */
static Tcl_Encoding binaryEncoding = NULL;
/* Has the basic library path encoding issue been fixed */
static int libraryPathEncodingFixed = 0;
/*
* The Init script (common to Windows and Unix platforms) is
* defined in tkInitScript.h
*/
#include "tclInitScript.h"
|
| ︙ | ︙ | |||
458 459 460 461 462 463 464 | *--------------------------------------------------------------------------- * * TclpSetInitialEncodings -- * * Based on the locale, determine the encoding of the operating * system and the default encoding for newly opened files. * | | > > > | > > < < > > | < | | | | | | | | | | | | | | | | | | | | | | | | | > > > > > > > > | | | | < | | > | 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 |
*---------------------------------------------------------------------------
*
* TclpSetInitialEncodings --
*
* Based on the locale, determine the encoding of the operating
* system and the default encoding for newly opened files.
*
* Called at process initialization time, and part way through
* startup, we verify that the initial encodings were correctly
* setup. Depending on Tcl's environment, there may not have been
* enough information first time through (above).
*
* Results:
* None.
*
* Side effects:
* The Tcl library path is converted from native encoding to UTF-8,
* on the first call, and the encodings may be changed on first or
* second call.
*
*---------------------------------------------------------------------------
*/
void
TclpSetInitialEncodings()
{
CONST char *encoding;
char buf[4 + TCL_INTEGER_SPACE];
if (libraryPathEncodingFixed == 0) {
int platformId;
platformId = TclWinGetPlatformId();
TclWinSetInterfaces(platformId == VER_PLATFORM_WIN32_NT);
wsprintfA(buf, "cp%d", GetACP());
Tcl_SetSystemEncoding(NULL, buf);
if (platformId != VER_PLATFORM_WIN32_NT) {
Tcl_Obj *pathPtr = TclGetLibraryPath();
if (pathPtr != NULL) {
int i, objc;
Tcl_Obj **objv;
objc = 0;
Tcl_ListObjGetElements(NULL, pathPtr, &objc, &objv);
for (i = 0; i < objc; i++) {
int length;
char *string;
Tcl_DString ds;
string = Tcl_GetStringFromObj(objv[i], &length);
Tcl_ExternalToUtfDString(NULL, string, length, &ds);
Tcl_SetStringObj(objv[i], Tcl_DStringValue(&ds),
Tcl_DStringLength(&ds));
Tcl_DStringFree(&ds);
}
}
}
libraryPathEncodingFixed = 1;
} else {
wsprintfA(buf, "cp%d", GetACP());
Tcl_SetSystemEncoding(NULL, buf);
}
/* This is only ever called from the startup thread */
if (binaryEncoding == NULL) {
/*
* Keep this encoding preloaded. The IO package uses it for
* gets on a binary channel.
*/
encoding = "iso8859-1";
binaryEncoding = Tcl_GetEncoding(NULL, encoding);
}
}
/*
*---------------------------------------------------------------------------
*
* TclpSetVariables --
*
|
| ︙ | ︙ |
Changes to win/tclWinPipe.c.
1 2 3 4 5 6 7 8 9 10 11 | /* * tclWinPipe.c -- * * This file implements the Windows-specific exec pipeline functions, * the "pipe" channel driver, and the "pid" Tcl command. * * Copyright (c) 1996-1997 by Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /* * tclWinPipe.c -- * * This file implements the Windows-specific exec pipeline functions, * the "pipe" channel driver, and the "pid" Tcl command. * * Copyright (c) 1996-1997 by Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tclWinPipe.c,v 1.18 2001/07/31 19:12:08 vincentdarley Exp $ */ #include "tclWinInt.h" #include <fcntl.h> #include <io.h> #include <sys/stat.h> |
| ︙ | ︙ | |||
759 760 761 762 763 764 765 766 767 768 769 770 771 772 |
}
TclWinConvertError(GetLastError());
CloseHandle(handle);
(*tclWinProcs->deleteFileProc)((TCHAR *) name);
return NULL;
}
/*
*----------------------------------------------------------------------
*
* TclpCreatePipe --
*
* Creates an anonymous pipe.
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 |
}
TclWinConvertError(GetLastError());
CloseHandle(handle);
(*tclWinProcs->deleteFileProc)((TCHAR *) name);
return NULL;
}
/*
*----------------------------------------------------------------------
*
* TclpTempFileName --
*
* This function returns a unique filename.
*
* Results:
* Returns a valid Tcl_Obj* with refCount 0, or NULL on failure.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
Tcl_Obj*
TclpTempFileName()
{
WCHAR fileName[MAX_PATH];
if (TempFileName(fileName) == 0) {
return NULL;
}
return TclpNativeToNormalized((ClientData) fileName);
}
/*
*----------------------------------------------------------------------
*
* TclpCreatePipe --
*
* Creates an anonymous pipe.
|
| ︙ | ︙ |