~ubuntu-branches/ubuntu/gutsy/icu/gutsy-updates

« back to all changes in this revision

Viewing changes to source/tools/genrb/genrb.c

  • Committer: Package Import Robot
  • Author(s): Jay Berkenbilt
  • Date: 2005-11-19 11:29:31 UTC
  • mfrom: (1.1.2)
  • Revision ID: package-import@ubuntu.com-20051119112931-vcizkrp10tli4enw
Tags: 3.4-3
Explicitly build with g++ 3.4.  The current ICU fails its test suite
with 4.0 but not with 3.4.  Future versions should work properly with
4.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
*******************************************************************************
3
 
*
4
 
*   Copyright (C) 1998-2001, International Business Machines
5
 
*   Corporation and others.  All Rights Reserved.
6
 
*
7
 
*******************************************************************************
8
 
*
9
 
* File genrb.c
10
 
*
11
 
* Modification History:
12
 
*
13
 
*   Date        Name        Description
14
 
*   05/25/99    stephen     Creation.
15
 
*   5/10/01     Ram         removed ustdio dependency
16
 
*******************************************************************************
17
 
*/
18
 
 
19
 
#include "genrb.h"
20
 
 
21
 
/* Protos */
22
 
static void  processFile(const char *filename, const char* cp, const char *inputDir, const char *outputDir, UErrorCode *status);
23
 
static char *make_res_filename(const char *filename, const char *outputDir, UErrorCode *status);
24
 
 
25
 
/* File suffixes */
26
 
#define RES_SUFFIX ".res"
27
 
#define COL_SUFFIX ".col"
28
 
 
29
 
static char theCurrentFileName[4096];
30
 
const char *gCurrentFileName = theCurrentFileName;
31
 
#ifdef XP_MAC_CONSOLE
32
 
#include <console.h>
33
 
#endif
34
 
 
35
 
enum
36
 
{
37
 
    HELP1,
38
 
    HELP2,
39
 
    VERBOSE,
40
 
    QUIET,
41
 
    VERSION,
42
 
    SOURCEDIR,
43
 
    DESTDIR,
44
 
    ENCODING,
45
 
    ICUDATADIR,
46
 
    WRITE_JAVA,
47
 
    COPYRIGHT
48
 
};
49
 
 
50
 
UOption options[]={
51
 
                      UOPTION_HELP_H,
52
 
                      UOPTION_HELP_QUESTION_MARK,
53
 
                      UOPTION_VERBOSE,
54
 
                      UOPTION_QUIET,
55
 
                      UOPTION_VERSION,
56
 
                      UOPTION_SOURCEDIR,
57
 
                      UOPTION_DESTDIR,
58
 
                      UOPTION_ENCODING,
59
 
                      UOPTION_ICUDATADIR,
60
 
                      UOPTION_WRITE_JAVA,
61
 
                      UOPTION_COPYRIGHT
62
 
                  };
63
 
 
64
 
static     UBool       verbose = FALSE;
65
 
static     UBool       write_java = FALSE;
66
 
static     const char* outputEnc ="";
67
 
int
68
 
main(int argc,
69
 
     char* argv[])
70
 
