1f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/******************************************************************************
2f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *   Copyright (C) 2008-2010, International Business Machines
3f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *   Corporation and others.  All Rights Reserved.
4f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *******************************************************************************
5f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
6f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/utypes.h"
7f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
8f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <stdio.h>
9f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <stdlib.h>
10f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/utypes.h"
11f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/putil.h"
12f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "cmemory.h"
13f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "cstring.h"
14f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "filestrm.h"
15f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "toolutil.h"
16f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/uclean.h"
17f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unewdata.h"
18f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "putilimp.h"
19f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "pkg_gencmn.h"
20f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
21f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define STRING_STORE_SIZE 100000
22f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
23f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define COMMON_DATA_NAME U_ICUDATA_NAME
24f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define DATA_TYPE "dat"
25f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
26f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* ICU package data file format (.dat files) ------------------------------- ***
27f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
28f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)Description of the data format after the usual ICU data file header
29f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)(UDataInfo etc.).
30f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
31f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)Format version 1
32f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
33f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)A .dat package file contains a simple Table of Contents of item names,
34f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)followed by the items themselves:
35f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
36f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)1. ToC table
37f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
38f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)uint32_t count; - number of items
39f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UDataOffsetTOCEntry entry[count]; - pair of uint32_t values per item:
40f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uint32_t nameOffset; - offset of the item name
41f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uint32_t dataOffset; - offset of the item data
42f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)both are byte offsets from the beginning of the data
43f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
44f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)2. item name strings
45f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
46f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)All item names are stored as char * strings in one block between the ToC table
47f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)and the data items.
48f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
49f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)3. data items
50f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
51f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)The data items are stored following the item names block.
52f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)Each data item is 16-aligned.
53f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)The data items are stored in the sorted order of their names.
54f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
55f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)Therefore, the top of the name strings block is the offset of the first item,
56f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)the length of the last item is the difference between its offset and
57f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)the .dat file length, and the length of all previous items is the difference
58f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)between its offset and the next one.
59f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
60f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)----------------------------------------------------------------------------- */
61f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
62f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* UDataInfo cf. udata.h */
63f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const UDataInfo dataInfo={
64f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    sizeof(UDataInfo),
65f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    0,
66f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
67f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    U_IS_BIG_ENDIAN,
68f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    U_CHARSET_FAMILY,
69f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    sizeof(UChar),
70f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    0,
71f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
72f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {0x43, 0x6d, 0x6e, 0x44},     /* dataFormat="CmnD" */
73f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {1, 0, 0, 0},                 /* formatVersion */
74f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {3, 0, 0, 0}                  /* dataVersion */
75f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)};
76f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
77f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static uint32_t maxSize;
78f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
79f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static char stringStore[STRING_STORE_SIZE];
80f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static uint32_t stringTop=0, basenameTotal=0;
81f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
82f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)typedef struct {
83f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    char *pathname, *basename;
84f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uint32_t basenameLength, basenameOffset, fileSize, fileOffset;
85f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} File;
86f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
87f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define CHUNK_FILE_COUNT 256
88f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static File *files = NULL;
89f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static uint32_t fileCount=0;
90f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static uint32_t fileMax = 0;
91f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
92f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
93f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static char *symPrefix = NULL;
94f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
95f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* prototypes --------------------------------------------------------------- */
96f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
97f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void
98f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)addFile(const char *filename, const char *name, const char *source, UBool sourceTOC, UBool verbose);
99f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static char *
101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)allocString(uint32_t length);
102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int
104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)compareFiles(const void *file1, const void *file2);
105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static char *
107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)pathToFullPath(const char *path, const char *source);
108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* map non-tree separator (such as '\') to tree separator ('/') inplace. */
110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void
111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)fixDirToTreePath(char *s);
112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* -------------------------------------------------------------------------- */
113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI void U_EXPORT2
115f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)createCommonDataFile(const char *destDir, const char *name, const char *entrypointName, const char *type, const char *source, const char *copyRight,
116f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                     const char *dataFile, uint32_t max_size, UBool sourceTOC, UBool verbose, char *gencmnFileName) {
117f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    static char buffer[4096];
118f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    char line[512];
119f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    char *s;
120f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UErrorCode errorCode=U_ZERO_ERROR;
121f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uint32_t i, fileOffset, basenameOffset, length, nread;
122f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    FileStream *in, *file;
123f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
124f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    maxSize = max_size;
125f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
126f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (destDir == NULL) {
127f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        destDir = u_getDataDirectory();
128f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
129f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (name == NULL) {
130f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        name = COMMON_DATA_NAME;
131f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
132f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (type == NULL) {
133f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        type = DATA_TYPE;
134f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
135f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (source == NULL) {
136f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        source = ".";
137f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
138f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
139f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (dataFile == NULL) {
140f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        in = T_FileStream_stdin();
141f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    } else {
142f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        in = T_FileStream_open(dataFile, "r");
143f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(in == NULL) {
144f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            fprintf(stderr, "gencmn: unable to open input file %s\n", dataFile);
145f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            exit(U_FILE_ACCESS_ERROR);
146f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
147f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
148f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
149f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (verbose) {
150f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(sourceTOC) {
151f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            printf("generating %s_%s.c (table of contents source file)\n", name, type);
152f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        } else {
153f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            printf("generating %s.%s (common data file with table of contents)\n", name, type);
154f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
155f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
156f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
157f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* read the list of files and get their lengths */
158f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    while(T_FileStream_readLine(in, line, sizeof(line))!=NULL) {
159f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* remove trailing newline characters */
160f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        s=line;
161f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        while(*s!=0) {
162f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if(*s=='\r' || *s=='\n') {
163f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                *s=0;
164f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                break;
165f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
166f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            ++s;
167f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
168f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
169f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* check for comment */
170f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
171f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (*line == '#') {
172f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            continue;
173f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
174f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
175f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* add the file */
176f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if (U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR)
177f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
178f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          char *t;
179f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          while((t = uprv_strchr(line,U_FILE_ALT_SEP_CHAR))) {
180f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            *t = U_FILE_SEP_CHAR;
181f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          }
182f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
183f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
184f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        addFile(getLongPathname(line), name, source, sourceTOC, verbose);
185f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
186f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
187f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(in!=T_FileStream_stdin()) {
188f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        T_FileStream_close(in);
189f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
190f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
191f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(fileCount==0) {
192f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fprintf(stderr, "gencmn: no files listed in %s\n", dataFile == NULL ? "<stdin>" : dataFile);
193f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
194f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
195f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
196f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* sort the files by basename */
197f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    qsort(files, fileCount, sizeof(File), compareFiles);
198f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
199f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(!sourceTOC) {
200f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        UNewDataMemory *out;
201f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
202f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* determine the offsets of all basenames and files in this common one */
203f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        basenameOffset=4+8*fileCount;
204f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fileOffset=(basenameOffset+(basenameTotal+15))&~0xf;
205f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        for(i=0; i<fileCount; ++i) {
206f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            files[i].fileOffset=fileOffset;
207f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            fileOffset+=(files[i].fileSize+15)&~0xf;
208f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            files[i].basenameOffset=basenameOffset;
209f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            basenameOffset+=files[i].basenameLength;
210f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
211f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
212f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* create the output file */
213f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        out=udata_create(destDir, type, name,
214f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                         &dataInfo,
215f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                         copyRight == NULL ? U_COPYRIGHT_STRING : copyRight,
216f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                         &errorCode);
217f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(U_FAILURE(errorCode)) {
218f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            fprintf(stderr, "gencmn: udata_create(-d %s -n %s -t %s) failed - %s\n",
219f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                destDir, name, type,
220f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                u_errorName(errorCode));
221f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            exit(errorCode);
222f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
223f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
224f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* write the table of contents */
225f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        udata_write32(out, fileCount);
226f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        for(i=0; i<fileCount; ++i) {
227f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            udata_write32(out, files[i].basenameOffset);
228f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            udata_write32(out, files[i].fileOffset);
229f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
230f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
231f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* write the basenames */
232f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        for(i=0; i<fileCount; ++i) {
233f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            udata_writeString(out, files[i].basename, files[i].basenameLength);
234f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
235f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        length=4+8*fileCount+basenameTotal;
236f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
237f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* copy the files */
238f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        for(i=0; i<fileCount; ++i) {
239f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            /* pad to 16-align the next file */
240f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            length&=0xf;
241f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if(length!=0) {
242f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                udata_writePadding(out, 16-length);
243f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
244f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
245f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (verbose) {
246f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                printf("adding %s (%ld byte%s)\n", files[i].pathname, (long)files[i].fileSize, files[i].fileSize == 1 ? "" : "s");
247f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
248f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
249f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            /* copy the next file */
250f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            file=T_FileStream_open(files[i].pathname, "rb");
251f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if(file==NULL) {
252f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                fprintf(stderr, "gencmn: unable to open listed file %s\n", files[i].pathname);
253f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                exit(U_FILE_ACCESS_ERROR);
254f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
255f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            for(nread = 0;;) {
256f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                length=T_FileStream_read(file, buffer, sizeof(buffer));
257f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if(length <= 0) {
258f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    break;
259f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
260f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                nread += length;
261f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                udata_writeBlock(out, buffer, length);
262f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
263f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            T_FileStream_close(file);
264f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            length=files[i].fileSize;
265f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
266f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (nread != files[i].fileSize) {
267f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)              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");
268f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                exit(U_FILE_ACCESS_ERROR);
269f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
270f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
271f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
272f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* pad to 16-align the last file (cleaner, avoids growing .dat files in icuswap) */
273f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        length&=0xf;
274f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(length!=0) {
275f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            udata_writePadding(out, 16-length);
276f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
277f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
278f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* finish */
279f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        udata_finish(out, &errorCode);
280f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(U_FAILURE(errorCode)) {
281f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            fprintf(stderr, "gencmn: udata_finish() failed - %s\n", u_errorName(errorCode));
282f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            exit(errorCode);
283f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
284f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    } else {
285f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* write a .c source file with the table of contents */
286f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        char *filename;
287f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        FileStream *out;
288f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
289f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* create the output filename */
290f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        filename=s=buffer;
291f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        uprv_strcpy(filename, destDir);
292f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        s=filename+uprv_strlen(filename);
293f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(s>filename && *(s-1)!=U_FILE_SEP_CHAR) {
294f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            *s++=U_FILE_SEP_CHAR;
295f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
296f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        uprv_strcpy(s, name);
297f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(*(type)!=0) {
298f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            s+=uprv_strlen(s);
299f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            *s++='_';
300f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            uprv_strcpy(s, type);
301f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
302f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        s+=uprv_strlen(s);
303f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        uprv_strcpy(s, ".c");
304f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
305f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* open the output file */
306f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        out=T_FileStream_open(filename, "w");
307f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (gencmnFileName != NULL) {
308f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            uprv_strcpy(gencmnFileName, filename);
309f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
310f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(out==NULL) {
311f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            fprintf(stderr, "gencmn: unable to open .c output file %s\n", filename);
312f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            exit(U_FILE_ACCESS_ERROR);
313f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
314f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
315f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* write the source file */
316f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        sprintf(buffer,
317f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            "/*\n"
318f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            " * ICU common data table of contents for %s.%s ,\n"
319f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            " * Automatically generated by icu/source/tools/gencmn/gencmn .\n"
320f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            " */\n\n"
321f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            "#include \"unicode/utypes.h\"\n"
322f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            "#include \"unicode/udata.h\"\n"
323f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            "\n"
324f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            "/* external symbol declarations for data */\n",
325f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            name, type);
326f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        T_FileStream_writeLine(out, buffer);
327f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
328f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        sprintf(buffer, "extern const char\n    %s%s[]", symPrefix?symPrefix:"", files[0].pathname);
329f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        T_FileStream_writeLine(out, buffer);
330f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        for(i=1; i<fileCount; ++i) {
331f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            sprintf(buffer, ",\n    %s%s[]", symPrefix?symPrefix:"", files[i].pathname);
332f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            T_FileStream_writeLine(out, buffer);
333f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
334f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        T_FileStream_writeLine(out, ";\n\n");
335f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
336f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        sprintf(
337f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            buffer,
338f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            "U_EXPORT struct {\n"
339f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            "    uint16_t headerSize;\n"
340f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            "    uint8_t magic1, magic2;\n"
341f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            "    UDataInfo info;\n"
342f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            "    char padding[%lu];\n"
343f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            "    uint32_t count, reserved;\n"
344f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            "    struct {\n"
345f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            "        const char *name;\n"
346f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            "        const void *data;\n"
347f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            "    } toc[%lu];\n"
348f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            "} U_EXPORT2 %s_dat = {\n"
349f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            "    32, 0xda, 0x27, {\n"
350f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            "        %lu, 0,\n"
351f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            "        %u, %u, %u, 0,\n"
352f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            "        {0x54, 0x6f, 0x43, 0x50},\n"
353f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            "        {1, 0, 0, 0},\n"
354f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            "        {0, 0, 0, 0}\n"
355f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            "    },\n"
356f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            "    \"\", %lu, 0, {\n",
357f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            (unsigned long)32-4-sizeof(UDataInfo),
358f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            (unsigned long)fileCount,
359f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            entrypointName,
360f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            (unsigned long)sizeof(UDataInfo),
361f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            U_IS_BIG_ENDIAN,
362f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            U_CHARSET_FAMILY,
363f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            U_SIZEOF_UCHAR,
364f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            (unsigned long)fileCount
365f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        );
366f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        T_FileStream_writeLine(out, buffer);
367f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
368f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        sprintf(buffer, "        { \"%s\", %s%s }", files[0].basename, symPrefix?symPrefix:"", files[0].pathname);
369f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        T_FileStream_writeLine(out, buffer);
370f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        for(i=1; i<fileCount; ++i) {
371f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            sprintf(buffer, ",\n        { \"%s\", %s%s }", files[i].basename, symPrefix?symPrefix:"", files[i].pathname);
372f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            T_FileStream_writeLine(out, buffer);
373f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
374f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
375f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        T_FileStream_writeLine(out, "\n    }\n};\n");
376f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        T_FileStream_close(out);
377f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
378f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        uprv_free(symPrefix);
379f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
380f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
381f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
382f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void
383f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)addFile(const char *filename, const char *name, const char *source, UBool sourceTOC, UBool verbose) {
384f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    char *s;
385f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uint32_t length;
386f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    char *fullPath = NULL;
387f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
388f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(fileCount==fileMax) {
389f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      fileMax += CHUNK_FILE_COUNT;
390f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      files = uprv_realloc(files, fileMax*sizeof(files[0])); /* note: never freed. */
391f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      if(files==NULL) {
392f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fprintf(stderr, "pkgdata/gencmn: Could not allocate %ld bytes for %d files\n", (fileMax*sizeof(files[0])), fileCount);
393f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        exit(U_MEMORY_ALLOCATION_ERROR);
394f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      }
395f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
396f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
397f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(!sourceTOC) {
398f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        FileStream *file;
399f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
400f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(uprv_pathIsAbsolute(filename)) {
401f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            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);
402f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            exit(U_ILLEGAL_ARGUMENT_ERROR);
403f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
404f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fullPath = pathToFullPath(filename, source);
405f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
406f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* store the pathname */
407f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        length = (uint32_t)(uprv_strlen(filename) + 1 + uprv_strlen(name) + 1);
408f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        s=allocString(length);
409f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        uprv_strcpy(s, name);
410f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        uprv_strcat(s, U_TREE_ENTRY_SEP_STRING);
411f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        uprv_strcat(s, filename);
412f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
413f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* get the basename */
414f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fixDirToTreePath(s);
415f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        files[fileCount].basename=s;
416f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        files[fileCount].basenameLength=length;
417f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
418f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        files[fileCount].pathname=fullPath;
419f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
420f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        basenameTotal+=length;
421f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
422f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* try to open the file */
423f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        file=T_FileStream_open(fullPath, "rb");
424f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(file==NULL) {
425f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            fprintf(stderr, "gencmn: unable to open listed file %s\n", fullPath);
426f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            exit(U_FILE_ACCESS_ERROR);
427f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
428f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
429f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* get the file length */
430f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        length=T_FileStream_size(file);
431f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(T_FileStream_error(file) || length<=20) {
432f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            fprintf(stderr, "gencmn: unable to get length of listed file %s\n", fullPath);
433f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            exit(U_FILE_ACCESS_ERROR);
434f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
435f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
436f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        T_FileStream_close(file);
437f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
438f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* do not add files that are longer than maxSize */
439f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(maxSize && length>maxSize) {
440f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (verbose) {
441f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                printf("%s ignored (size %ld > %ld)\n", fullPath, (long)length, (long)maxSize);
442f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
443f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return;
444f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
445f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        files[fileCount].fileSize=length;
446f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    } else {
447f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        char *t;
448f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
449f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* get and store the basename */
450f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* need to include the package name */
451f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        length = (uint32_t)(uprv_strlen(filename) + 1 + uprv_strlen(name) + 1);
452f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        s=allocString(length);
453f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        uprv_strcpy(s, name);
454f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        uprv_strcat(s, U_TREE_ENTRY_SEP_STRING);
455f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        uprv_strcat(s, filename);
456f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fixDirToTreePath(s);
457f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        files[fileCount].basename=s;
458f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
459f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
460f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* turn the basename into an entry point name and store in the pathname field */
461f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        t=files[fileCount].pathname=allocString(length);
462f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        while(--length>0) {
463f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if(*s=='.' || *s=='-' || *s=='/') {
464f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                *t='_';
465f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            } else {
466f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                *t=*s;
467f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
468f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            ++s;
469f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            ++t;
470f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
471f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        *t=0;
472f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
473f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    ++fileCount;
474f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
475f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
476f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static char *
477f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)allocString(uint32_t length) {
478f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uint32_t top=stringTop+length;
479f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    char *p;
480f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
481f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(top>STRING_STORE_SIZE) {
482f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fprintf(stderr, "gencmn: out of memory\n");
483f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        exit(U_MEMORY_ALLOCATION_ERROR);
484f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
485f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    p=stringStore+stringTop;
486f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    stringTop=top;
487f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return p;
488f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
489f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
490f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static char *
491f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)pathToFullPath(const char *path, const char *source) {
492f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t length;
493f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t newLength;
494f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    char *fullPath;
495f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t n;
496f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
497f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    length = (uint32_t)(uprv_strlen(path) + 1);
498f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    newLength = (length + 1 + (int32_t)uprv_strlen(source));
499f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fullPath = uprv_malloc(newLength);
500f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(source != NULL) {
501f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        uprv_strcpy(fullPath, source);
502f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        uprv_strcat(fullPath, U_FILE_SEP_STRING);
503f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    } else {
504f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fullPath[0] = 0;
505f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
506f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    n = (int32_t)uprv_strlen(fullPath);
507f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uprv_strcat(fullPath, path);
508f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
509f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if (U_FILE_ALT_SEP_CHAR != U_TREE_ENTRY_SEP_CHAR)
510f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if (U_FILE_ALT_SEP_CHAR != U_FILE_SEP_CHAR)
511f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* replace tree separator (such as '/') with file sep char (such as ':' or '\\') */
512f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for(;fullPath[n];n++) {
513f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(fullPath[n] == U_FILE_ALT_SEP_CHAR) {
514f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            fullPath[n] = U_FILE_SEP_CHAR;
515f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
516f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
517f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
518f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
519f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if (U_FILE_SEP_CHAR != U_TREE_ENTRY_SEP_CHAR)
520f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* replace tree separator (such as '/') with file sep char (such as ':' or '\\') */
521f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for(;fullPath[n];n++) {
522f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(fullPath[n] == U_TREE_ENTRY_SEP_CHAR) {
523f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            fullPath[n] = U_FILE_SEP_CHAR;
524f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
525f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
526f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
527f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return fullPath;
528f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
529f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
530f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int
531f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)compareFiles(const void *file1, const void *file2) {
532f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* sort by basename */
533f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return uprv_strcmp(((File *)file1)->basename, ((File *)file2)->basename);
534f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
535f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
536f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void
537f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)fixDirToTreePath(char *s)
538f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
539f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#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))
540f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    char *t;
541f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
542f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if (U_FILE_SEP_CHAR != U_TREE_ENTRY_SEP_CHAR)
543f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for(t=s;t=uprv_strchr(t,U_FILE_SEP_CHAR);) {
544f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        *t = U_TREE_ENTRY_SEP_CHAR;
545f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
546f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
547f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if (U_FILE_ALT_SEP_CHAR != U_FILE_SEP_CHAR) && (U_FILE_ALT_SEP_CHAR != U_TREE_ENTRY_SEP_CHAR)
548f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for(t=s;t=uprv_strchr(t,U_FILE_ALT_SEP_CHAR);) {
549f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        *t = U_TREE_ENTRY_SEP_CHAR;
550f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
551f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
552f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
553