Diff
Not logged in

Differences From Artifact [f02a88faeb]:

To Artifact [add2a39f0e]:


13
14
15
16
17
18
19
20

21
22
23
24
25
26
27
28
29

30
31
32
33
34
35
36
13
14
15
16
17
18
19

20
21
22
23
24
25
26
27
28

29
30
31
32
33
34
35
36







-
+








-
+







 *
 * 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.47 2002/06/10 17:41:52 vincentdarley Exp $
 * RCS: @(#) $Id: tclIOUtil.c,v 1.48 2002/06/12 09:28:58 vincentdarley Exp $
 */

#include "tclInt.h"
#include "tclPort.h"
#ifdef MAC_TCL
#include "tclMacInt.h"
#endif
#ifdef __WIN32__
/* For 'file link' */
/* for tclWinProcs->useWide */
#include "tclWinInt.h"
#endif

/*
 * Prototypes for procedures defined later in this file.
 */

314
315
316
317
318
319
320



321
322
323
324
325
326
327
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330







+
+
+







    int fileRefCount;             /* How many Tcl_Obj's use this
                                   * filesystem. */
    struct FilesystemRecord *nextPtr;  
                                  /* The next filesystem registered
                                   * to Tcl, or NULL if no more. */
} FilesystemRecord;

static FilesystemRecord* GetFilesystemRecord 
	_ANSI_ARGS_((Tcl_Filesystem *fromFilesystem, int *epoch));