{
71
 
    UErrorCode  status    = U_ZERO_ERROR;
72
 
    const char *arg       = NULL;
73
 
    const char *outputDir = NULL; /* NULL = no output directory, use current */
74
 
    const char *inputDir  = NULL;
75
 
    const char *encoding  = "";
76
 
    int         i;
77
 
 
78
 
    U_MAIN_INIT_ARGS(argc, argv);
79
 
 
80
 
    argc = u_parseArgs(argc, argv, (int32_t)(sizeof(options)/sizeof(options[0])), options);
81
 
 
82
 
    /* error handling, printing usage message */
83
 
    if(argc<0) {
84
 
        fprintf(stderr, "%s: error in command line argument \"%s\"\n", argv[0], argv[-argc]);
85
 
    } else if(argc<2) {
86
 
        argc = -1;
87
 
    }
88
 
 
89
 
    if(options[VERSION].doesOccur) {
90
 
        fprintf(stderr,
91
 
                "%s version %s (ICU version %s).\n"
92
 
                "%s\n",
93
 
                argv[0], GENRB_VERSION, U_ICU_VERSION, U_COPYRIGHT_STRING);
94
 
        return U_ZERO_ERROR;
95
 
    }
96
 
 
97
 
    if(argc<0 || options[HELP1].doesOccur || options[HELP2].doesOccur) {
98
 
        /*
99
 
         * Broken into chucks because the C89 standard says the minimum
100
 
         * required supported string length is 509 bytes.
101
 
         */
102
 
        fprintf(stderr,
103
 
                "Usage: %s [OPTIONS] [FILES]\n"
104
 
                "\tReads the list of resource bundle source files and creates\n"
105
 
                "\tbinary version of reosurce bundles (.res files)\n",
106
 
                argv[0]);
107
 
        fprintf(stderr,
108
 
                "Options:\n"
109
 
                "\t-h or -? or --help   this usage text\n"
110
 
                "\t-q or --quiet        do not display warnings\n"
111
 
                "\t-v or --verbose      prints out extra information about processing the files\n"
112
 
                "\t-V or --version      prints out version number and exits\n"
113
 
                "\t-c or --copyright    include copyright notice\n");
114
 
        fprintf(stderr,
115
 
                "\t-e or --encoding     encoding of source files, leave empty for system default encoding\n"
116
 
                "\t                     NOTE: ICU must be completely built to use this option\n"
117
 
                "\t-d of --destdir      destination directory, followed by the path, defaults to %s\n"
118
 
                "\t-s or --sourcedir    source directory for files followed by path, defaults to %s\n"
119
 
                "\t-i or --icudatadir   directory for locating any needed intermediate data files,\n"
120
 
                "\t                     followed by path, defaults to %s\n",
121
 
                u_getDataDirectory(), u_getDataDirectory(), u_getDataDirectory());
122
 
        fprintf(stderr,
123
 
                "\t-j or --write-java   write a Java ListResourceBundle for ICU4J, followed by optional encoding\n"
124
 
                "\t                     defaults to ASCII and \\uXXXX format.\n");
125
 
        return argc < 0 ? U_ILLEGAL_ARGUMENT_ERROR : U_ZERO_ERROR;
126
 
    }
127
 
 
128
 
    if(options[VERBOSE].doesOccur) {
129
 
        verbose = TRUE;
130
 
    }
131
 
 
132
 
    if(options[QUIET].doesOccur) {
133
 
        setShowWarning(FALSE);
134
 
    }
135
 
    
136
 
    if(options[COPYRIGHT].doesOccur){
137
 
        setIncludeCopyright(TRUE);
138
 
    }
139
 
 
140
 
    if(options[SOURCEDIR].doesOccur) {
141
 
        inputDir = options[SOURCEDIR].value;
142
 
    }
143
 
 
144
 
    if(options[DESTDIR].doesOccur) {
145
 
        outputDir = options[DESTDIR].value;
146
 
    }
147
 
 
148
 
    if(options[ENCODING].doesOccur) {
149
 
        encoding = options[ENCODING].value;
150
 
    }
151
 
 
152
 
    if(options[ICUDATADIR].doesOccur) {
153
 
        u_setDataDirectory(options[ICUDATADIR].value);
154
 
    }
155
 
    if(options[WRITE_JAVA].doesOccur) {
156
 
        write_java = TRUE;
157
 
        outputEnc = options[WRITE_JAVA].value;
158
 
    }
159
 
 
160
 
    initParser();
161
 
 
162
 
    /* generate the binary files */
163
 
    for(i = 1; i < argc; ++i) {
164
 
        status = U_ZERO_ERROR;
165
 
        arg    = getLongPathname(argv[i]);
166
 
 
167
 
        if (inputDir) {
168
 
            uprv_strcpy(theCurrentFileName, inputDir);
169
 
            uprv_strcat(theCurrentFileName, U_FILE_SEP_STRING);
170
 
        } else {
171
 
            *theCurrentFileName = 0;
172
 
        }
173
 
        uprv_strcat(theCurrentFileName, arg);
174
 
 
175
 
        if (verbose) {
176
 
            printf("processing file \"%s\"\n", theCurrentFileName);
177
 
        }
178
 
        processFile(arg, encoding, inputDir, outputDir, &status);
179
 
    }
180
 
 
181
 
    return status;
182
 
}
183
 
 
184
 
/* Process a file */
185
 
static void
186
 
