~ubuntu-branches/ubuntu/raring/tcl8.5/raring

« back to all changes in this revision

Viewing changes to generic/tclPathObj.c

  • Committer: Bazaar Package Importer
  • Author(s): Sergei Golovan
  • Date: 2009-03-01 10:35:30 UTC
  • mfrom: (8.1.1 sid)
  • Revision ID: james.westby@ubuntu.com-20090301103530-0nvyl18uo9sbu9wh
Tags: 8.5.6-3
Don't remove tclsh alternative in case of package upgrade because the
manually installed alternative is also removed which isn't desirable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
10
10
 * See the file "license.terms" for information on usage and redistribution of
11
11
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
12
12
 *
13
 
 * RCS: @(#) $Id: tclPathObj.c,v 1.66.2.4 2008/06/29 19:08:36 dgp Exp $
 
13
 * RCS: @(#) $Id: tclPathObj.c,v 1.66.2.5 2008/12/04 17:45:02 dgp Exp $
14
14
 */
15
15
 
16
16
#include "tclInt.h"
103
103
 */
104
104
 
105
105
#define TCLPATH_APPENDED 1
 
106
#define TCLPATH_NEEDNORM 4
106
107
 
107
108
/*
108
109
 * Define some macros to give us convenient access to path-object specific
1246
1247
    FsPath *fsPathPtr;
1247
1248
    Tcl_Obj *pathPtr;
1248
1249
    ThreadSpecificData *tsdPtr;
 
1250
    const char *p;
 
1251
    int state = 0, count = 0;
1249
1252
 
1250
1253
    tsdPtr = TCL_TSD_INIT(&tclFsDataKey);
1251
1254
 
1271
1274
    pathPtr->bytes = NULL;
1272
1275
    pathPtr->length = 0;
1273
1276
 
 
1277
    /*
 
1278
     * Look for path components made up of only "."
 
1279
     * This is overly conservative analysis to keep simple.  It may
 
1280
     * mark some things as needing more aggressive normalization
 
1281
     * that don't actually need it.  No harm done.
 
1282
     */
 
1283
    for (p = addStrRep; len > 0; p++, len--) {
 
1284
       switch (state) {
 
1285
       case 0: /* So far only "." since last dirsep or start */
 
1286
           switch (*p) {
 
1287
           case '.':
 
1288
               count++;
 
1289
               break;
 
1290
           case '/':
 
1291
           case '\\':
 
1292
           case ':':
 
1293
               if (count) {
 
1294
                   PATHFLAGS(pathPtr) |= TCLPATH_NEEDNORM;
 
1295
                   len = 0;
 
1296
               }
 
1297
               break;
 
1298
           default:
 
1299
               count = 0;
 
1300
               state = 1;
 
1301
           }
 
1302
       case 1: /* Scanning for next dirsep */
 
1303
           switch (*p) {
 
1304
           case '/':
 
1305
           case '\\':
 
1306
           case ':':
 
1307
               state = 0;
 
1308
               break;
 
1309
           }
 
1310
       }
 
1311
    }
 
1312
    if (len == 0 && count) {
 
1313
       PATHFLAGS(pathPtr) |= TCLPATH_NEEDNORM;
 
1314
    }
 
1315
 
1274
1316
    return pathPtr;
1275
1317
}
1276
1318
 
1756
1798
        }
1757
1799
        Tcl_AppendObjToObj(copy, fsPathPtr->normPathPtr);
1758
1800
 
1759
 
        /*
1760
 
         * Normalize the combined string, but only starting after the end of
1761
 
         * the previously normalized 'dir'. This should be much faster! We use
1762
 
         * 'cwdLen-1' so that we are already pointing at the dir-separator
1763
 
         * that we know about. The normalization code will actually start off
1764
 
         * directly after that separator.
1765
 
         */
1766
 
 
1767
 
        TclFSNormalizeToUniquePath(interp, copy, cwdLen-1,
1768
 
                (fsPathPtr->nativePathPtr == NULL ? &clientData : NULL));
1769
 
 
1770
 
        /*
1771
 
         * Now we need to construct the new path object
1772
 
         */
 
1801
        /* Normalize the combined string. */
 
1802
 
 
1803
        if (PATHFLAGS(pathPtr) & TCLPATH_NEEDNORM) {
 
1804
            /*
 
1805
             * If the "tail" part has components (like /../) that cause
 
1806
             * the combined path to need more complete normalizing,
 
1807
             * call on the more powerful routine to accomplish that so
 
1808
             * we avoid [Bug 2385549] ...
 
1809
             */
 
1810
 
 
1811
            Tcl_Obj *newCopy = TclFSNormalizeAbsolutePath(interp, copy, NULL);
 
1812
            Tcl_DecrRefCount(copy);
 
1813
            copy = newCopy;
 
1814
        } else {
 
1815
            /*
 
1816
             * ... but in most cases where we join a trouble free tail
 
1817
             * to a normalized head, we can more efficiently normalize the
 
1818
             * combined path by passing over only the unnormalized tail
 
1819
             * portion.  When this is sufficient, prior developers claim
 
1820
             * this should be much faster.  We use 'cwdLen-1' so that we are
 
1821
             * already pointing at the dir-separator that we know about.
 
1822
             * The normalization code will actually start off directly
 
1823
             * after that separator.
 
1824
             */
 
1825
 
 
1826
            TclFSNormalizeToUniquePath(interp, copy, cwdLen-1,
 
1827
                    (fsPathPtr->nativePathPtr == NULL ? &clientData : NULL));
 
1828
        }
 
1829
 
 
1830
        /* Now we need to construct the new path object. */
1773
1831
 
1774
1832
        if (pathType == TCL_PATH_RELATIVE) {
1775
1833
            Tcl_Obj *origDir = fsPathPtr->cwdPtr;
1810
1868
            TclDecrRefCount(dir);
1811
1869
        }
1812
1870
        if (clientData != NULL) {
 
1871
            /*
 
1872
             * This may be unnecessary. It appears that the
 
1873
             * TclFSNormalizeToUniquePath call above should have already
 
1874
             * set this up.  Not changing out of fear of the unknown.
 
1875
             */
1813
1876
            fsPathPtr->nativePathPtr = clientData;
1814
1877
        }
1815
1878
        PATHFLAGS(pathPtr) = 0;