/* 
 * 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.
 * 
366
367
368
369
370
371
372
373

374
375
376
377
378
379
380
369
370
371
372
373
374
375

376
377
378
379
380
381
382
383







-
+







Tcl_FSCopyDirectoryProc TclpObjCopyDirectory;	    
Tcl_FSRemoveDirectoryProc TclpObjRemoveDirectory;	    
Tcl_FSUnloadFileProc TclpUnloadFile;	    
Tcl_FSLinkProc TclpObjLink; 
Tcl_FSListVolumesProc TclpObjListVolumes;	    

/* Define the native filesystem dispatch table */
static Tcl_Filesystem nativeFilesystem = {
Tcl_Filesystem nativeFilesystem = {
    "native",
    sizeof(Tcl_Filesystem),
    TCL_FILESYSTEM_VERSION_1,
    &NativePathInFilesystem,
    &NativeDupInternalRep,
    &NativeFreeInternalRep,
    &TclpNativeToNormalized,
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
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







-
+



-
+
+

+

+
-
-
+
+
+


-
-
-
+







 *	New memory may be allocated.
 *
 *---------------------------------------------------------------------------
 */

Tcl_Obj *
Tcl_FSNewNativePath(fromFilesystem, clientData)
    Tcl_Obj* fromFilesystem;
    Tcl_Filesystem* fromFilesystem;
    ClientData clientData;
{
    Tcl_Obj *objPtr;
    FsPath *fsPathPtr, *fsFromPtr;
    FsPath *fsPathPtr;
    FilesystemRecord *fsFromPtr;
    Tcl_FSInternalToNormalizedProc *proc;
    int epoch;
    
    fsFromPtr = GetFilesystemRecord(fromFilesystem, &epoch);
    if (Tcl_FSConvertToPathType(NULL, fromFilesystem) != TCL_OK) {
        return NULL;

    if (fsFromPtr == NULL) {
	return NULL;
    }
    
    fsFromPtr = (FsPath*) fromFilesystem->internalRep.otherValuePtr;

    proc = fsFromPtr->fsRecPtr->fsPtr->internalToNormalizedProc;
    proc = fsFromPtr->fsPtr->internalToNormalizedProc;

    if (proc == NULL) {
        return NULL;
    }
    
    objPtr = (*proc)(clientData);
    if (objPtr == NULL) {
3942
3943
3944
3945
3946
3947
3948
3949

3950
3951
3952

3953
3954
3955
3956
3957
3958
3959
3947
3948
3949
3950
3951
3952
3953

3954
3955
3956

3957
3958
3959
3960
3961
3962
3963
3964







-
+


-
+







    
    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->fsRecPtr = fsFromPtr;
    /* We must increase the refCount for this filesystem. */
    fsPathPtr->fsRecPtr->fileRefCount++;
    fsPathPtr->filesystemEpoch = fsFromPtr->filesystemEpoch;
    fsPathPtr->filesystemEpoch = epoch;

    objPtr->internalRep.otherValuePtr = (VOID *) fsPathPtr;
    objPtr->typePtr = &tclFsPathType;
    return objPtr;
}

static void
4381
4382
4383
4384
4385
4386
4387





4388
4389
4390




4391
4392
4393

4394
4395

4396
4397
4398
4399
4400
4401
4402
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







+
+
+
+
+
-
-
-
+
+
+
+


-
+

-
+








    /* Make sure the normalized path is set */
    normPtr = Tcl_FSGetNormalizedPath(NULL, pathObjPtr);

    str = Tcl_GetStringFromObj(normPtr,&len);
#ifdef __WIN32__
    Tcl_WinUtfToTChar(str, len, &ds);
    if (tclWinProcs->useWide) {
	nativePathPtr = ckalloc((unsigned)(sizeof(WCHAR)+Tcl_DStringLength(&ds)));
	memcpy((VOID*)nativePathPtr, (VOID*)Tcl_DStringValue(&ds), 
	       (size_t) (sizeof(WCHAR)+Tcl_DStringLength(&ds)));
    } else {
    nativePathPtr = ckalloc((unsigned)(2+Tcl_DStringLength(&ds)));
    memcpy((VOID*)nativePathPtr, (VOID*)Tcl_DStringValue(&ds), 
	   (size_t) (2+Tcl_DStringLength(&ds)));
	nativePathPtr = ckalloc((unsigned)(sizeof(char)+Tcl_DStringLength(&ds)));
	memcpy((VOID*)nativePathPtr, (VOID*)Tcl_DStringValue(&ds), 
	       (size_t) (sizeof(char)+Tcl_DStringLength(&ds)));
    }
#else
    Tcl_UtfToExternalDString(NULL, str, len, &ds);
    nativePathPtr = ckalloc((unsigned)(1+Tcl_DStringLength(&ds)));
    nativePathPtr = ckalloc((unsigned)(sizeof(char)+Tcl_DStringLength(&ds)));
    memcpy((VOID*)nativePathPtr, (VOID*)Tcl_DStringValue(&ds), 
	  (size_t) (1+Tcl_DStringLength(&ds)));
	  (size_t) (sizeof(char)+Tcl_DStringLength(&ds)));
#endif
	  
    Tcl_DStringFree(&ds);
    return (ClientData)nativePathPtr;
}

/*
4435
4436
4437
4438
4439
4440
4441

4442
4443
4444







4445
4446
4447
4448
4449
4450
4451
4446
4447
4448
4449
4450
4451
4452
4453



4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467







+
-
-
-
+
+
+
+
+
+
+








#ifdef __WIN32__
    /* 
     * Certain native path representations on Windows have this special
     * prefix to indicate that they are to be treated specially.  For
     * example extremely long paths, or symlinks 
     */
    if (*copy == '\\') {
    if (0 == strncmp(copy,"\\??\\",4)) {
	copy += 4;
	len -= 4;
        if (0 == strncmp(copy,"\\??\\",4)) {
	    copy += 4;
	    len -= 4;
	} else if (0 == strncmp(copy,"\\\\?\\",4)) {
	    copy += 4;
	    len -= 4;
	}
    }
#endif

    objPtr = Tcl_NewStringObj(copy,len);
    Tcl_DStringFree(&ds);
    
    return objPtr;
4771
4772
4773
4774
4775
4776
4777

















4778
4779
4780
4781
4782
4783
4784
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







	fsRecPtr = fsRecPtr->nextPtr;
    }

  done:
    FsReleaseIterator();
    return retVal;
}

/* Simple helper function */
static FilesystemRecord* 
GetFilesystemRecord(fromFilesystem, epoch)
    Tcl_Filesystem *fromFilesystem;
    int *epoch;
{
    FilesystemRecord *fsRecPtr = FsGetIterator();
    while (fsRecPtr != NULL) {
	if (fsRecPtr->fsPtr == fromFilesystem) {
	    *epoch = theFilesystemEpoch;
	    break;
	}
    }
    FsReleaseIterator();
    return fsRecPtr;
}

/*
 *---------------------------------------------------------------------------
 *
 * Tcl_FSEqualPaths --
 *
 *      This function tests whether the two paths given are equal path