processFile(const char *filename, const char *cp, const char *inputDir, const char *outputDir, UErrorCode *status) {
187
 
    FileStream     *in           = NULL;
188
 
    struct SRBRoot *data         = NULL;
189
 
    UCHARBUF       *ucbuf        = NULL;
190
 
    char           *rbname       = NULL;
191
 
    char           *openFileName = NULL;
192
 
    char           *inputDirBuf  = NULL;
193
 
 
194
 
    char           outputFileName[256];
195
 
 
196
 
    if (U_FAILURE(*status)) {
197
 
        return;
198
 
    }
199
 
 
200
 
    /* Setup */
201
 
    in = 0;
202
 
 
203
 
    /* Open the input file for reading */
204
 
    if (!uprv_strcmp(filename, "-")) {
205
 
        in = T_FileStream_stdin();
206
 
    } else if(inputDir == NULL) {
207
 
        const char *filenameBegin = uprv_strrchr(filename, U_FILE_SEP_CHAR);
208
 
        if (filenameBegin != NULL) {
209
 
            /*
210
 
             * When a filename ../../../data/root.txt is specified, 
211
 
             * we presume that the input directory is ../../../data
212
 
             * This is very important when the resource file includes
213
 
             * another file, like UCARules.txt or thaidict.brk.
214
 
             */
215
 
            int32_t filenameSize = filenameBegin - filename + 1;
216
 
            inputDirBuf = uprv_strncpy((char *)uprv_malloc(filenameSize), filename, filenameSize);
217
 
            inputDirBuf[filenameSize - 1] = 0;
218
 
            inputDir = inputDirBuf;
219
 
        }
220
 
        in = T_FileStream_open(filename, "rb");
221
 
    } else {
222
 
        int32_t dirlen  = (int32_t)uprv_strlen(inputDir);
223
 
        int32_t filelen = (int32_t)uprv_strlen(filename);
224
 
        if(inputDir[dirlen-1] != U_FILE_SEP_CHAR) {
225
 
            openFileName = (char *) uprv_malloc(dirlen + filelen + 2);
226
 
            openFileName[0] = '\0';
227
 
            /*
228
 
             * append the input dir to openFileName if the first char in 
229
 
             * filename is not file seperation char and the last char input directory is  not '.'.
230
 
             * This is to support :
231
 
             * genrb -s. /home/icu/data
232
 
             * genrb -s. icu/data
233
 
             * The user cannot mix notations like
234
 
             * genrb -s. /icu/data --- the absolute path specified. -s redundant
235
 
             * user should use
236
 
             * genrb -s. icu/data  --- start from CWD and look in icu/data dir
237
 
             */
238
 
            if( (filename[0] != U_FILE_SEP_CHAR) && (inputDir[dirlen-1] !='.')){
239
 
                uprv_strcpy(openFileName, inputDir);
240
 
                openFileName[dirlen]     = U_FILE_SEP_CHAR;
241
 
            }
242
 
            openFileName[dirlen + 1] = '\0';
243
 
            uprv_strcat(openFileName, filename);
244
 
        } else {
245
 
            openFileName = (char *) uprv_malloc(dirlen + filelen + 1);
246
 
            uprv_strcpy(openFileName, inputDir);
247
 
            uprv_strcat(openFileName, filename);
248
 
        }
249
 
        in = T_FileStream_open(openFileName, "rb");
250
 
    }
251
 
 
252
 
    if(in == 0) {
253
 
        *status = U_FILE_ACCESS_ERROR;
254
 
        fprintf(stderr, "couldn't open file %s\n", openFileName == NULL ? filename : openFileName);
255
 
        goto finish;
256
 
    } else {
257
 
        /* auto detect popular encodings */
258
 
        if (*cp=='\0' && ucbuf_autodetect(in, &cp) && verbose) {
259
 
            printf("autodetected encoding %s\n", cp);
260
 
        }
261
 
    }
262
 
 
263
 
    ucbuf = ucbuf_open(in, cp, 0, status);
264
 
 
265
 
    if (ucbuf == NULL || U_FAILURE(*status)) {
266
 
        goto finish;
267
 
    }
268
 
 
269
 
    /* Parse the data into an SRBRoot */
270
 
    data = parse(ucbuf, inputDir, status);
271
 
 
272
 
    if (data == NULL || U_FAILURE(*status)) {
273
 
        goto finish;
274
 
    }
275
 
 
276
 
    /* Determine the target rb filename */
277
 
    rbname = make_res_filename(filename, outputDir, status);
278
 
    if(U_FAILURE(*status)) {
279
 
        goto finish;
280
 
    }
281
 
    if(write_java== FALSE){
282
 
        /* Write the data to the file */
283
 
        bundle_write(data, outputDir, outputFileName, sizeof(outputFileName), status);
284
 
    }else{
285
 
        bundle_write_java(data,outputDir,outputEnc, outputFileName, sizeof(outputFileName), status);
286
 
    }
287
 
    if (U_FAILURE(*status)) {
288
 
        fprintf(stderr, "couldn't write bundle %s. Error:%s\n", outputFileName,u_errorName(*status));
289
 
    }
290
 
    bundle_close(data, status);
291
 
 
292
 
finish:
293
 
 
294
 
    if (inputDirBuf != NULL) {
295
 
        uprv_free(inputDirBuf);
296
 
    }
297
 
 
298
 
    if (openFileName != NULL) {
299
 
        uprv_free(openFileName);
300
 
    }
301
 
 
302
 
    if(ucbuf) {
303
 
        ucbuf_close(ucbuf);
304
 
    }
305
 
 
306
 
    /* Clean up */
307
 
    if (in != T_FileStream_stdin()) {
308
 
        T_FileStream_close(in);
309
 
    }
310
 
 
311
 
    if (rbname) {
312
 
        uprv_free(rbname);
313
 
    }
314
 
}
315
 
 
316
 
