/* ******************************************************************************* * * Copyright (C) 1998-1999, International Business Machines * Corporation and others. All Rights Reserved. * ******************************************************************************* * * File genrb.c * * Modification History: * * Date Name Description * 05/25/99 stephen Creation. ******************************************************************************* */ #include #include "unicode/utypes.h" #include "cmemory.h" #include "cstring.h" #include "filestrm.h" U_CDECL_BEGIN extern int32_t lineCount; extern char lastTag[]; #include "error.h" #include "parse.h" #include "util.h" #include "reslist.h" U_CDECL_END #include "toolutil.h" #include "uoptions.h" #include "unicode/ucol.h" #include "unicode/uloc.h" /* Protos */ static void usage(void); static void version(void); static void processFile(const char *filename, const char* cp, const char *inputDir, const char *outputDir, UErrorCode *status); static char* make_res_filename(const char *filename, const char *outputDir, UErrorCode *status); static char* make_col_filename(const char *filename, const char *outputDir, UErrorCode *status); static void make_col(const char *filename, UErrorCode *status); int main(int argc, char **argv); /* File suffixes */ #define RES_SUFFIX ".res" #define COL_SUFFIX ".col" /* The version of genrb */ #define GENRB_VERSION "2.0" enum { HELP1, HELP2, VERBOSE, VERSION, SOURCEDIR, DESTDIR, ENCODING }; UOption options[]={ UOPTION_HELP_H, UOPTION_HELP_QUESTION_MARK, UOPTION_VERBOSE, UOPTION_VERSION, UOPTION_SOURCEDIR, UOPTION_DESTDIR, UOPTION_ENCODING }; #ifdef XP_MAC_CONSOLE #include #endif int main(int argc, char* argv[]) { int i; UErrorCode status = U_ZERO_ERROR; const char *arg = NULL; const char *outputDir = NULL; /* NULL = no output directory, use current */ const char *inputDir = NULL; const char *encoding = ""; UBool verbose; #ifdef XP_MAC_CONSOLE argc = ccommand((char***)&argv); #endif argc = u_parseArgs(argc, argv, sizeof(options)/sizeof(options[0]), options); /* error handling, printing usage message */ if(argc<0) { fprintf(stderr, "error in command line argument \"%s\"\n", argv[-argc]); } else if(argc<2) { argc=-1; } if(argc<0 || options[HELP1].doesOccur || options[HELP2].doesOccur) { fprintf(stderr, "Usage: %s [OPTIONS] [FILES]\n" "\treads the list of resource bundle source files and creates\n" "\tbinary version of reosurce bundles (.res files)\n" "\tOptions:\n" "\t\t-h, -? or --help this usage text\n" "\t\t-V or --version prints out version number and exits\n" "\t\t-d of --destdir destination directory, followed by the path, defaults to %s\n" "\t\t-v or --verbose be verbose\n" "\t\t-e or --encoding encoding of source files, leave empty for system default encoding\n" "\t\t NOTE: ICU must be completely built to use this option\n" "\t\t-s or --sourcedir source directory for files followed by path, defaults to %s\n", argv[0], u_getDataDirectory(), u_getDataDirectory()); return argc<0 ? U_ILLEGAL_ARGUMENT_ERROR : U_ZERO_ERROR; } if(options[VERSION].doesOccur) { fprintf(stderr, "%s version %s (ICU version %s).\n" "%s\n", argv[0], GENRB_VERSION, U_ICU_VERSION, U_COPYRIGHT_STRING); return U_ZERO_ERROR; } if(options[VERBOSE].doesOccur) { verbose = TRUE; } if(options[SOURCEDIR].doesOccur) { inputDir = options[SOURCEDIR].value; } if(options[DESTDIR].doesOccur) { outputDir = options[DESTDIR].value; } if(options[ENCODING].doesOccur) { encoding = options[ENCODING].value; } /* generate the binary files */ for(i = 1; i < argc; ++i) { status = U_ZERO_ERROR; arg = getLongPathname(argv[i]); /* if(outputDir == NULL) { char *pathSepPosition = NULL; pathSepPosition = uprv_strrchr(arg, U_FILE_SEP_CHAR); if(pathSepPosition != NULL) { int32_t pathLen = pathSepPosition-arg+1; outputDir = (char *) uprv_malloc(sizeof(char)*(pathLen+1)); uprv_strncpy(outputDir, arg, pathLen); outputDir[pathLen] = '\0'; } } */ printf("genrb: processing file \"%s\"\n", arg); processFile(arg, encoding, inputDir, outputDir, &status); /*make_col(arg, &status);*/ if(U_FAILURE(status)) { printf("genrb: %s processing file \"%s\" around line %d, last Tag %s\n", u_errorName(status), arg, lineCount, lastTag); } if(getErrorText() != 0) printf("Issued Errors and Warnings:\n (%s)\n", getErrorText()); } return status; } /* Process a file */ static void processFile(const char *filename, const char *cp, const char *inputDir, const char *outputDir, UErrorCode *status) { FileStream *in; struct SRBRoot *data; char *rbname; if(U_FAILURE(*status)) return; /* Setup */ in = 0; /* Open the input file for reading */ if(inputDir == NULL) { in = T_FileStream_open(filename, "r"); } else { char *openFileName = NULL; int32_t dirlen = uprv_strlen(inputDir); int32_t filelen = uprv_strlen(filename); if(inputDir[dirlen-1] != U_FILE_SEP_CHAR) { openFileName = (char *) uprv_malloc(dirlen+filelen+2); uprv_strcpy(openFileName, inputDir); openFileName[dirlen] = U_FILE_SEP_CHAR; openFileName[dirlen+1] = '\0'; uprv_strcat(openFileName, filename); } else { openFileName = (char *) uprv_malloc(dirlen+filelen+1); uprv_strcpy(openFileName, inputDir); uprv_strcat(openFileName, filename); } in = T_FileStream_open(openFileName, "rb"); uprv_free(openFileName); } if(in == 0) { *status = U_FILE_ACCESS_ERROR; setErrorText("File not found"); return; } else { /* auto detect popular encodings */ UBool autodetect = FALSE; char start[3]; T_FileStream_read(in, start, 3); if(start[0] == '\xFE' && start[1] == '\xFF') { cp = "utf-16be"; autodetect = TRUE; } else if(start[0] == '\xFF' && start[1] == '\xFE') { cp = "utf-16le"; autodetect = TRUE; } else if(start[0] == '\xEF' && start[1] == '\xBB' && start[2] == '\xBF') { cp = "utf-8"; autodetect = TRUE; } T_FileStream_rewind(in); if(autodetect == TRUE) { printf("Autodetected encoding %s\n", cp); } } /* Parse the data into an SRBRoot */ data = parse(in, cp, inputDir, status); /* Determine the target rb filename */ rbname = make_res_filename(filename, outputDir, status); if(U_FAILURE(*status)) { goto finish; } /* Open the target file for writing */ /* Write the data to the file */ /*rb_write(rb_out, data, status);*/ bundle_write(data, outputDir, status); /*bundle_write(data, outputDir, rbname, status);*/ bundle_close(data, status); finish: /* Clean up */ T_FileStream_close(in); uprv_free(rbname); } /* Generate the target .res file name from the input file name */ static char* make_res_filename(const char *filename, const char *outputDir, UErrorCode *status) { char *basename; char *dirname; char *resName; if(U_FAILURE(*status)) return 0; /* setup */ basename = dirname = resName = 0; /* determine basename, and compiled file names */ basename = (char*) uprv_malloc(sizeof(char) * (uprv_strlen(filename) + 1)); if(basename == 0) { *status = U_MEMORY_ALLOCATION_ERROR; goto finish; } get_basename(basename, filename); dirname = (char*) uprv_malloc(sizeof(char) * (uprv_strlen(filename) + 1)); if(dirname == 0) { *status = U_MEMORY_ALLOCATION_ERROR; goto finish; } get_dirname(dirname, filename); if ( outputDir == NULL ) { /* output in same dir as .txt */ resName = (char*) uprv_malloc(sizeof(char) * (uprv_strlen(dirname) + uprv_strlen(basename) + uprv_strlen(RES_SUFFIX) + 1)); if(resName == 0) { *status = U_MEMORY_ALLOCATION_ERROR; goto finish; } uprv_strcpy(resName, dirname); uprv_strcat(resName, basename); /*uprv_strcat(resName, RES_SUFFIX);*/ } else { int32_t dirlen = uprv_strlen(outputDir); /*int32_t dirnamelen = uprv_strlen(dirname);*/ int32_t basenamelen = uprv_strlen(basename); resName = (char*) uprv_malloc(sizeof(char) * (dirlen + basenamelen + 2)); /*resName = (char*) uprv_malloc(sizeof(char) * (dirnamelen + basenamelen + 1));*/ if(resName == 0) { *status = U_MEMORY_ALLOCATION_ERROR; goto finish; } uprv_strcpy(resName, outputDir); if(outputDir[dirlen] != U_FILE_SEP_CHAR) { resName[dirlen] = U_FILE_SEP_CHAR; resName[dirlen+1] = '\0'; } /*uprv_strcat(resName, dirname);*/ /*uprv_strcpy(resName, dirname);*/ uprv_strcat(resName, basename); } finish: uprv_free(basename); uprv_free(dirname); return resName; } /* This seems to be dead code */ #if 0 /* Generate the target .col file name from the input file name */ static char* make_col_filename(const char *filename, const char *outputDir, UErrorCode *status) { char *basename; char *dirname; char *colName; if(U_FAILURE(*status)) return 0; /* setup */ basename = dirname = colName = 0; /* determine basename, and compiled file names */ basename = (char*) uprv_malloc(sizeof(char) * (uprv_strlen(filename) + 1)); if(basename == 0) { *status = U_MEMORY_ALLOCATION_ERROR; goto finish; } get_basename(basename, filename); dirname = (char*) uprv_malloc(sizeof(char) * (uprv_strlen(filename) + 1)); if(dirname == 0) { *status = U_MEMORY_ALLOCATION_ERROR; goto finish; } if(outputDir == NULL) { get_dirname(dirname, filename); colName = (char*) uprv_malloc(sizeof(char) * (uprv_strlen(dirname) + uprv_strlen(basename) + uprv_strlen(COL_SUFFIX) + 1)); if(colName == 0) { *status = U_MEMORY_ALLOCATION_ERROR; goto finish; } uprv_strcpy(colName, dirname); uprv_strcat(colName, basename); uprv_strcat(colName, COL_SUFFIX); } else { get_dirname(dirname, filename); colName = (char*) uprv_malloc(sizeof(char) * (uprv_strlen(outputDir) + uprv_strlen(basename) + uprv_strlen(COL_SUFFIX) + 1)); if(colName == 0) { *status = U_MEMORY_ALLOCATION_ERROR; goto finish; } uprv_strcpy(colName, outputDir); uprv_strcat(colName, basename); uprv_strcat(colName, COL_SUFFIX); } finish: uprv_free(basename); uprv_free(dirname); return colName; } static void make_col(const char *filename, UErrorCode *status) { char *basename; UCollator *coll; basename = (char*) uprv_malloc(sizeof(char) * (uprv_strlen(filename) + 1)); if(basename == 0) { *status = U_MEMORY_ALLOCATION_ERROR; return; } get_basename(basename, filename); coll = ucol_open(basename, status); if(U_FAILURE(*status)) { printf("gencol: %s for locale \"%s\"", u_errorName(*status), basename); } else { ucol_close(coll); } } #endif /* * Local Variables: * indent-tabs-mode: nil * End: */