intl/icu/source/tools/toolutil/pkg_gencmn.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/intl/icu/source/tools/toolutil/pkg_gencmn.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,571 @@
     1.4 +/******************************************************************************
     1.5 + *   Copyright (C) 2008-2012, International Business Machines
     1.6 + *   Corporation and others.  All Rights Reserved.
     1.7 + *******************************************************************************
     1.8 + */
     1.9 +#include "unicode/utypes.h"
    1.10 +
    1.11 +#include <stdio.h>
    1.12 +#include <stdlib.h>
    1.13 +#include "unicode/utypes.h"
    1.14 +#include "unicode/putil.h"
    1.15 +#include "cmemory.h"
    1.16 +#include "cstring.h"
    1.17 +#include "filestrm.h"
    1.18 +#include "toolutil.h"
    1.19 +#include "unicode/uclean.h"
    1.20 +#include "unewdata.h"
    1.21 +#include "putilimp.h"
    1.22 +#include "pkg_gencmn.h"
    1.23 +
    1.24 +#define STRING_STORE_SIZE 200000
    1.25 +
    1.26 +#define COMMON_DATA_NAME U_ICUDATA_NAME
    1.27 +#define DATA_TYPE "dat"
    1.28 +
    1.29 +/* ICU package data file format (.dat files) ------------------------------- ***
    1.30 +
    1.31 +Description of the data format after the usual ICU data file header
    1.32 +(UDataInfo etc.).
    1.33 +
    1.34 +Format version 1
    1.35 +
    1.36 +A .dat package file contains a simple Table of Contents of item names,
    1.37 +followed by the items themselves:
    1.38 +
    1.39 +1. ToC table
    1.40 +
    1.41 +uint32_t count; - number of items
    1.42 +UDataOffsetTOCEntry entry[count]; - pair of uint32_t values per item:
    1.43 +    uint32_t nameOffset; - offset of the item name
    1.44 +    uint32_t dataOffset; - offset of the item data
    1.45 +both are byte offsets from the beginning of the data
    1.46 +
    1.47 +2. item name strings
    1.48 +
    1.49 +All item names are stored as char * strings in one block between the ToC table
    1.50 +and the data items.
    1.51 +
    1.52 +3. data items
    1.53 +
    1.54 +The data items are stored following the item names block.
    1.55 +Each data item is 16-aligned.
    1.56 +The data items are stored in the sorted order of their names.
    1.57 +
    1.58 +Therefore, the top of the name strings block is the offset of the first item,
    1.59 +the length of the last item is the difference between its offset and
    1.60 +the .dat file length, and the length of all previous items is the difference
    1.61 +between its offset and the next one.
    1.62 +
    1.63 +----------------------------------------------------------------------------- */
    1.64 +
    1.65 +/* UDataInfo cf. udata.h */
    1.66 +static const UDataInfo dataInfo={
    1.67 +    sizeof(UDataInfo),
    1.68 +    0,
    1.69 +
    1.70 +    U_IS_BIG_ENDIAN,
    1.71 +    U_CHARSET_FAMILY,
    1.72 +    sizeof(UChar),
    1.73 +    0,
    1.74 +
    1.75 +    {0x43, 0x6d, 0x6e, 0x44},     /* dataFormat="CmnD" */
    1.76 +    {1, 0, 0, 0},                 /* formatVersion */
    1.77 +    {3, 0, 0, 0}                  /* dataVersion */
    1.78 +};
    1.79 +
    1.80 +static uint32_t maxSize;
    1.81 +
    1.82 +static char stringStore[STRING_STORE_SIZE];
    1.83 +static uint32_t stringTop=0, basenameTotal=0;
    1.84 +
    1.85 +typedef struct {
    1.86 +    char *pathname, *basename;
    1.87 +    uint32_t basenameLength, basenameOffset, fileSize, fileOffset;
    1.88 +} File;
    1.89 +
    1.90 +#define CHUNK_FILE_COUNT 256
    1.91 +static File *files = NULL;
    1.92 +static uint32_t fileCount=0;
    1.93 +static uint32_t fileMax = 0;
    1.94 +
    1.95 +
    1.96 +static char *symPrefix = NULL;
    1.97 +
    1.98 +#define LINE_BUFFER_SIZE 512
    1.99 +/* prototypes --------------------------------------------------------------- */
   1.100 +
   1.101 +static void
   1.102 +addFile(const char *filename, const char *name, const char *source, UBool sourceTOC, UBool verbose);
   1.103 +
   1.104 +static char *
   1.105 +allocString(uint32_t length);
   1.106 +
   1.107 +static int
   1.108 +compareFiles(const void *file1, const void *file2);
   1.109 +
   1.110 +static char *
   1.111 +pathToFullPath(const char *path, const char *source);
   1.112 +
   1.113 +/* map non-tree separator (such as '\') to tree separator ('/') inplace. */
   1.114 +static void
   1.115 +fixDirToTreePath(char *s);
   1.116 +/* -------------------------------------------------------------------------- */
   1.117 +
   1.118 +U_CAPI void U_EXPORT2
   1.119 +createCommonDataFile(const char *destDir, const char *name, const char *entrypointName, const char *type, const char *source, const char *copyRight,
   1.120 +                     const char *dataFile, uint32_t max_size, UBool sourceTOC, UBool verbose, char *gencmnFileName) {
   1.121 +    static char buffer[4096];
   1.122 +    char *line;
   1.123 +    char *linePtr;
   1.124 +    char *s = NULL;
   1.125 +    UErrorCode errorCode=U_ZERO_ERROR;
   1.126 +    uint32_t i, fileOffset, basenameOffset, length, nread;
   1.127 +    FileStream *in, *file;
   1.128 +
   1.129 +    line = (char *)uprv_malloc(sizeof(char) * LINE_BUFFER_SIZE);
   1.130 +    if (line == NULL) {
   1.131 +        fprintf(stderr, "gencmn: unable to allocate memory for line buffer of size %d\n", LINE_BUFFER_SIZE);
   1.132 +        exit(U_MEMORY_ALLOCATION_ERROR);
   1.133 +    }
   1.134 +
   1.135 +    linePtr = line;
   1.136 +
   1.137 +    maxSize = max_size;
   1.138 +
   1.139 +    if (destDir == NULL) {
   1.140 +        destDir = u_getDataDirectory();
   1.141 +    }
   1.142 +    if (name == NULL) {
   1.143 +        name = COMMON_DATA_NAME;
   1.144 +    }
   1.145 +    if (type == NULL) {
   1.146 +        type = DATA_TYPE;
   1.147 +    }
   1.148 +    if (source == NULL) {
   1.149 +        source = ".";
   1.150 +    }
   1.151 +
   1.152 +    if (dataFile == NULL) {
   1.153 +        in = T_FileStream_stdin();
   1.154 +    } else {
   1.155 +        in = T_FileStream_open(dataFile, "r");
   1.156 +        if(in == NULL) {
   1.157 +            fprintf(stderr, "gencmn: unable to open input file %s\n", dataFile);
   1.158 +            exit(U_FILE_ACCESS_ERROR);
   1.159 +        }
   1.160 +    }
   1.161 +
   1.162 +    if (verbose) {
   1.163 +        if(sourceTOC) {
   1.164 +            printf("generating %s_%s.c (table of contents source file)\n", name, type);
   1.165 +        } else {
   1.166 +            printf("generating %s.%s (common data file with table of contents)\n", name, type);
   1.167 +        }
   1.168 +    }
   1.169 +
   1.170 +    /* read the list of files and get their lengths */
   1.171 +    while((s != NULL && *s != 0) || (s=T_FileStream_readLine(in, (line=linePtr),
   1.172 +                                                             LINE_BUFFER_SIZE))!=NULL) {
   1.173 +        /* remove trailing newline characters and parse space separated items */
   1.174 +        if (s != NULL && *s != 0) {
   1.175 +            line=s;
   1.176 +        } else {
   1.177 +            s=line;
   1.178 +        }
   1.179 +        while(*s!=0) {
   1.180 +            if(*s==' ') {
   1.181 +                *s=0;
   1.182 +                ++s;
   1.183 +                break;
   1.184 +            } else if(*s=='\r' || *s=='\n') {
   1.185 +                *s=0;
   1.186 +                break;
   1.187 +            }
   1.188 +            ++s;
   1.189 +        }
   1.190 +
   1.191 +        /* check for comment */
   1.192 +
   1.193 +        if (*line == '#') {
   1.194 +            continue;
   1.195 +        }
   1.196 +
   1.197 +        /* add the file */
   1.198 +#if (U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR)
   1.199 +        {
   1.200 +          char *t;
   1.201 +          while((t = uprv_strchr(line,U_FILE_ALT_SEP_CHAR))) {
   1.202 +            *t = U_FILE_SEP_CHAR;
   1.203 +          }
   1.204 +        }
   1.205 +#endif
   1.206 +        addFile(getLongPathname(line), name, source, sourceTOC, verbose);
   1.207 +    }
   1.208 +
   1.209 +    uprv_free(linePtr);
   1.210 +
   1.211 +    if(in!=T_FileStream_stdin()) {
   1.212 +        T_FileStream_close(in);
   1.213 +    }
   1.214 +
   1.215 +    if(fileCount==0) {
   1.216 +        fprintf(stderr, "gencmn: no files listed in %s\n", dataFile == NULL ? "<stdin>" : dataFile);
   1.217 +        return;
   1.218 +    }
   1.219 +
   1.220 +    /* sort the files by basename */
   1.221 +    qsort(files, fileCount, sizeof(File), compareFiles);
   1.222 +
   1.223 +    if(!sourceTOC) {
   1.224 +        UNewDataMemory *out;
   1.225 +
   1.226 +        /* determine the offsets of all basenames and files in this common one */
   1.227 +        basenameOffset=4+8*fileCount;
   1.228 +        fileOffset=(basenameOffset+(basenameTotal+15))&~0xf;
   1.229 +        for(i=0; i<fileCount; ++i) {
   1.230 +            files[i].fileOffset=fileOffset;
   1.231 +            fileOffset+=(files[i].fileSize+15)&~0xf;
   1.232 +            files[i].basenameOffset=basenameOffset;
   1.233 +            basenameOffset+=files[i].basenameLength;
   1.234 +        }
   1.235 +
   1.236 +        /* create the output file */
   1.237 +        out=udata_create(destDir, type, name,
   1.238 +                         &dataInfo,
   1.239 +                         copyRight == NULL ? U_COPYRIGHT_STRING : copyRight,
   1.240 +                         &errorCode);
   1.241 +        if(U_FAILURE(errorCode)) {
   1.242 +            fprintf(stderr, "gencmn: udata_create(-d %s -n %s -t %s) failed - %s\n",
   1.243 +                destDir, name, type,
   1.244 +                u_errorName(errorCode));
   1.245 +            exit(errorCode);
   1.246 +        }
   1.247 +
   1.248 +        /* write the table of contents */
   1.249 +        udata_write32(out, fileCount);
   1.250 +        for(i=0; i<fileCount; ++i) {
   1.251 +            udata_write32(out, files[i].basenameOffset);
   1.252 +            udata_write32(out, files[i].fileOffset);
   1.253 +        }
   1.254 +
   1.255 +        /* write the basenames */
   1.256 +        for(i=0; i<fileCount; ++i) {
   1.257 +            udata_writeString(out, files[i].basename, files[i].basenameLength);
   1.258 +        }
   1.259 +        length=4+8*fileCount+basenameTotal;
   1.260 +
   1.261 +        /* copy the files */
   1.262 +        for(i=0; i<fileCount; ++i) {
   1.263 +            /* pad to 16-align the next file */
   1.264 +            length&=0xf;
   1.265 +            if(length!=0) {
   1.266 +                udata_writePadding(out, 16-length);
   1.267 +            }
   1.268 +
   1.269 +            if (verbose) {
   1.270 +                printf("adding %s (%ld byte%s)\n", files[i].pathname, (long)files[i].fileSize, files[i].fileSize == 1 ? "" : "s");
   1.271 +            }
   1.272 +
   1.273 +            /* copy the next file */
   1.274 +            file=T_FileStream_open(files[i].pathname, "rb");
   1.275 +            if(file==NULL) {
   1.276 +                fprintf(stderr, "gencmn: unable to open listed file %s\n", files[i].pathname);
   1.277 +                exit(U_FILE_ACCESS_ERROR);
   1.278 +            }
   1.279 +            for(nread = 0;;) {
   1.280 +                length=T_FileStream_read(file, buffer, sizeof(buffer));
   1.281 +                if(length <= 0) {
   1.282 +                    break;
   1.283 +                }
   1.284 +                nread += length;
   1.285 +                udata_writeBlock(out, buffer, length);
   1.286 +            }
   1.287 +            T_FileStream_close(file);
   1.288 +            length=files[i].fileSize;
   1.289 +
   1.290 +            if (nread != files[i].fileSize) {
   1.291 +              fprintf(stderr, "gencmn: unable to read %s properly (got %ld/%ld byte%s)\n", files[i].pathname,  (long)nread, (long)files[i].fileSize, files[i].fileSize == 1 ? "" : "s");
   1.292 +                exit(U_FILE_ACCESS_ERROR);
   1.293 +            }
   1.294 +        }
   1.295 +
   1.296 +        /* pad to 16-align the last file (cleaner, avoids growing .dat files in icuswap) */
   1.297 +        length&=0xf;
   1.298 +        if(length!=0) {
   1.299 +            udata_writePadding(out, 16-length);
   1.300 +        }
   1.301 +
   1.302 +        /* finish */
   1.303 +        udata_finish(out, &errorCode);
   1.304 +        if(U_FAILURE(errorCode)) {
   1.305 +            fprintf(stderr, "gencmn: udata_finish() failed - %s\n", u_errorName(errorCode));
   1.306 +            exit(errorCode);
   1.307 +        }
   1.308 +    } else {
   1.309 +        /* write a .c source file with the table of contents */
   1.310 +        char *filename;
   1.311 +        FileStream *out;
   1.312 +
   1.313 +        /* create the output filename */
   1.314 +        filename=s=buffer;
   1.315 +        uprv_strcpy(filename, destDir);
   1.316 +        s=filename+uprv_strlen(filename);
   1.317 +        if(s>filename && *(s-1)!=U_FILE_SEP_CHAR) {
   1.318 +            *s++=U_FILE_SEP_CHAR;
   1.319 +        }
   1.320 +        uprv_strcpy(s, name);
   1.321 +        if(*(type)!=0) {
   1.322 +            s+=uprv_strlen(s);
   1.323 +            *s++='_';
   1.324 +            uprv_strcpy(s, type);
   1.325 +        }
   1.326 +        s+=uprv_strlen(s);
   1.327 +        uprv_strcpy(s, ".c");
   1.328 +
   1.329 +        /* open the output file */
   1.330 +        out=T_FileStream_open(filename, "w");
   1.331 +        if (gencmnFileName != NULL) {
   1.332 +            uprv_strcpy(gencmnFileName, filename);
   1.333 +        }
   1.334 +        if(out==NULL) {
   1.335 +            fprintf(stderr, "gencmn: unable to open .c output file %s\n", filename);
   1.336 +            exit(U_FILE_ACCESS_ERROR);
   1.337 +        }
   1.338 +
   1.339 +        /* write the source file */
   1.340 +        sprintf(buffer,
   1.341 +            "/*\n"
   1.342 +            " * ICU common data table of contents for %s.%s\n"
   1.343 +            " * Automatically generated by icu/source/tools/gencmn/gencmn .\n"
   1.344 +            " */\n\n"
   1.345 +            "#include \"unicode/utypes.h\"\n"
   1.346 +            "#include \"unicode/udata.h\"\n"
   1.347 +            "\n"
   1.348 +            "/* external symbol declarations for data (%d files) */\n",
   1.349 +                name, type, fileCount);
   1.350 +        T_FileStream_writeLine(out, buffer);
   1.351 +
   1.352 +        sprintf(buffer, "extern const char\n    %s%s[]", symPrefix?symPrefix:"", files[0].pathname);
   1.353 +        T_FileStream_writeLine(out, buffer);
   1.354 +        for(i=1; i<fileCount; ++i) {
   1.355 +            sprintf(buffer, ",\n    %s%s[]", symPrefix?symPrefix:"", files[i].pathname);
   1.356 +            T_FileStream_writeLine(out, buffer);
   1.357 +        }
   1.358 +        T_FileStream_writeLine(out, ";\n\n");
   1.359 +
   1.360 +        sprintf(
   1.361 +            buffer,
   1.362 +            "U_EXPORT struct {\n"
   1.363 +            "    uint16_t headerSize;\n"
   1.364 +            "    uint8_t magic1, magic2;\n"
   1.365 +            "    UDataInfo info;\n"
   1.366 +            "    char padding[%lu];\n"
   1.367 +            "    uint32_t count, reserved;\n"
   1.368 +            "    struct {\n"
   1.369 +            "        const char *name;\n"
   1.370 +            "        const void *data;\n"
   1.371 +            "    } toc[%lu];\n"
   1.372 +            "} U_EXPORT2 %s_dat = {\n"
   1.373 +            "    32, 0xda, 0x27, {\n"
   1.374 +            "        %lu, 0,\n"
   1.375 +            "        %u, %u, %u, 0,\n"
   1.376 +            "        {0x54, 0x6f, 0x43, 0x50},\n"
   1.377 +            "        {1, 0, 0, 0},\n"
   1.378 +            "        {0, 0, 0, 0}\n"
   1.379 +            "    },\n"
   1.380 +            "    \"\", %lu, 0, {\n",
   1.381 +            (unsigned long)32-4-sizeof(UDataInfo),
   1.382 +            (unsigned long)fileCount,
   1.383 +            entrypointName,
   1.384 +            (unsigned long)sizeof(UDataInfo),
   1.385 +            U_IS_BIG_ENDIAN,
   1.386 +            U_CHARSET_FAMILY,
   1.387 +            U_SIZEOF_UCHAR,
   1.388 +            (unsigned long)fileCount
   1.389 +        );
   1.390 +        T_FileStream_writeLine(out, buffer);
   1.391 +
   1.392 +        sprintf(buffer, "        { \"%s\", %s%s }", files[0].basename, symPrefix?symPrefix:"", files[0].pathname);
   1.393 +        T_FileStream_writeLine(out, buffer);
   1.394 +        for(i=1; i<fileCount; ++i) {
   1.395 +            sprintf(buffer, ",\n        { \"%s\", %s%s }", files[i].basename, symPrefix?symPrefix:"", files[i].pathname);
   1.396 +            T_FileStream_writeLine(out, buffer);
   1.397 +        }
   1.398 +
   1.399 +        T_FileStream_writeLine(out, "\n    }\n};\n");
   1.400 +        T_FileStream_close(out);
   1.401 +
   1.402 +        uprv_free(symPrefix);
   1.403 +    }
   1.404 +}
   1.405 +
   1.406 +static void
   1.407 +addFile(const char *filename, const char *name, const char *source, UBool sourceTOC, UBool verbose) {
   1.408 +    char *s;
   1.409 +    uint32_t length;
   1.410 +    char *fullPath = NULL;
   1.411 +
   1.412 +    if(fileCount==fileMax) {
   1.413 +      fileMax += CHUNK_FILE_COUNT;
   1.414 +      files = uprv_realloc(files, fileMax*sizeof(files[0])); /* note: never freed. */
   1.415 +      if(files==NULL) {
   1.416 +        fprintf(stderr, "pkgdata/gencmn: Could not allocate %u bytes for %d files\n", (unsigned int)(fileMax*sizeof(files[0])), fileCount);
   1.417 +        exit(U_MEMORY_ALLOCATION_ERROR);
   1.418 +      }
   1.419 +    }
   1.420 +
   1.421 +    if(!sourceTOC) {
   1.422 +        FileStream *file;
   1.423 +
   1.424 +        if(uprv_pathIsAbsolute(filename)) {
   1.425 +            fprintf(stderr, "gencmn: Error: absolute path encountered. Old style paths are not supported. Use relative paths such as 'fur.res' or 'translit%cfur.res'.\n\tBad path: '%s'\n", U_FILE_SEP_CHAR, filename);
   1.426 +            exit(U_ILLEGAL_ARGUMENT_ERROR);
   1.427 +        }
   1.428 +        fullPath = pathToFullPath(filename, source);
   1.429 +        /* store the pathname */
   1.430 +        length = (uint32_t)(uprv_strlen(filename) + 1 + uprv_strlen(name) + 1);
   1.431 +        s=allocString(length);
   1.432 +        uprv_strcpy(s, name);
   1.433 +        uprv_strcat(s, U_TREE_ENTRY_SEP_STRING);
   1.434 +        uprv_strcat(s, filename);
   1.435 +
   1.436 +        /* get the basename */
   1.437 +        fixDirToTreePath(s);
   1.438 +        files[fileCount].basename=s;
   1.439 +        files[fileCount].basenameLength=length;
   1.440 +
   1.441 +        files[fileCount].pathname=fullPath;
   1.442 +
   1.443 +        basenameTotal+=length;
   1.444 +
   1.445 +        /* try to open the file */
   1.446 +        file=T_FileStream_open(fullPath, "rb");
   1.447 +        if(file==NULL) {
   1.448 +            fprintf(stderr, "gencmn: unable to open listed file %s\n", fullPath);
   1.449 +            exit(U_FILE_ACCESS_ERROR);
   1.450 +        }
   1.451 +
   1.452 +        /* get the file length */
   1.453 +        length=T_FileStream_size(file);
   1.454 +        if(T_FileStream_error(file) || length<=20) {
   1.455 +            fprintf(stderr, "gencmn: unable to get length of listed file %s\n", fullPath);
   1.456 +            exit(U_FILE_ACCESS_ERROR);
   1.457 +        }
   1.458 +
   1.459 +        T_FileStream_close(file);
   1.460 +
   1.461 +        /* do not add files that are longer than maxSize */
   1.462 +        if(maxSize && length>maxSize) {
   1.463 +            if (verbose) {
   1.464 +                printf("%s ignored (size %ld > %ld)\n", fullPath, (long)length, (long)maxSize);
   1.465 +            }
   1.466 +            return;
   1.467 +        }
   1.468 +        files[fileCount].fileSize=length;
   1.469 +    } else {
   1.470 +        char *t;
   1.471 +        /* get and store the basename */
   1.472 +        /* need to include the package name */
   1.473 +        length = (uint32_t)(uprv_strlen(filename) + 1 + uprv_strlen(name) + 1);
   1.474 +        s=allocString(length);
   1.475 +        uprv_strcpy(s, name);
   1.476 +        uprv_strcat(s, U_TREE_ENTRY_SEP_STRING);
   1.477 +        uprv_strcat(s, filename);
   1.478 +        fixDirToTreePath(s);
   1.479 +        files[fileCount].basename=s;
   1.480 +        /* turn the basename into an entry point name and store in the pathname field */
   1.481 +        t=files[fileCount].pathname=allocString(length);
   1.482 +        while(--length>0) {
   1.483 +            if(*s=='.' || *s=='-' || *s=='/') {
   1.484 +                *t='_';
   1.485 +            } else {
   1.486 +                *t=*s;
   1.487 +            }
   1.488 +            ++s;
   1.489 +            ++t;
   1.490 +        }
   1.491 +        *t=0;
   1.492 +    }
   1.493 +    ++fileCount;
   1.494 +}
   1.495 +
   1.496 +static char *
   1.497 +allocString(uint32_t length) {
   1.498 +    uint32_t top=stringTop+length;
   1.499 +    char *p;
   1.500 +
   1.501 +    if(top>STRING_STORE_SIZE) {
   1.502 +        fprintf(stderr, "gencmn: out of memory\n");
   1.503 +        exit(U_MEMORY_ALLOCATION_ERROR);
   1.504 +    }
   1.505 +    p=stringStore+stringTop;
   1.506 +    stringTop=top;
   1.507 +    return p;
   1.508 +}
   1.509 +
   1.510 +static char *
   1.511 +pathToFullPath(const char *path, const char *source) {
   1.512 +    int32_t length;
   1.513 +    int32_t newLength;
   1.514 +    char *fullPath;
   1.515 +    int32_t n;
   1.516 +
   1.517 +    length = (uint32_t)(uprv_strlen(path) + 1);
   1.518 +    newLength = (length + 1 + (int32_t)uprv_strlen(source));
   1.519 +    fullPath = uprv_malloc(newLength);
   1.520 +    if(source != NULL) {
   1.521 +        uprv_strcpy(fullPath, source);
   1.522 +        uprv_strcat(fullPath, U_FILE_SEP_STRING);
   1.523 +    } else {
   1.524 +        fullPath[0] = 0;
   1.525 +    }
   1.526 +    n = (int32_t)uprv_strlen(fullPath);
   1.527 +    fullPath[n] = 0;       /* Suppress compiler warning for unused variable n    */
   1.528 +                           /*  when conditional code below is not compiled.      */
   1.529 +    uprv_strcat(fullPath, path);
   1.530 +
   1.531 +#if (U_FILE_ALT_SEP_CHAR != U_TREE_ENTRY_SEP_CHAR)
   1.532 +#if (U_FILE_ALT_SEP_CHAR != U_FILE_SEP_CHAR)
   1.533 +    /* replace tree separator (such as '/') with file sep char (such as ':' or '\\') */
   1.534 +    for(;fullPath[n];n++) {
   1.535 +        if(fullPath[n] == U_FILE_ALT_SEP_CHAR) {
   1.536 +            fullPath[n] = U_FILE_SEP_CHAR;
   1.537 +        }
   1.538 +    }
   1.539 +#endif
   1.540 +#endif
   1.541 +#if (U_FILE_SEP_CHAR != U_TREE_ENTRY_SEP_CHAR)
   1.542 +    /* replace tree separator (such as '/') with file sep char (such as ':' or '\\') */
   1.543 +    for(;fullPath[n];n++) {
   1.544 +        if(fullPath[n] == U_TREE_ENTRY_SEP_CHAR) {
   1.545 +            fullPath[n] = U_FILE_SEP_CHAR;
   1.546 +        }
   1.547 +    }
   1.548 +#endif
   1.549 +    return fullPath;
   1.550 +}
   1.551 +
   1.552 +static int
   1.553 +compareFiles(const void *file1, const void *file2) {
   1.554 +    /* sort by basename */
   1.555 +    return uprv_strcmp(((File *)file1)->basename, ((File *)file2)->basename);
   1.556 +}
   1.557 +
   1.558 +static void
   1.559 +fixDirToTreePath(char *s)
   1.560 +{
   1.561 +#if (U_FILE_SEP_CHAR != U_TREE_ENTRY_SEP_CHAR) || ((U_FILE_ALT_SEP_CHAR != U_FILE_SEP_CHAR) && (U_FILE_ALT_SEP_CHAR != U_TREE_ENTRY_SEP_CHAR))
   1.562 +    char *t;
   1.563 +#endif
   1.564 +#if (U_FILE_SEP_CHAR != U_TREE_ENTRY_SEP_CHAR)
   1.565 +    for(t=s;t=uprv_strchr(t,U_FILE_SEP_CHAR);) {
   1.566 +        *t = U_TREE_ENTRY_SEP_CHAR;
   1.567 +    }
   1.568 +#endif
   1.569 +#if (U_FILE_ALT_SEP_CHAR != U_FILE_SEP_CHAR) && (U_FILE_ALT_SEP_CHAR != U_TREE_ENTRY_SEP_CHAR)
   1.570 +    for(t=s;t=uprv_strchr(t,U_FILE_ALT_SEP_CHAR);) {
   1.571 +        *t = U_TREE_ENTRY_SEP_CHAR;
   1.572 +    }
   1.573 +#endif
   1.574 +}

mercurial