/* Generate the target .res file name from the input file name */
317
 
static char*
318
 
make_res_filename(const char *filename,
319
 
                  const char *outputDir,
320
 
                  UErrorCode *status) {
321
 
    char *basename;
322
 
    char *dirname;
323
 
    char *resName;
324
 
 
325
 
    if (U_FAILURE(*status)) {
326
 
        return 0;
327
 
    }
328
 
 
329
 
    /* setup */
330
 
    basename = dirname = resName = 0;
331
 
 
332
 
    /* determine basename, and compiled file names */
333
 
    basename = (char*) uprv_malloc(sizeof(char) * (uprv_strlen(filename) + 1));
334
 
    if(basename == 0) {
335
 
        *status = U_MEMORY_ALLOCATION_ERROR;
336
 
        goto finish;
337
 
    }
338
 
 
339
 
    get_basename(basename, filename);
340
 
 
341
 
    dirname = (char*) uprv_malloc(sizeof(char) * (uprv_strlen(filename) + 1));
342
 
    if(dirname == 0) {
343
 
        *status = U_MEMORY_ALLOCATION_ERROR;
344
 
        goto finish;
345
 
    }
346
 
 
347
 
    get_dirname(dirname, filename);
348
 
 
349
 
    if (outputDir == NULL) {
350
 
        /* output in same dir as .txt */
351
 
        resName = (char*) uprv_malloc(sizeof(char) * (uprv_strlen(dirname)
352
 
                                      + uprv_strlen(basename)
353
 
                                      + uprv_strlen(RES_SUFFIX) + 1));
354
 
        if(resName == 0) {
355
 
            *status = U_MEMORY_ALLOCATION_ERROR;
356
 
            goto finish;
357
 
        }
358
 
 
359
 
        uprv_strcpy(resName, dirname);
360
 
        uprv_strcat(resName, basename);
361
 
    } else {
362
 
        int32_t dirlen      = (int32_t)uprv_strlen(outputDir);
363
 
        int32_t basenamelen = (int32_t)uprv_strlen(basename);
364
 
 
365
 
        resName = (char*) uprv_malloc(sizeof(char) * (dirlen + basenamelen + 2));
366
 
 
367
 
        if (resName == NULL) {
368
 
            *status = U_MEMORY_ALLOCATION_ERROR;
369
 
            goto finish;
370
 
        }
371
 
 
372
 
        uprv_strcpy(resName, outputDir);
373
 
 
374
 
        if(outputDir[dirlen] != U_FILE_SEP_CHAR) {
375
 
            resName[dirlen]     = U_FILE_SEP_CHAR;
376
 
            resName[dirlen + 1] = '\0';
377
 
        }
378
 
 
379
 
        uprv_strcat(resName, basename);
380
 
    }
381
 
 
382
 
finish:
383
 
    uprv_free(basename);
384
 
    uprv_free(dirname);
385
 
 
386
 
    return resName;
387
 
}
388
 
 
389
 
/*
390
 
 * Local Variables:
391
 
 * indent-tabs-mode: nil
392
 
 * End:
393
 
 */