/* Process a file */ void processFile( const char *filename, const char *cp, const char *inputDir, const char *outputDir, const char *packageName, UBool omitBinaryCollation, UErrorCode *status) { /*FileStream *in = NULL;*/ struct SRBRoot *data = NULL; UCHARBUF *ucbuf = NULL; char *rbname = NULL; char *openFileName = NULL; char *inputDirBuf = NULL; char outputFileName[256]; int32_t dirlen = 0; int32_t filelen = 0; if (status==NULL || U_FAILURE(*status)) { return; } if(filename==NULL){ *status=U_ILLEGAL_ARGUMENT_ERROR; return; }else{ filelen = (int32_t)uprv_strlen(filename); } if(inputDir == NULL) { const char *filenameBegin = uprv_strrchr(filename, U_FILE_SEP_CHAR); openFileName = (char *) uprv_malloc(dirlen + filelen + 2); openFileName[0] = '\0'; if (filenameBegin != NULL) { /* * When a filename ../../../data/root.txt is specified, * we presume that the input directory is ../../../data * This is very important when the resource file includes * another file, like UCARules.txt or thaidict.brk. */ int32_t filenameSize = (int32_t)(filenameBegin - filename + 1); inputDirBuf = uprv_strncpy((char *)uprv_malloc(filenameSize), filename, filenameSize); /* test for NULL */ if(inputDirBuf == NULL) { *status = U_MEMORY_ALLOCATION_ERROR; goto finish; } inputDirBuf[filenameSize - 1] = 0; inputDir = inputDirBuf; dirlen = (int32_t)uprv_strlen(inputDir); } }else{ dirlen = (int32_t)uprv_strlen(inputDir); if(inputDir[dirlen-1] != U_FILE_SEP_CHAR) { openFileName = (char *) uprv_malloc(dirlen + filelen + 2); /* test for NULL */ if(openFileName == NULL) { *status = U_MEMORY_ALLOCATION_ERROR; goto finish; } openFileName[0] = '\0'; /* * append the input dir to openFileName if the first char in * filename is not file seperation char and the last char input directory is not '.'. * This is to support : * genrb -s. /home/icu/data * genrb -s. icu/data * The user cannot mix notations like * genrb -s. /icu/data --- the absolute path specified. -s redundant * user should use * genrb -s. icu/data --- start from CWD and look in icu/data dir */ if( (filename[0] != U_FILE_SEP_CHAR) && (inputDir[dirlen-1] !='.')){ uprv_strcpy(openFileName, inputDir); openFileName[dirlen] = U_FILE_SEP_CHAR; } openFileName[dirlen + 1] = '\0'; } else { openFileName = (char *) uprv_malloc(dirlen + filelen + 1); /* test for NULL */ if(openFileName == NULL) { *status = U_MEMORY_ALLOCATION_ERROR; goto finish; } uprv_strcpy(openFileName, inputDir); } } uprv_strcat(openFileName, filename); ucbuf = ucbuf_open(openFileName, &cp,getShowWarning(),TRUE, status); if(*status == U_FILE_ACCESS_ERROR) { fprintf(stderr, "couldn't open file %s\n", openFileName == NULL ? filename : openFileName); goto finish; } if (ucbuf == NULL || U_FAILURE(*status)) { fprintf(stderr, "An error occurred processing file %s. Error: %s\n", openFileName == NULL ? filename : openFileName,u_errorName(*status)); goto finish; } /* auto detected popular encodings? */ if (cp!=NULL && isVerbose()) { printf("autodetected encoding %s\n", cp); } /* Parse the data into an SRBRoot */ data = parse(ucbuf, inputDir, outputDir, !omitBinaryCollation, status); if (data == NULL || U_FAILURE(*status)) { fprintf(stderr, "couldn't parse the file %s. Error:%s\n", filename,u_errorName(*status)); goto finish; } if(options[WRITE_POOL_BUNDLE].doesOccur) { int32_t newKeysLength; const char *newKeys, *newKeysLimit; bundle_compactKeys(data, status); newKeys = bundle_getKeyBytes(data, &newKeysLength); bundle_addKeyBytes(newPoolBundle, newKeys, newKeysLength, status); if(U_FAILURE(*status)) { fprintf(stderr, "bundle_compactKeys(%s) or bundle_getKeyBytes() failed: %s\n", filename, u_errorName(*status)); goto finish; } /* count the number of just-added key strings */ for(newKeysLimit = newKeys + newKeysLength; newKeys < newKeysLimit; ++newKeys) { if(*newKeys == 0) { ++newPoolBundle->fKeysCount; } } } if(options[USE_POOL_BUNDLE].doesOccur) { data->fPoolBundleKeys = poolBundle.fKeys; data->fPoolBundleKeysLength = poolBundle.fKeysLength; data->fPoolBundleKeysCount = poolBundle.fKeysCount; data->fPoolChecksum = poolBundle.fChecksum; } /* Determine the target rb filename */ rbname = make_res_filename(filename, outputDir, packageName, status); if(U_FAILURE(*status)) { fprintf(stderr, "couldn't make the res fileName for bundle %s. Error:%s\n", filename,u_errorName(*status)); goto finish; } if(write_java== TRUE){ bundle_write_java(data,outputDir,outputEnc, outputFileName, sizeof(outputFileName), options[JAVA_PACKAGE].value, options[BUNDLE_NAME].value, status); }else if(write_xliff ==TRUE){ bundle_write_xml(data,outputDir,outputEnc, filename, outputFileName, sizeof(outputFileName),language, xliffOutputFileName,status); }else{ /* Write the data to the file */ bundle_write(data, outputDir, packageName, outputFileName, sizeof(outputFileName), status); } if (U_FAILURE(*status)) { fprintf(stderr, "couldn't write bundle %s. Error:%s\n", outputFileName,u_errorName(*status)); } bundle_close(data, status); finish: if (inputDirBuf != NULL) { uprv_free(inputDirBuf); } if (openFileName != NULL) { uprv_free(openFileName); } if(ucbuf) { ucbuf_close(ucbuf); } if (rbname) { uprv_free(rbname); } }
/* open a selector. If converterListSize is 0, build for all converters. If excludedCodePoints is NULL, don't exclude any codepoints */ U_CAPI UConverterSelector* U_EXPORT2 ucnvsel_open(const char* const* converterList, int32_t converterListSize, const USet* excludedCodePoints, const UConverterUnicodeSet whichSet, UErrorCode* status) { // check if already failed if (U_FAILURE(*status)) { return NULL; } // ensure args make sense! if (converterListSize < 0 || (converterList == NULL && converterListSize != 0)) { *status = U_ILLEGAL_ARGUMENT_ERROR; return NULL; } // allocate a new converter LocalUConverterSelectorPointer newSelector( (UConverterSelector*)uprv_malloc(sizeof(UConverterSelector))); if (newSelector.isNull()) { *status = U_MEMORY_ALLOCATION_ERROR; return NULL; } uprv_memset(newSelector.getAlias(), 0, sizeof(UConverterSelector)); if (converterListSize == 0) { converterList = NULL; converterListSize = ucnv_countAvailable(); } newSelector->encodings = (char**)uprv_malloc(converterListSize * sizeof(char*)); if (!newSelector->encodings) { *status = U_MEMORY_ALLOCATION_ERROR; return NULL; } newSelector->encodings[0] = NULL; // now we can call ucnvsel_close() // make a backup copy of the list of converters int32_t totalSize = 0; int32_t i; for (i = 0; i < converterListSize; i++) { totalSize += (int32_t)uprv_strlen(converterList != NULL ? converterList[i] : ucnv_getAvailableName(i)) + 1; } // 4-align the totalSize to 4-align the size of the serialized form int32_t encodingStrPadding = totalSize & 3; if (encodingStrPadding != 0) { encodingStrPadding = 4 - encodingStrPadding; } newSelector->encodingStrLength = totalSize += encodingStrPadding; char* allStrings = (char*) uprv_malloc(totalSize); if (!allStrings) { *status = U_MEMORY_ALLOCATION_ERROR; return NULL; } for (i = 0; i < converterListSize; i++) { newSelector->encodings[i] = allStrings; uprv_strcpy(newSelector->encodings[i], converterList != NULL ? converterList[i] : ucnv_getAvailableName(i)); allStrings += uprv_strlen(newSelector->encodings[i]) + 1; } while (encodingStrPadding > 0) { *allStrings++ = 0; --encodingStrPadding; } newSelector->ownEncodingStrings = TRUE; newSelector->encodingsCount = converterListSize; UPropsVectors *upvec = upvec_open((converterListSize+31)/32, status); generateSelectorData(newSelector.getAlias(), upvec, excludedCodePoints, whichSet, status); upvec_close(upvec); if (U_FAILURE(*status)) { return NULL; } return newSelector.orphan(); }
int main(int argc, char* argv[]) { 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 = ""; int i; UBool illegalArg = FALSE; U_MAIN_INIT_ARGS(argc, argv); options[JAVA_PACKAGE].value = "com.ibm.icu.impl.data"; options[BUNDLE_NAME].value = "LocaleElements"; argc = u_parseArgs(argc, argv, (int32_t)(sizeof(options)/sizeof(options[0])), options); /* error handling, printing usage message */ if(argc<0) { fprintf(stderr, "%s: error in command line argument \"%s\"\n", argv[0], argv[-argc]); } else if(argc<2) { argc = -1; } if(options[WRITE_POOL_BUNDLE].doesOccur && options[USE_POOL_BUNDLE].doesOccur) { fprintf(stderr, "%s: cannot combine --writePoolBundle and --usePoolBundle\n", argv[0]); argc = -1; } if(options[FORMAT_VERSION].doesOccur) { const char *s = options[FORMAT_VERSION].value; if(uprv_strlen(s) != 1 || (s[0] != '1' && s[0] != '2')) { fprintf(stderr, "%s: unsupported --formatVersion %s\n", argv[0], s); argc = -1; } else if(s[0] == '1' && (options[WRITE_POOL_BUNDLE].doesOccur || options[USE_POOL_BUNDLE].doesOccur) ) { fprintf(stderr, "%s: cannot combine --formatVersion 1 with --writePoolBundle or --usePoolBundle\n", argv[0]); argc = -1; } else { setFormatVersion(s[0] - '0'); } } 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(argc<0) { illegalArg = TRUE; } else if((options[JAVA_PACKAGE].doesOccur || options[BUNDLE_NAME].doesOccur) && !options[WRITE_JAVA].doesOccur) { fprintf(stderr, "%s error: command line argument --java-package or --bundle-name " "without --write-java\n", argv[0]); illegalArg = TRUE; } if(illegalArg || options[HELP1].doesOccur || options[HELP2].doesOccur) { /* * Broken into chunks because the C89 standard says the minimum * required supported string length is 509 bytes. */ fprintf(stderr, "Usage: %s [OPTIONS] [FILES]\n" "\tReads the list of resource bundle source files and creates\n" "\tbinary version of resource bundles (.res files)\n", argv[0]); fprintf(stderr, "Options:\n" "\t-h or -? or --help this usage text\n" "\t-q or --quiet do not display warnings\n" "\t-v or --verbose print extra information when processing files\n" "\t-V or --version prints out version number and exits\n" "\t-c or --copyright include copyright notice\n"); fprintf(stderr, "\t-e or --encoding encoding of source files\n" "\t-d of --destdir destination directory, followed by the path, defaults to %s\n" "\t-s or --sourcedir source directory for files followed by path, defaults to %s\n" "\t-i or --icudatadir directory for locating any needed intermediate data files,\n" "\t followed by path, defaults to %s\n", u_getDataDirectory(), u_getDataDirectory(), u_getDataDirectory()); fprintf(stderr, "\t-j or --write-java write a Java ListResourceBundle for ICU4J, followed by optional encoding\n" "\t defaults to ASCII and \\uXXXX format.\n" "\t --java-package For --write-java: package name for writing the ListResourceBundle,\n" "\t defaults to com.ibm.icu.impl.data\n"); fprintf(stderr, "\t-b or --bundle-name For --write-java: root resource bundle name for writing the ListResourceBundle,\n" "\t defaults to LocaleElements\n" "\t-x or --write-xliff write an XLIFF file for the resource bundle. Followed by\n" "\t an optional output file name.\n" "\t-k or --strict use pedantic parsing of syntax\n" /*added by Jing*/ "\t-l or --language for XLIFF: language code compliant with BCP 47.\n"); fprintf(stderr, "\t-C or --noBinaryCollation do not generate binary collation image;\n" "\t makes .res file smaller but collator instantiation much slower;\n" "\t maintains ability to get tailoring rules\n" "\t-R or --omitCollationRules do not include collation (tailoring) rules;\n" "\t makes .res file smaller and maintains collator instantiation speed\n" "\t but tailoring rules will not be available (they are rarely used)\n"); fprintf(stderr, "\t --formatVersion write a .res file compatible with the requested formatVersion (single digit);\n" "\t for example, --formatVersion 1\n"); fprintf(stderr, "\t --writePoolBundle write a pool.res file with all of the keys of all input bundles\n" "\t --usePoolBundle [path-to-pool.res] point to keys from the pool.res keys pool bundle if they are available there;\n" "\t makes .res files smaller but dependent on the pool bundle\n" "\t (--writePoolBundle and --usePoolBundle cannot be combined)\n"); return illegalArg ? U_ILLEGAL_ARGUMENT_ERROR : U_ZERO_ERROR; } if(options[VERBOSE].doesOccur) { setVerbose(TRUE); } if(options[QUIET].doesOccur) { setShowWarning(FALSE); } if(options[STRICT].doesOccur) { setStrict(TRUE); } if(options[COPYRIGHT].doesOccur){ setIncludeCopyright(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; } if(options[ICUDATADIR].doesOccur) { u_setDataDirectory(options[ICUDATADIR].value); } /* Initialize ICU */ u_init(&status); if (U_FAILURE(status) && status != U_FILE_ACCESS_ERROR) { /* Note: u_init() will try to open ICU property data. * failures here are expected when building ICU from scratch. * ignore them. */ fprintf(stderr, "%s: can not initialize ICU. status = %s\n", argv[0], u_errorName(status)); exit(1); } status = U_ZERO_ERROR; if(options[WRITE_JAVA].doesOccur) { write_java = TRUE; outputEnc = options[WRITE_JAVA].value; } if(options[WRITE_XLIFF].doesOccur) { write_xliff = TRUE; if(options[WRITE_XLIFF].value != NULL){ xliffOutputFileName = options[WRITE_XLIFF].value; } } initParser(options[NO_COLLATION_RULES].doesOccur); /*added by Jing*/ if(options[LANGUAGE].doesOccur) { language = options[LANGUAGE].value; } if(options[WRITE_POOL_BUNDLE].doesOccur) { newPoolBundle = bundle_open(NULL, TRUE, &status); if(U_FAILURE(status)) { fprintf(stderr, "unable to create an empty bundle for the pool keys: %s\n", u_errorName(status)); return status; } else { const char *poolResName = "pool.res"; char *nameWithoutSuffix = uprv_malloc(uprv_strlen(poolResName) + 1); if (nameWithoutSuffix == NULL) { fprintf(stderr, "out of memory error\n"); return U_MEMORY_ALLOCATION_ERROR; } uprv_strcpy(nameWithoutSuffix, poolResName); *uprv_strrchr(nameWithoutSuffix, '.') = 0; newPoolBundle->fLocale = nameWithoutSuffix; } } if(options[USE_POOL_BUNDLE].doesOccur) { const char *poolResName = "pool.res"; FileStream *poolFile; int32_t poolFileSize; int32_t indexLength; /* * TODO: Consolidate inputDir/filename handling from main() and processFile() * into a common function, and use it here as well. * Try to create toolutil functions for dealing with dir/filenames and * loading ICU data files without udata_open(). * Share code with icupkg? * Also, make_res_filename() seems to be unused. Review and remove. */ if (options[USE_POOL_BUNDLE].value!=NULL) { uprv_strcpy(theCurrentFileName, options[USE_POOL_BUNDLE].value); uprv_strcat(theCurrentFileName, U_FILE_SEP_STRING); } else if (inputDir) { uprv_strcpy(theCurrentFileName, inputDir); uprv_strcat(theCurrentFileName, U_FILE_SEP_STRING); } else { *theCurrentFileName = 0; } uprv_strcat(theCurrentFileName, poolResName); poolFile = T_FileStream_open(theCurrentFileName, "rb"); if (poolFile == NULL) { fprintf(stderr, "unable to open pool bundle file %s\n", theCurrentFileName); return 1; } poolFileSize = T_FileStream_size(poolFile); if (poolFileSize < 32) { fprintf(stderr, "the pool bundle file %s is too small\n", theCurrentFileName); return 1; } poolBundle.fBytes = (uint8_t *)uprv_malloc((poolFileSize + 15) & ~15); if (poolFileSize > 0 && poolBundle.fBytes == NULL) { fprintf(stderr, "unable to allocate memory for the pool bundle file %s\n", theCurrentFileName); return U_MEMORY_ALLOCATION_ERROR; } else { UDataSwapper *ds; const DataHeader *header; int32_t bytesRead = T_FileStream_read(poolFile, poolBundle.fBytes, poolFileSize); int32_t keysBottom; if (bytesRead != poolFileSize) { fprintf(stderr, "unable to read the pool bundle file %s\n", theCurrentFileName); return 1; } /* * Swap the pool bundle so that a single checked-in file can be used. * The swapper functions also test that the data looks like * a well-formed .res file. */ ds = udata_openSwapperForInputData(poolBundle.fBytes, bytesRead, U_IS_BIG_ENDIAN, U_CHARSET_FAMILY, &status); if (U_FAILURE(status)) { fprintf(stderr, "udata_openSwapperForInputData(pool bundle %s) failed: %s\n", theCurrentFileName, u_errorName(status)); return status; } ures_swap(ds, poolBundle.fBytes, bytesRead, poolBundle.fBytes, &status); udata_closeSwapper(ds); if (U_FAILURE(status)) { fprintf(stderr, "ures_swap(pool bundle %s) failed: %s\n", theCurrentFileName, u_errorName(status)); return status; } header = (const DataHeader *)poolBundle.fBytes; if (header->info.formatVersion[0]!=2) { fprintf(stderr, "invalid format of pool bundle file %s\n", theCurrentFileName); return U_INVALID_FORMAT_ERROR; } poolBundle.fKeys = (const char *)header + header->dataHeader.headerSize; poolBundle.fIndexes = (const int32_t *)poolBundle.fKeys + 1; indexLength = poolBundle.fIndexes[URES_INDEX_LENGTH] & 0xff; if (indexLength <= URES_INDEX_POOL_CHECKSUM) { fprintf(stderr, "insufficient indexes[] in pool bundle file %s\n", theCurrentFileName); return U_INVALID_FORMAT_ERROR; } keysBottom = (1 + indexLength) * 4; poolBundle.fKeys += keysBottom; poolBundle.fKeysLength = (poolBundle.fIndexes[URES_INDEX_KEYS_TOP] * 4) - keysBottom; poolBundle.fChecksum = poolBundle.fIndexes[URES_INDEX_POOL_CHECKSUM]; } for (i = 0; i < poolBundle.fKeysLength; ++i) { if (poolBundle.fKeys[i] == 0) { ++poolBundle.fKeysCount; } } T_FileStream_close(poolFile); setUsePoolBundle(TRUE); } if(options[INCLUDE_UNIHAN_COLL].doesOccur) { gIncludeUnihanColl = TRUE; } if((argc-1)!=1) { printf("genrb number of files: %d\n", argc - 1); } /* generate the binary files */ for(i = 1; i < argc; ++i) { status = U_ZERO_ERROR; arg = getLongPathname(argv[i]); if (inputDir) { uprv_strcpy(theCurrentFileName, inputDir); uprv_strcat(theCurrentFileName, U_FILE_SEP_STRING); } else { *theCurrentFileName = 0; } uprv_strcat(theCurrentFileName, arg); if (isVerbose()) { printf("Processing file \"%s\"\n", theCurrentFileName); } processFile(arg, encoding, inputDir, outputDir, NULL, options[NO_BINARY_COLLATION].doesOccur, &status); } uprv_free(poolBundle.fBytes); if(options[WRITE_POOL_BUNDLE].doesOccur) { char outputFileName[256]; bundle_write(newPoolBundle, outputDir, NULL, outputFileName, sizeof(outputFileName), &status); bundle_close(newPoolBundle, &status); if(U_FAILURE(status)) { fprintf(stderr, "unable to write the pool bundle: %s\n", u_errorName(status)); } } u_cleanup(); /* Dont return warnings as a failure */ if (U_SUCCESS(status)) { return 0; } return status; }
TimeZoneNamesDelegate::TimeZoneNamesDelegate(const Locale& locale, UErrorCode& status) { Mutex lock(&gTimeZoneNamesLock); if (!gTimeZoneNamesCacheInitialized) { // Create empty hashtable if it is not already initialized. gTimeZoneNamesCache = uhash_open(uhash_hashChars, uhash_compareChars, NULL, &status); if (U_SUCCESS(status)) { uhash_setKeyDeleter(gTimeZoneNamesCache, uprv_free); uhash_setValueDeleter(gTimeZoneNamesCache, deleteTimeZoneNamesCacheEntry); gTimeZoneNamesCacheInitialized = TRUE; ucln_i18n_registerCleanup(UCLN_I18N_TIMEZONENAMES, timeZoneNames_cleanup); } } if (U_FAILURE(status)) { return; } // Check the cache, if not available, create new one and cache TimeZoneNamesCacheEntry *cacheEntry = NULL; const char *key = locale.getName(); cacheEntry = (TimeZoneNamesCacheEntry *)uhash_get(gTimeZoneNamesCache, key); if (cacheEntry == NULL) { TimeZoneNames *tznames = NULL; char *newKey = NULL; tznames = new TimeZoneNamesImpl(locale, status); if (tznames == NULL) { status = U_MEMORY_ALLOCATION_ERROR; } if (U_SUCCESS(status)) { newKey = (char *)uprv_malloc(uprv_strlen(key) + 1); if (newKey == NULL) { status = U_MEMORY_ALLOCATION_ERROR; } else { uprv_strcpy(newKey, key); } } if (U_SUCCESS(status)) { cacheEntry = (TimeZoneNamesCacheEntry *)uprv_malloc(sizeof(TimeZoneNamesCacheEntry)); if (cacheEntry == NULL) { status = U_MEMORY_ALLOCATION_ERROR; } else { cacheEntry->names = tznames; cacheEntry->refCount = 1; cacheEntry->lastAccess = (double)uprv_getUTCtime(); uhash_put(gTimeZoneNamesCache, newKey, cacheEntry, &status); } } if (U_FAILURE(status)) { if (tznames != NULL) { delete tznames; } if (newKey != NULL) { uprv_free(newKey); } if (cacheEntry != NULL) { uprv_free(cacheEntry); } cacheEntry = NULL; } } else { // Update the reference count cacheEntry->refCount++; cacheEntry->lastAccess = (double)uprv_getUTCtime(); } gAccessCount++; if (gAccessCount >= SWEEP_INTERVAL) { // sweep sweepCache(); gAccessCount = 0; } fTZnamesCacheEntry = cacheEntry; }
MeasureUnit::MeasureUnit(const MeasureUnit &other) : fTypeId(other.fTypeId), fSubTypeId(other.fSubTypeId) { uprv_strcpy(fCurrency, other.fCurrency); }
TimeZoneGenericNames* TimeZoneGenericNames::createInstance(const Locale& locale, UErrorCode& status) { if (U_FAILURE(status)) { return NULL; } TimeZoneGenericNames* instance = new TimeZoneGenericNames(); if (instance == NULL) { status = U_MEMORY_ALLOCATION_ERROR; return NULL; } TZGNCoreRef *cacheEntry = NULL; { Mutex lock(&gTZGNLock); if (!gTZGNCoreCacheInitialized) { // Create empty hashtable gTZGNCoreCache = uhash_open(uhash_hashChars, uhash_compareChars, NULL, &status); if (U_SUCCESS(status)) { uhash_setKeyDeleter(gTZGNCoreCache, uprv_free); uhash_setValueDeleter(gTZGNCoreCache, deleteTZGNCoreRef); gTZGNCoreCacheInitialized = TRUE; ucln_i18n_registerCleanup(UCLN_I18N_TIMEZONEGENERICNAMES, tzgnCore_cleanup); } } if (U_FAILURE(status)) { return NULL; } // Check the cache, if not available, create new one and cache const char *key = locale.getName(); cacheEntry = (TZGNCoreRef *)uhash_get(gTZGNCoreCache, key); if (cacheEntry == NULL) { TZGNCore *tzgnCore = NULL; char *newKey = NULL; tzgnCore = new TZGNCore(locale, status); if (tzgnCore == NULL) { status = U_MEMORY_ALLOCATION_ERROR; } if (U_SUCCESS(status)) { newKey = (char *)uprv_malloc(uprv_strlen(key) + 1); if (newKey == NULL) { status = U_MEMORY_ALLOCATION_ERROR; } else { uprv_strcpy(newKey, key); } } if (U_SUCCESS(status)) { cacheEntry = (TZGNCoreRef *)uprv_malloc(sizeof(TZGNCoreRef)); if (cacheEntry == NULL) { status = U_MEMORY_ALLOCATION_ERROR; } else { cacheEntry->obj = tzgnCore; cacheEntry->refCount = 1; cacheEntry->lastAccess = (double)uprv_getUTCtime(); uhash_put(gTZGNCoreCache, newKey, cacheEntry, &status); } } if (U_FAILURE(status)) { if (tzgnCore != NULL) { delete tzgnCore; } if (newKey != NULL) { uprv_free(newKey); } if (cacheEntry != NULL) { uprv_free(cacheEntry); } cacheEntry = NULL; } } else { // Update the reference count cacheEntry->refCount++; cacheEntry->lastAccess = (double)uprv_getUTCtime(); } gAccessCount++; if (gAccessCount >= SWEEP_INTERVAL) { // sweep sweepCache(); gAccessCount = 0; } } // End of mutex locked block if (cacheEntry == NULL) { delete instance; return NULL; } instance->fRef = cacheEntry; return instance; }
UBool ResourceBundleTest::testTag(const char* frag, UBool in_Root, UBool in_te, UBool in_te_IN) { int32_t failOrig = fail; // Make array from input params UBool is_in[] = { in_Root, in_te, in_te_IN }; const char* NAME[] = { "ROOT", "TE", "TE_IN" }; // Now try to load the desired items char tag[100]; UnicodeString action; int32_t i,j,actual_bundle; // int32_t row,col; int32_t index; UErrorCode status = U_ZERO_ERROR; const char* testdatapath; testdatapath=loadTestData(status); if(U_FAILURE(status)) { dataerrln("Could not load testdata.dat %s " + UnicodeString(u_errorName(status))); return FALSE; } for (i=0; i<bundles_count; ++i) { action = "Constructor for "; action += param[i].name; status = U_ZERO_ERROR; ResourceBundle theBundle( testdatapath, *param[i].locale, status); //ResourceBundle theBundle( "c:\\icu\\icu\\source\\test\\testdata\\testdata", *param[i].locale, status); CONFIRM_UErrorCode(status, param[i].expected_constructor_status, action); if(i == 5) actual_bundle = 0; /* ne -> default */ else if(i == 3) actual_bundle = 1; /* te_NE -> te */ else if(i == 4) actual_bundle = 2; /* te_IN_NE -> te_IN */ else actual_bundle = i; UErrorCode expected_resource_status = U_MISSING_RESOURCE_ERROR; for (j=e_te_IN; j>=e_Root; --j) { if (is_in[j] && param[i].inherits[j]) { if(j == actual_bundle) /* it's in the same bundle OR it's a nonexistent=default bundle (5) */ expected_resource_status = U_ZERO_ERROR; else if(j == 0) expected_resource_status = U_USING_DEFAULT_WARNING; else expected_resource_status = U_USING_FALLBACK_WARNING; break; } } UErrorCode expected_status; UnicodeString base; for (j=param[i].where; j>=0; --j) { if (is_in[j]) { base = NAME[j]; break; } } //-------------------------------------------------------------------------- // string uprv_strcpy(tag, "string_"); uprv_strcat(tag, frag); action = param[i].name; action += ".getString("; action += tag; action += ")"; status = U_ZERO_ERROR; UnicodeString string(theBundle.getStringEx(tag, status)); if(U_FAILURE(status)) { string.setTo(TRUE, kErrorUChars, kErrorLength); } CONFIRM_UErrorCode(status, expected_resource_status, action); UnicodeString expected_string(kErrorUChars); if (U_SUCCESS(status)) { expected_string = base; } CONFIRM_EQ(string, expected_string, action); //-------------------------------------------------------------------------- // array uprv_strcpy(tag, "array_"); uprv_strcat(tag, frag); action = param[i].name; action += ".get("; action += tag; action += ")"; status = U_ZERO_ERROR; ResourceBundle arrayBundle(theBundle.get(tag, status)); CONFIRM_UErrorCode(status, expected_resource_status, action); int32_t count = arrayBundle.getSize(); if (U_SUCCESS(status)) { CONFIRM_GE(count, 1, action); for (j=0; j < count; ++j) { char buf[32]; UnicodeString value(arrayBundle.getStringEx(j, status)); expected_string = base; expected_string += itoa(j,buf); CONFIRM_EQ(value, expected_string, action); } action = param[i].name; action += ".getStringEx("; action += tag; action += ")"; for (j=0; j<100; ++j) { index = count ? (randi(count * 3) - count) : (randi(200) - 100); status = U_ZERO_ERROR; string = kErrorUChars; UnicodeString t(arrayBundle.getStringEx(index, status)); expected_status = (index >= 0 && index < count) ? expected_resource_status : U_MISSING_RESOURCE_ERROR; CONFIRM_UErrorCode(status, expected_status, action); if (U_SUCCESS(status)) { char buf[32]; expected_string = base; expected_string += itoa(index,buf); } else { expected_string = kErrorUChars; } CONFIRM_EQ(string, expected_string, action); } } else if (status != expected_resource_status) { record_fail("Error getting " + (UnicodeString)tag); return (UBool)(failOrig != fail); } } return (UBool)(failOrig != fail); }
static void addFile(const char *filename, UBool sourceTOC, UBool verbose) { char *s; uint32_t length; char *fullPath = NULL; if(fileCount==MAX_FILE_COUNT) { fprintf(stderr, "gencmn: too many files, maximum is %d\n", MAX_FILE_COUNT); exit(U_BUFFER_OVERFLOW_ERROR); } if(!sourceTOC) { FileStream *file; if(uprv_pathIsAbsolute(filename)) { 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); exit(U_ILLEGAL_ARGUMENT_ERROR); } fullPath = pathToFullPath(filename); /* store the pathname */ length = (uint32_t)(uprv_strlen(filename) + 1 + uprv_strlen(options[6].value) + 1); s=allocString(length); uprv_strcpy(s, options[6].value); uprv_strcat(s, U_TREE_ENTRY_SEP_STRING); uprv_strcat(s, filename); /* get the basename */ fixDirToTreePath(s); files[fileCount].basename=s; files[fileCount].basenameLength=length; files[fileCount].pathname=fullPath; basenameTotal+=length; /* try to open the file */ file=T_FileStream_open(fullPath, "rb"); if(file==NULL) { fprintf(stderr, "gencmn: unable to open listed file %s\n", fullPath); exit(U_FILE_ACCESS_ERROR); } /* get the file length */ length=T_FileStream_size(file); if(T_FileStream_error(file) || length<=20) { fprintf(stderr, "gencmn: unable to get length of listed file %s\n", fullPath); exit(U_FILE_ACCESS_ERROR); } T_FileStream_close(file); /* do not add files that are longer than maxSize */ if(maxSize && length>maxSize) { if (verbose) { printf("%s ignored (size %ld > %ld)\n", fullPath, (long)length, (long)maxSize); } return; } files[fileCount].fileSize=length; } else { char *t; /* get and store the basename */ /* need to include the package name */ length = (uint32_t)(uprv_strlen(filename) + 1 + uprv_strlen(options[6].value) + 1); s=allocString(length); uprv_strcpy(s, options[6].value); uprv_strcat(s, U_TREE_ENTRY_SEP_STRING); uprv_strcat(s, filename); fixDirToTreePath(s); files[fileCount].basename=s; /* turn the basename into an entry point name and store in the pathname field */ t=files[fileCount].pathname=allocString(length); while(--length>0) { if(*s=='.' || *s=='-' || *s=='/') { *t='_'; } else { *t=*s; } ++s; ++t; } *t=0; } ++fileCount; }
static void TestFileStream(void){ int32_t c = 0; int32_t c1=0; UErrorCode status = U_ZERO_ERROR; const char* testdatapath = loadTestData(&status); char* fileName = (char*) malloc(uprv_strlen(testdatapath) +10); FileStream* stream = NULL; /* these should not be closed */ FileStream* pStdin = T_FileStream_stdin(); FileStream* pStdout = T_FileStream_stdout(); FileStream* pStderr = T_FileStream_stderr(); const char* testline = "This is a test line"; int32_t bufLen = (int32_t)strlen(testline)+10; char* buf = (char*) malloc(bufLen); int32_t retLen = 0; if(pStdin==NULL){ log_err("failed to get T_FileStream_stdin()"); } if(pStdout==NULL){ log_err("failed to get T_FileStream_stdout()"); } if(pStderr==NULL){ log_err("failed to get T_FileStream_stderr()"); } uprv_strcpy(fileName,testdatapath); uprv_strcat(fileName,".dat"); stream = T_FileStream_open(fileName, "r"); if(stream==NULL){ log_data_err("T_FileStream_open failed to open %s\n",fileName); } else { if(!T_FileStream_file_exists(fileName)){ log_data_err("T_FileStream_file_exists failed to verify existence of %s \n",fileName); } retLen=T_FileStream_read(stream,&c,1); if(retLen==0){ log_data_err("T_FileStream_read failed to read from %s \n",fileName); } retLen=0; T_FileStream_rewind(stream); T_FileStream_read(stream,&c1,1); if(c!=c1){ log_data_err("T_FileStream_rewind failed to rewind %s \n",fileName); } T_FileStream_rewind(stream); c1 = T_FileStream_peek(stream); if(c!=c1){ log_data_err("T_FileStream_peek failed to peekd %s \n",fileName); } c = T_FileStream_getc(stream); T_FileStream_ungetc(c,stream); if(c!= T_FileStream_getc(stream)){ log_data_err("T_FileStream_ungetc failed to d %s \n",fileName); } if(T_FileStream_size(stream)<=0){ log_data_err("T_FileStream_size failed to d %s \n",fileName); } if(T_FileStream_error(stream)){ log_data_err("T_FileStream_error shouldn't have an error %s\n",fileName); } if(!T_FileStream_error(NULL)){ log_err("T_FileStream_error didn't get an error %s\n",fileName); } T_FileStream_putc(stream, 0x20); if(!T_FileStream_error(stream)){ /* Warning writing to a read-only file may not consistently fail on all platforms (e.g. HP-UX, FreeBSD, MacOSX) */ log_verbose("T_FileStream_error didn't get an error when writing to a readonly file %s\n",fileName); } T_FileStream_close(stream); } /* test writing function */ stream=NULL; uprv_strcpy(fileName,testdatapath); uprv_strcat(fileName,".tmp"); stream = T_FileStream_open(fileName,"w+"); if(stream == NULL){ log_data_err("Could not open %s for writing\n",fileName); } else { c= '$'; T_FileStream_putc(stream,c); T_FileStream_rewind(stream); if(c != T_FileStream_getc(stream)){ log_data_err("T_FileStream_putc failed %s\n",fileName); } T_FileStream_rewind(stream); T_FileStream_writeLine(stream,testline); T_FileStream_rewind(stream); T_FileStream_readLine(stream,buf,bufLen); if(uprv_strncmp(testline, buf,uprv_strlen(buf))!=0){ log_data_err("T_FileStream_writeLine failed %s\n",fileName); } T_FileStream_rewind(stream); T_FileStream_write(stream,testline,(int32_t)strlen(testline)); T_FileStream_rewind(stream); retLen = T_FileStream_read(stream, buf, bufLen); if(uprv_strncmp(testline, buf,retLen)!=0){ log_data_err("T_FileStream_write failed %s\n",fileName); } T_FileStream_close(stream); } if(!T_FileStream_remove(fileName)){ log_data_err("T_FileStream_remove failed to delete %s\n",fileName); } free(fileName); free(buf); }
void pkg_sttc_writeReadme(struct UPKGOptions_ *o, const char *libName, UErrorCode *status) { char tmp[1024]; FileStream *out; if(U_FAILURE(*status)) { return; } /* Makefile pathname */ uprv_strcpy(tmp, o->targetDir); uprv_strcat(tmp, U_FILE_SEP_STRING "README_"); uprv_strcat(tmp, o->shortName); uprv_strcat(tmp, ".txt"); out = T_FileStream_open(tmp, "w"); if (!out) { fprintf(stderr, "err: couldn't create README file %s\n", tmp); *status = U_FILE_ACCESS_ERROR; return; } sprintf(tmp, "## README for \"%s\"'s static data (%s)\n" "## created by pkgdata, ICU Version %s\n", o->shortName, libName, U_ICU_VERSION); T_FileStream_writeLine(out, tmp); sprintf(tmp, "\n\nTo use this data in your application:\n\n" "1. At the top of your source file, add the following lines:\n" "\n" " #include \"unicode/utypes.h\"\n" " #include \"unicode/udata.h\"\n" " U_CFUNC char %s_dat[];\n", o->cShortName); T_FileStream_writeLine(out, tmp); sprintf(tmp, "2. *Early* in your application, call the following function:\n" "\n" " UErrorCode myError = U_ZERO_ERROR;\n" " udata_setAppData( \"%s\", (const void*) %s_dat, &myError);\n" " if(U_FAILURE(myError))\n" " {\n" " handle error condition ...\n" " }\n" "\n", o->cShortName, o->cShortName); T_FileStream_writeLine(out, tmp); sprintf(tmp, "3. Link your application against %s\n" "\n\n" "4. Now, you may access this data with a 'path' of \"%s\" as in the following example:\n" "\n" " ... ures_open( \"%s\", NULL /* Get the default locale */, &err ); \n", libName, o->shortName, o->shortName); T_FileStream_writeLine(out, tmp); T_FileStream_close(out); }
extern int main(int argc, char* argv[]) { static char buffer[4096]; char line[512]; FileStream *in, *file; char *s; UErrorCode errorCode=U_ZERO_ERROR; uint32_t i, fileOffset, basenameOffset, length, nread; UBool sourceTOC, verbose; const char *entrypointName = NULL; U_MAIN_INIT_ARGS(argc, argv); /* preset then read command line options */ options[4].value=u_getDataDirectory(); options[6].value=COMMON_DATA_NAME; options[7].value=DATA_TYPE; options[10].value="."; 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[0].doesOccur || options[1].doesOccur) { FILE *where = argc < 0 ? stderr : stdout; /* * Broken into chucks because the C89 standard says the minimum * required supported string length is 509 bytes. */ fprintf(where, "%csage: %s [ -h, -?, --help ] [ -v, --verbose ] [ -c, --copyright ] [ -C, --comment comment ] [ -d, --destdir dir ] [ -n, --name filename ] [ -t, --type filetype ] [ -S, --source tocfile ] [ -e, --entrypoint name ] maxsize listfile\n", argc < 0 ? 'u' : 'U', *argv); if (options[0].doesOccur || options[1].doesOccur) { fprintf(where, "\n" "Read the list file (default: standard input) and create a common data\n" "file from specified files. Omit any files larger than maxsize, if maxsize > 0.\n"); fprintf(where, "\n" "Options:\n" "\t-h, -?, --help this usage text\n" "\t-v, --verbose verbose output\n" "\t-c, --copyright include the ICU copyright notice\n" "\t-C, --comment comment include a comment string\n" "\t-d, --destdir dir destination directory\n"); fprintf(where, "\t-n, --name filename output filename, without .type extension\n" "\t (default: " COMMON_DATA_NAME ")\n" "\t-t, --type filetype type of the destination file\n" "\t (default: \"" DATA_TYPE "\")\n" "\t-S, --source tocfile write a .c source file with the table of\n" "\t contents\n" "\t-e, --entrypoint name override the c entrypoint name\n" "\t (default: \"<name>_<type>\")\n"); } return argc<0 ? U_ILLEGAL_ARGUMENT_ERROR : U_ZERO_ERROR; } sourceTOC=options[8].doesOccur; verbose = options[2].doesOccur; maxSize=(uint32_t)uprv_strtoul(argv[1], NULL, 0); if(argc==2) { in=T_FileStream_stdin(); } else { in=T_FileStream_open(argv[2], "r"); if(in==NULL) { fprintf(stderr, "gencmn: unable to open input file %s\n", argv[2]); exit(U_FILE_ACCESS_ERROR); } } if (verbose) { if(sourceTOC) { printf("generating %s_%s.c (table of contents source file)\n", options[6].value, options[7].value); } else { printf("generating %s.%s (common data file with table of contents)\n", options[6].value, options[7].value); } } /* read the list of files and get their lengths */ while(T_FileStream_readLine(in, line, sizeof(line))!=NULL) { /* remove trailing newline characters */ s=line; while(*s!=0) { if(*s=='\r' || *s=='\n') { *s=0; break; } ++s; } /* check for comment */ if (*line == '#') { continue; } /* add the file */ #if (U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR) { char *t; while((t = uprv_strchr(line,U_FILE_ALT_SEP_CHAR))) { *t = U_FILE_SEP_CHAR; } } #endif addFile(getLongPathname(line), sourceTOC, verbose); } if(in!=T_FileStream_stdin()) { T_FileStream_close(in); } if(fileCount==0) { fprintf(stderr, "gencmn: no files listed in %s\n", argc==2 ? "<stdin>" : argv[2]); return 0; } /* sort the files by basename */ qsort(files, fileCount, sizeof(File), compareFiles); if(!sourceTOC) { UNewDataMemory *out; /* determine the offsets of all basenames and files in this common one */ basenameOffset=4+8*fileCount; fileOffset=(basenameOffset+(basenameTotal+15))&~0xf; for(i=0; i<fileCount; ++i) { files[i].fileOffset=fileOffset; fileOffset+=(files[i].fileSize+15)&~0xf; files[i].basenameOffset=basenameOffset; basenameOffset+=files[i].basenameLength; } /* create the output file */ out=udata_create(options[4].value, options[7].value, options[6].value, &dataInfo, options[3].doesOccur ? U_COPYRIGHT_STRING : options[5].value, &errorCode); if(U_FAILURE(errorCode)) { fprintf(stderr, "gencmn: udata_create(-d %s -n %s -t %s) failed - %s\n", options[4].value, options[6].value, options[7].value, u_errorName(errorCode)); exit(errorCode); } /* write the table of contents */ udata_write32(out, fileCount); for(i=0; i<fileCount; ++i) { udata_write32(out, files[i].basenameOffset); udata_write32(out, files[i].fileOffset); } /* write the basenames */ for(i=0; i<fileCount; ++i) { udata_writeString(out, files[i].basename, files[i].basenameLength); } length=4+8*fileCount+basenameTotal; /* copy the files */ for(i=0; i<fileCount; ++i) { /* pad to 16-align the next file */ length&=0xf; if(length!=0) { udata_writePadding(out, 16-length); } if (verbose) { printf("adding %s (%ld byte%s)\n", files[i].pathname, (long)files[i].fileSize, files[i].fileSize == 1 ? "" : "s"); } /* copy the next file */ file=T_FileStream_open(files[i].pathname, "rb"); if(file==NULL) { fprintf(stderr, "gencmn: unable to open listed file %s\n", files[i].pathname); exit(U_FILE_ACCESS_ERROR); } for(nread = 0;;) { length=T_FileStream_read(file, buffer, sizeof(buffer)); if(length <= 0) { break; } nread += length; udata_writeBlock(out, buffer, length); } T_FileStream_close(file); length=files[i].fileSize; if (nread != files[i].fileSize) { 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"); exit(U_FILE_ACCESS_ERROR); } } /* pad to 16-align the last file (cleaner, avoids growing .dat files in icuswap) */ length&=0xf; if(length!=0) { udata_writePadding(out, 16-length); } /* finish */ udata_finish(out, &errorCode); if(U_FAILURE(errorCode)) { fprintf(stderr, "gencmn: udata_finish() failed - %s\n", u_errorName(errorCode)); exit(errorCode); } } else { /* write a .c source file with the table of contents */ char *filename; FileStream *out; /* create the output filename */ filename=s=buffer; uprv_strcpy(filename, options[4].value); s=filename+uprv_strlen(filename); if(s>filename && *(s-1)!=U_FILE_SEP_CHAR) { *s++=U_FILE_SEP_CHAR; } uprv_strcpy(s, options[6].value); if(*(options[7].value)!=0) { s+=uprv_strlen(s); *s++='_'; uprv_strcpy(s, options[7].value); } s+=uprv_strlen(s); uprv_strcpy(s, ".c"); /* open the output file */ out=T_FileStream_open(filename, "w"); if(out==NULL) { fprintf(stderr, "gencmn: unable to open .c output file %s\n", filename); exit(U_FILE_ACCESS_ERROR); } /* If an entrypoint is specified, use it. */ if(options[9].doesOccur) { entrypointName = options[9].value; } else { entrypointName = options[6].value; } /* write the source file */ sprintf(buffer, "/*\n" " * ICU common data table of contents for %s.%s ,\n" " * Automatically generated by icu/source/tools/gencmn/gencmn .\n" " */\n\n" "#include \"unicode/utypes.h\"\n" "#include \"unicode/udata.h\"\n" "\n" "/* external symbol declarations for data */\n", options[6].value, options[7].value); T_FileStream_writeLine(out, buffer); sprintf(buffer, "extern const char\n %s%s[]", symPrefix?symPrefix:"", files[0].pathname); T_FileStream_writeLine(out, buffer); for(i=1; i<fileCount; ++i) { sprintf(buffer, ",\n %s%s[]", symPrefix?symPrefix:"", files[i].pathname); T_FileStream_writeLine(out, buffer); } T_FileStream_writeLine(out, ";\n\n"); sprintf( buffer, "U_EXPORT struct {\n" " uint16_t headerSize;\n" " uint8_t magic1, magic2;\n" " UDataInfo info;\n" " char padding[%lu];\n" " uint32_t count, reserved;\n" " struct {\n" " const char *name;\n" " const void *data;\n" " } toc[%lu];\n" "} U_EXPORT2 %s_dat = {\n" " 32, 0xda, 0x27, {\n" " %lu, 0,\n" " %u, %u, %u, 0,\n" " {0x54, 0x6f, 0x43, 0x50},\n" " {1, 0, 0, 0},\n" " {0, 0, 0, 0}\n" " },\n" " \"\", %lu, 0, {\n", (unsigned long)32-4-sizeof(UDataInfo), (unsigned long)fileCount, entrypointName, (unsigned long)sizeof(UDataInfo), U_IS_BIG_ENDIAN, U_CHARSET_FAMILY, U_SIZEOF_UCHAR, (unsigned long)fileCount ); T_FileStream_writeLine(out, buffer); sprintf(buffer, " { \"%s\", %s%s }", files[0].basename, symPrefix?symPrefix:"", files[0].pathname); T_FileStream_writeLine(out, buffer); for(i=1; i<fileCount; ++i) { sprintf(buffer, ",\n { \"%s\", %s%s }", files[i].basename, symPrefix?symPrefix:"", files[i].pathname); T_FileStream_writeLine(out, buffer); } T_FileStream_writeLine(out, "\n }\n};\n"); T_FileStream_close(out); uprv_free(symPrefix); } return 0; }
void pkg_mode_static(UPKGOptions *o, FileStream *makefile, UErrorCode *status) { char tmp[1024]; CharList *tail = NULL; CharList *objects = NULL; if(U_FAILURE(*status)) { return; } uprv_strcpy(tmp, LIB_STATIC_PREFIX); uprv_strcat(tmp, o->libName); uprv_strcat(tmp, UDATA_LIB_SUFFIX); o->outFiles = pkg_appendToList(o->outFiles, &tail, uprv_strdup(tmp)); if (!o->quiet) { pkg_sttc_writeReadme(o, tmp, status); } if(U_FAILURE(*status)) { return; } if(o->nooutput || o->verbose) { fprintf(stdout, "# Output file: %s%s%s\n", o->targetDir, U_FILE_SEP_STRING, tmp); } if(o->nooutput) { *status = U_ZERO_ERROR; return; } /* begin writing makefile ========================= */ T_FileStream_writeLine(makefile, "# Version numbers:\nVERSIONED="); if (o->version) { sprintf(tmp, ".%s", o->version); if (!uprv_strchr(o->version, '.')) { uprv_strcat(tmp, ".0"); } T_FileStream_writeLine(makefile, tmp); T_FileStream_writeLine(makefile, "\nDLL_LDFLAGS=$(LD_SONAME) $(RPATH_LDFLAGS)\n"); } else { T_FileStream_writeLine(makefile, "\nDLL_LDFLAGS=$(BIR_LDFLAGS)\n"); } T_FileStream_writeLine(makefile, "\n"); sprintf(tmp, "# File to make:\nTARGET=%s\n\n", o->outFiles->str); T_FileStream_writeLine(makefile, tmp); T_FileStream_writeLine(makefile, "LIB_TARGET=$(TARGET)\n"); uprv_strcpy(tmp, "all: $(TARG_PATH)$(LIB_TARGET)"); uprv_strcat(tmp, "\n\n"); T_FileStream_writeLine(makefile, tmp); #ifdef OS400 /* New for iSeries: All packaged data in one .c */ sprintf(tmp, "# Create a file which contains all .c data files/structures\n" "$(TEMP_DIR)/$(NAME)all.c: $(CMNLIST)\n\n"); T_FileStream_writeLine(makefile, tmp); #endif /* Write compile rules */ pkg_mak_writeObjRules(o, makefile, &objects, ".$(STATIC_O)"); /* use special .o suffix */ sprintf(tmp, "# List file for gencmn:\n" "CMNLIST=%s%s$(NAME)_static.lst\n\n", o->tmpDir, U_FILE_SEP_STRING); T_FileStream_writeLine(makefile, tmp); if(o->hadStdin == FALSE) { /* shortcut */ T_FileStream_writeLine(makefile, "$(CMNLIST): $(LISTFILES)\n" "\tcat $(LISTFILES) > $(CMNLIST)\n\n"); } else { T_FileStream_writeLine(makefile, "$(CMNLIST): \n" "\t@echo \"generating $@ (list of data files)\"\n" "\t@-$(RMV) $@\n" "\t@for file in $(DATAFILEPATHS); do \\\n" "\t echo $$file >> $@; \\\n" "\tdone;\n\n"); } pkg_mak_writeAssemblyHeader(makefile, o); sprintf(tmp,"$(TEMP_PATH)$(NAME)_dat.$(STATIC_O) : $(TEMP_PATH)$(NAME)_dat.c\n" "\t$(COMPILE.c) -o $@ $<\n\n"); T_FileStream_writeLine(makefile, tmp); T_FileStream_writeLine(makefile, "# 'TOCOBJ' contains C Table of Contents objects [if any]\n"); sprintf(tmp, "$(TEMP_PATH)$(NAME)_dat.c: $(CMNLIST)\n" "\t$(INVOKE) $(GENCMN) -e $(ENTRYPOINT) -n $(NAME) -S -s $(SRCDIR) -d $(TEMP_DIR) 0 $(CMNLIST)\n\n"); T_FileStream_writeLine(makefile, tmp); sprintf(tmp, "TOCOBJ= $(NAME)_dat.$(STATIC_O)\n\n"); T_FileStream_writeLine(makefile, tmp); #ifdef OS400 /* New for iSeries: All packaged data in one .c */ sprintf(tmp,"$(TEMP_PATH)$(NAME)all.$(STATIC_O) : $(TEMP_PATH)$(NAME)all.c\n" "\t$(COMPILE.c) -o $@ $<\n\n"); T_FileStream_writeLine(makefile, tmp); T_FileStream_writeLine(makefile, "# 'ALLDATAOBJ' contains all .c data structures\n"); sprintf(tmp, "ALLDATAOBJ= $(NAME)all%s \n\n", OBJ_SUFFIX); T_FileStream_writeLine(makefile, tmp); #endif sprintf(tmp, "TOCSYM= $(ENTRYPOINT)_dat \n\n"); /* entrypoint not always shortname! */ T_FileStream_writeLine(makefile, tmp); T_FileStream_writeLine(makefile, "BASE_OBJECTS= $(TOCOBJ) "); #ifdef OS400 T_FileStream_writeLine(makefile, "$(ALLDATAOBJ) "); #else pkg_writeCharListWrap(makefile, objects, " ", " \\\n",0); #endif pkg_mak_writeAssemblyFooter(makefile, o); T_FileStream_writeLine(makefile, "\n\n"); T_FileStream_writeLine(makefile, "OBJECTS=$(BASE_OBJECTS:%=$(TEMP_PATH)%)\n\n"); T_FileStream_writeLine(makefile,"$(TEMP_PATH)%.$(STATIC_O): $(TEMP_PATH)%.c\n\t $(COMPILE.c) -o $@ $<\n\n"); #if NO_IMPLICIT_AR T_FileStream_writeLine(makefile, "$(TARG_PATH)$(LIB_TARGET):$(TARG_PATH)$(LIB_TARGET) $(OBJECTS) $(LISTFILES)\n" "\t$(AR) $(ARFLAGS) $(TARG_PATH)$(LIB_TARGET) $(OBJECTS)\n" "\t$(RANLIB) $@\n\n"); #else T_FileStream_writeLine(makefile, "$(TARG_PATH)$(LIB_TARGET):$(TARG_PATH)$(LIB_TARGET)($(OBJECTS)) $(LISTFILES)\n" "\t$(RANLIB) $@\n\n"); #endif T_FileStream_writeLine(makefile, "CLEANFILES= $(CMNLIST) $(OBJECTS) $(TARG_PATH)$(LIB_TARGET) $(TARG_PATH)$(MIDDLE_STATIC_LIB_TARGET) $(TARG_PATH)$(TARGET)\n\nclean:\n\t-$(RMV) $(CLEANFILES) $(MAKEFILE)"); T_FileStream_writeLine(makefile, "\n\n"); T_FileStream_writeLine(makefile, "# static mode shouldn't need to be installed, but we will install the header and static library for them.\n"); T_FileStream_writeLine(makefile, "install: $(TARG_PATH)$(LIB_TARGET)\n" "\t$(INSTALL-L) $(TARG_PATH)$(LIB_TARGET) $(INSTALLTO)/$(LIB_TARGET)\n"); T_FileStream_writeLine(makefile, "\t$(RANLIB) $(INSTALLTO)/$(LIB_TARGET)\n"); if (o->version) { T_FileStream_writeLine(makefile, "\tcd $(INSTALLTO) && $(RM) $(MIDDLE_STATIC_LIB_TARGET) && ln -s $(LIB_TARGET) $(MIDDLE_STATIC_LIB_TARGET)\n\tcd $(INSTALLTO) && $(RM) $(STATIC_LIB_TARGET) && ln -s $(LIB_TARGET) $(STATIC_LIB_TARGET)\n"); T_FileStream_writeLine(makefile, "\t$(RANLIB) $(INSTALLTO)/$(STATIC_LIB_TARGET)\n\n"); } *status = U_ZERO_ERROR; }
UBool uprv_mapFile(UDataMemory *pData, const char *path) { const char *inBasename; char *basename; char pathBuffer[1024]; const DataHeader *pHeader; dllhandle *handle; void *val=0; inBasename=uprv_strrchr(path, U_FILE_SEP_CHAR); if(inBasename==NULL) { inBasename = path; } else { inBasename++; } basename=uprv_computeDirPath(path, pathBuffer); if(uprv_strcmp(inBasename, U_ICUDATA_NAME".dat") != 0) { /* must mmap file... for build */ int fd; int length; struct stat mystat; void *data; UDataMemory_init(pData); /* Clear the output struct. */ /* determine the length of the file */ if(stat(path, &mystat)!=0 || mystat.st_size<=0) { return FALSE; } length=mystat.st_size; /* open the file */ fd=open(path, O_RDONLY); if(fd==-1) { return FALSE; } /* get a view of the mapping */ data=mmap(0, length, PROT_READ, MAP_PRIVATE, fd, 0); close(fd); /* no longer needed */ if(data==MAP_FAILED) { return FALSE; } pData->map = (char *)data + length; pData->pHeader=(const DataHeader *)data; pData->mapAddr = data; return TRUE; } # ifdef OS390BATCH /* ### hack: we still need to get u_getDataDirectory() fixed for OS/390 (batch mode - always return "//"? ) and this here straightened out with LIB_PREFIX and LIB_SUFFIX (both empty?!) This is probably due to the strange file system on OS/390. It's more like a database with short entry names than a typical file system. */ /* U_ICUDATA_NAME should always have the correct name */ /* BUT FOR BATCH MODE IT IS AN EXCEPTION BECAUSE */ /* THE FIRST THREE LETTERS ARE PREASSIGNED TO THE */ /* PROJECT!!!!! */ uprv_strcpy(pathBuffer, "IXMI" U_ICU_VERSION_SHORT "DA"); # else /* set up the library name */ uprv_strcpy(basename, LIB_PREFIX U_LIBICUDATA_NAME U_ICU_VERSION_SHORT LIB_SUFFIX); # endif # ifdef UDATA_DEBUG fprintf(stderr, "dllload: %s ", pathBuffer); # endif handle=dllload(pathBuffer); # ifdef UDATA_DEBUG fprintf(stderr, " -> %08X\n", handle ); # endif if(handle != NULL) { /* we have a data DLL - what kind of lookup do we need here? */ /* try to find the Table of Contents */ UDataMemory_init(pData); /* Clear the output struct. */ val=dllqueryvar((dllhandle*)handle, U_ICUDATA_ENTRY_NAME); if(val == 0) { /* failed... so keep looking */ return FALSE; } # ifdef UDATA_DEBUG fprintf(stderr, "dllqueryvar(%08X, %s) -> %08X\n", handle, U_ICUDATA_ENTRY_NAME, val); # endif pData->pHeader=(const DataHeader *)val; return TRUE; } else { return FALSE; /* no handle */ } }
/** * Main Windows time zone detection function. Returns the Windows * time zone, translated to an ICU time zone, or NULL upon failure. */ U_CFUNC const char* U_EXPORT2 uprv_detectWindowsTimeZone() { UErrorCode status = U_ZERO_ERROR; UResourceBundle* bundle = NULL; char* icuid = NULL; char apiStdName[MAX_LENGTH_ID]; char regStdName[MAX_LENGTH_ID]; char tmpid[MAX_LENGTH_ID]; int32_t len; int id; int errorCode; wchar_t ISOcodeW[3]; /* 2 letter iso code in UTF-16*/ char ISOcodeA[3]; /* 2 letter iso code in ansi */ LONG result; TZI tziKey; TZI tziReg; TIME_ZONE_INFORMATION apiTZI; BOOL isVistaOrHigher; BOOL tryPreVistaFallback; OSVERSIONINFO osVerInfo; /* Obtain TIME_ZONE_INFORMATION from the API, and then convert it to TZI. We could also interrogate the registry directly; we do this below if needed. */ uprv_memset(&apiTZI, 0, sizeof(apiTZI)); uprv_memset(&tziKey, 0, sizeof(tziKey)); uprv_memset(&tziReg, 0, sizeof(tziReg)); GetTimeZoneInformation(&apiTZI); tziKey.bias = apiTZI.Bias; uprv_memcpy((char *)&tziKey.standardDate, (char*)&apiTZI.StandardDate, sizeof(apiTZI.StandardDate)); uprv_memcpy((char *)&tziKey.daylightDate, (char*)&apiTZI.DaylightDate, sizeof(apiTZI.DaylightDate)); /* Convert the wchar_t* standard name to char* */ uprv_memset(apiStdName, 0, sizeof(apiStdName)); wcstombs(apiStdName, apiTZI.StandardName, MAX_LENGTH_ID); tmpid[0] = 0; id = GetUserGeoID(GEOCLASS_NATION); errorCode = GetGeoInfoW(id, GEO_ISO2, ISOcodeW, 3, 0); u_strToUTF8(ISOcodeA, 3, NULL, (const UChar *)ISOcodeW, 3, &status); bundle = ures_openDirect(NULL, "windowsZones", &status); ures_getByKey(bundle, "mapTimezones", bundle, &status); /* Windows Vista+ provides us with a "TimeZoneKeyName" that is not localized and can be used to directly map a name in our bundle. Try to use that first if we're on Vista or higher */ uprv_memset(&osVerInfo, 0, sizeof(osVerInfo)); osVerInfo.dwOSVersionInfoSize = sizeof(osVerInfo); GetVersionEx(&osVerInfo); isVistaOrHigher = osVerInfo.dwMajorVersion >= 6; /* actually includes Windows Server 2008 as well, but don't worry about it */ tryPreVistaFallback = TRUE; if(isVistaOrHigher) { result = getTZKeyName(regStdName, sizeof(regStdName)); if(ERROR_SUCCESS == result) { UResourceBundle* winTZ = ures_getByKey(bundle, regStdName, NULL, &status); if(U_SUCCESS(status)) { const UChar* icuTZ = NULL; if (errorCode != 0) { icuTZ = ures_getStringByKey(winTZ, ISOcodeA, &len, &status); } if (errorCode==0 || icuTZ==NULL) { /* fallback to default "001" and reset status */ status = U_ZERO_ERROR; icuTZ = ures_getStringByKey(winTZ, "001", &len, &status); } if(U_SUCCESS(status)) { int index=0; while (! (*icuTZ == '\0' || *icuTZ ==' ')) { tmpid[index++]=(char)(*icuTZ++); /* safe to assume 'char' is ASCII compatible on windows */ } tmpid[index]='\0'; tryPreVistaFallback = FALSE; } } ures_close(winTZ); } } if(tryPreVistaFallback) { /* Note: We get the winid not from static tables but from resource bundle. */ while (U_SUCCESS(status) && ures_hasNext(bundle)) { UBool idFound = FALSE; const char* winid; UResourceBundle* winTZ = ures_getNextResource(bundle, NULL, &status); if (U_FAILURE(status)) { break; } winid = ures_getKey(winTZ); result = getTZI(winid, &tziReg); if (result == ERROR_SUCCESS) { /* Windows alters the DaylightBias in some situations. Using the bias and the rules suffices, so overwrite these unreliable fields. */ tziKey.standardBias = tziReg.standardBias; tziKey.daylightBias = tziReg.daylightBias; if (uprv_memcmp((char *)&tziKey, (char*)&tziReg, sizeof(tziKey)) == 0) { const UChar* icuTZ = NULL; if (errorCode != 0) { icuTZ = ures_getStringByKey(winTZ, ISOcodeA, &len, &status); } if (errorCode==0 || icuTZ==NULL) { /* fallback to default "001" and reset status */ status = U_ZERO_ERROR; icuTZ = ures_getStringByKey(winTZ, "001", &len, &status); } if (U_SUCCESS(status)) { /* Get the standard name from the registry key to compare with the one from Windows API call. */ uprv_memset(regStdName, 0, sizeof(regStdName)); result = getSTDName(winid, regStdName, sizeof(regStdName)); if (result == ERROR_SUCCESS) { if (uprv_strcmp(apiStdName, regStdName) == 0) { idFound = TRUE; } } /* tmpid buffer holds the ICU timezone ID corresponding to the timezone ID from Windows. * If none is found, tmpid buffer will contain a fallback ID (i.e. the time zone ID matching * the current time zone information) */ if (idFound || tmpid[0] == 0) { /* if icuTZ has more than one city, take only the first (i.e. terminate icuTZ at first space) */ int index=0; while (! (*icuTZ == '\0' || *icuTZ ==' ')) { tmpid[index++]=(char)(*icuTZ++); /* safe to assume 'char' is ASCII compatible on windows */ } tmpid[index]='\0'; } } } } ures_close(winTZ); if (idFound) { break; } } } /* * Copy the timezone ID to icuid to be returned. */ if (tmpid[0] != 0) { len = uprv_strlen(tmpid); icuid = (char*)uprv_calloc(len + 1, sizeof(char)); if (icuid != NULL) { uprv_strcpy(icuid, tmpid); } } ures_close(bundle); return icuid; }
/* Generate the target .res file name from the input file name */ static char* make_res_filename(const char *filename, const char *outputDir, const char *packageName, UErrorCode *status) { char *basename; char *dirname; char *resName; int32_t pkgLen = 0; /* length of package prefix */ if (U_FAILURE(*status)) { return 0; } if(packageName != NULL) { pkgLen = (int32_t)(1 + uprv_strlen(packageName)); } /* 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) + pkgLen + uprv_strlen(basename) + uprv_strlen(RES_SUFFIX) + 8)); if(resName == 0) { *status = U_MEMORY_ALLOCATION_ERROR; goto finish; } uprv_strcpy(resName, dirname); if(packageName != NULL) { uprv_strcat(resName, packageName); uprv_strcat(resName, "_"); } uprv_strcat(resName, basename); } else { int32_t dirlen = (int32_t)uprv_strlen(outputDir); int32_t basenamelen = (int32_t)uprv_strlen(basename); resName = (char*) uprv_malloc(sizeof(char) * (dirlen + pkgLen + basenamelen + 8)); if (resName == NULL) { *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'; } if(packageName != NULL) { uprv_strcat(resName, packageName); uprv_strcat(resName, "_"); } uprv_strcat(resName, basename); } finish: uprv_free(basename); uprv_free(dirname); return resName; }
static UStringPrepProfile * usprep_getProfile(const char * path, const char * name, UErrorCode * status) { UStringPrepProfile * profile = NULL; initCache(status); if (U_FAILURE(*status)) { return NULL; } UStringPrepKey stackKey; /* * const is cast way to save malloc, strcpy and free calls * we use the passed in pointers for fetching the data from the * hash table which is safe */ stackKey.name = (char *) name; stackKey.path = (char *) path; /* fetch the data from the cache */ umtx_lock(&usprepMutex); profile = (UStringPrepProfile *)(uhash_get(SHARED_DATA_HASHTABLE, &stackKey)); if (profile != NULL) { profile->refCount++; } umtx_unlock(&usprepMutex); if (profile == NULL) { /* else load the data and put the data in the cache */ LocalMemory<UStringPrepProfile> newProfile; if (newProfile.allocateInsteadAndReset() == NULL) { *status = U_MEMORY_ALLOCATION_ERROR; return NULL; } /* load the data */ if (!loadData(newProfile.getAlias(), path, name, _SPREP_DATA_TYPE, status) || U_FAILURE(*status)) { return NULL; } /* get the options */ newProfile->doNFKC = (UBool)((newProfile->indexes[_SPREP_OPTIONS] & _SPREP_NORMALIZATION_ON) > 0); newProfile->checkBiDi = (UBool)((newProfile->indexes[_SPREP_OPTIONS] & _SPREP_CHECK_BIDI_ON) > 0); if (newProfile->checkBiDi) { newProfile->bdp = ubidi_getSingleton(); } LocalMemory<UStringPrepKey> key; LocalMemory<char> keyName; LocalMemory<char> keyPath; if (key.allocateInsteadAndReset() == NULL || keyName.allocateInsteadAndCopy(uprv_strlen(name) + 1) == NULL || (path != NULL && keyPath.allocateInsteadAndCopy(uprv_strlen(path) + 1) == NULL) ) { *status = U_MEMORY_ALLOCATION_ERROR; usprep_unload(newProfile.getAlias()); return NULL; } umtx_lock(&usprepMutex); // If another thread already inserted the same key/value, refcount and cleanup our thread data profile = (UStringPrepProfile *)(uhash_get(SHARED_DATA_HASHTABLE, &stackKey)); if (profile != NULL) { profile->refCount++; usprep_unload(newProfile.getAlias()); } else { /* initialize the key members */ key->name = keyName.orphan(); uprv_strcpy(key->name, name); if (path != NULL) { key->path = keyPath.orphan(); uprv_strcpy(key->path, path); } profile = newProfile.orphan(); /* add the data object to the cache */ profile->refCount = 1; uhash_put(SHARED_DATA_HASHTABLE, key.orphan(), profile, status); } umtx_unlock(&usprepMutex); } return profile; }
U_CAPI UBool U_EXPORT2 ucm_parseHeaderLine(UCMFile *ucm, char *line, char **pKey, char **pValue) { UCMStates *states; char *s, *end; char c; states=&ucm->states; /* remove comments and trailing CR and LF and remove whitespace from the end */ for(end=line; (c=*end)!=0; ++end) { if(c=='#' || c=='\r' || c=='\n') { break; } } while(end>line && (*(end-1)==' ' || *(end-1)=='\t')) { --end; } *end=0; /* skip leading white space and ignore empty lines */ s=(char *)u_skipWhitespace(line); if(*s==0) { return TRUE; } /* stop at the beginning of the mapping section */ if(uprv_memcmp(s, "CHARMAP", 7)==0) { return FALSE; } /* get the key name, bracketed in <> */ if(*s!='<') { fprintf(stderr, "ucm error: no header field <key> in line \"%s\"\n", line); exit(U_INVALID_TABLE_FORMAT); } *pKey=++s; while(*s!='>') { if(*s==0) { fprintf(stderr, "ucm error: incomplete header field <key> in line \"%s\"\n", line); exit(U_INVALID_TABLE_FORMAT); } ++s; } *s=0; /* get the value string, possibly quoted */ s=(char *)u_skipWhitespace(s+1); if(*s!='"') { *pValue=s; } else { /* remove the quotes */ *pValue=s+1; if(end>*pValue && *(end-1)=='"') { *--end=0; } } /* collect the information from the header field, ignore unknown keys */ if(uprv_strcmp(*pKey, "uconv_class")==0) { if(uprv_strcmp(*pValue, "DBCS")==0) { states->conversionType=UCNV_DBCS; } else if(uprv_strcmp(*pValue, "SBCS")==0) { states->conversionType = UCNV_SBCS; } else if(uprv_strcmp(*pValue, "MBCS")==0) { states->conversionType = UCNV_MBCS; } else if(uprv_strcmp(*pValue, "EBCDIC_STATEFUL")==0) { states->conversionType = UCNV_EBCDIC_STATEFUL; } else { fprintf(stderr, "ucm error: unknown <uconv_class> %s\n", *pValue); exit(U_INVALID_TABLE_FORMAT); } return TRUE; } else if(uprv_strcmp(*pKey, "mb_cur_max")==0) { c=**pValue; if('1'<=c && c<='4' && (*pValue)[1]==0) { states->maxCharLength=(int8_t)(c-'0'); states->outputType=(int8_t)(states->maxCharLength-1); } else { fprintf(stderr, "ucm error: illegal <mb_cur_max> %s\n", *pValue); exit(U_INVALID_TABLE_FORMAT); } return TRUE; } else if(uprv_strcmp(*pKey, "mb_cur_min")==0) { c=**pValue; if('1'<=c && c<='4' && (*pValue)[1]==0) { states->minCharLength=(int8_t)(c-'0'); } else { fprintf(stderr, "ucm error: illegal <mb_cur_min> %s\n", *pValue); exit(U_INVALID_TABLE_FORMAT); } return TRUE; } else if(uprv_strcmp(*pKey, "icu:state")==0) { /* if an SBCS/DBCS/EBCDIC_STATEFUL converter has icu:state, then turn it into MBCS */ switch(states->conversionType) { case UCNV_SBCS: case UCNV_DBCS: case UCNV_EBCDIC_STATEFUL: states->conversionType=UCNV_MBCS; break; case UCNV_MBCS: break; default: fprintf(stderr, "ucm error: <icu:state> entry for non-MBCS table or before the <uconv_class> line\n"); exit(U_INVALID_TABLE_FORMAT); } if(states->maxCharLength==0) { fprintf(stderr, "ucm error: <icu:state> before the <mb_cur_max> line\n"); exit(U_INVALID_TABLE_FORMAT); } ucm_addState(states, *pValue); return TRUE; } else if(uprv_strcmp(*pKey, "icu:base")==0) { if(**pValue==0) { fprintf(stderr, "ucm error: <icu:base> without a base table name\n"); exit(U_INVALID_TABLE_FORMAT); } uprv_strcpy(ucm->baseName, *pValue); return TRUE; } return FALSE; }
U_CAPI void U_EXPORT2 writeAssemblyCode(const char *filename, const char *destdir, const char *optEntryPoint, const char *optFilename, char *outFilePath) { uint32_t column = MAX_COLUMN; char entry[64]; uint32_t buffer[1024]; char *bufferStr = (char *)buffer; FileStream *in, *out; size_t i, length; in=T_FileStream_open(filename, "rb"); if(in==NULL) { fprintf(stderr, "genccode: unable to open input file %s\n", filename); exit(U_FILE_ACCESS_ERROR); } getOutFilename(filename, destdir, bufferStr, entry, ".S", optFilename); out=T_FileStream_open(bufferStr, "w"); if(out==NULL) { fprintf(stderr, "genccode: unable to open output file %s\n", bufferStr); exit(U_FILE_ACCESS_ERROR); } if (outFilePath != NULL) { uprv_strcpy(outFilePath, bufferStr); } #ifdef WINDOWS_WITH_GNUC /* Need to fix the file seperator character when using MinGW. */ swapFileSepChar(outFilePath, U_FILE_SEP_CHAR, '/'); #endif if(optEntryPoint != NULL) { uprv_strcpy(entry, optEntryPoint); uprv_strcat(entry, "_dat"); } /* turn dashes or dots in the entry name into underscores */ length=uprv_strlen(entry); for(i=0; i<length; ++i) { if(entry[i]=='-' || entry[i]=='.') { entry[i]='_'; } } sprintf(bufferStr, assemblyHeader[assemblyHeaderIndex].header, entry, entry, entry, entry, entry, entry, entry, entry); T_FileStream_writeLine(out, bufferStr); T_FileStream_writeLine(out, assemblyHeader[assemblyHeaderIndex].beginLine); for(;;) { length=T_FileStream_read(in, buffer, sizeof(buffer)); if(length==0) { break; } if (length != sizeof(buffer)) { /* pad with extra 0's when at the end of the file */ for(i=0; i < (length % sizeof(uint32_t)); ++i) { buffer[length+i] = 0; } } for(i=0; i<(length/sizeof(buffer[0])); i++) { column = write32(out, buffer[i], column); } } T_FileStream_writeLine(out, "\n"); sprintf(bufferStr, assemblyHeader[assemblyHeaderIndex].footer, entry, entry, entry, entry, entry, entry, entry, entry); T_FileStream_writeLine(out, bufferStr); if(T_FileStream_error(in)) { fprintf(stderr, "genccode: file read error while generating from file %s\n", filename); exit(U_FILE_ACCESS_ERROR); } if(T_FileStream_error(out)) { fprintf(stderr, "genccode: file write error while generating from file %s\n", filename); exit(U_FILE_ACCESS_ERROR); } T_FileStream_close(out); T_FileStream_close(in); }
void TZGNCore::initialize(const Locale& locale, UErrorCode& status) { if (U_FAILURE(status)) { return; } // TimeZoneNames fTimeZoneNames = TimeZoneNames::createInstance(locale, status); if (U_FAILURE(status)) { return; } // Initialize format patterns UnicodeString rpat(TRUE, gDefRegionPattern, -1); UnicodeString fpat(TRUE, gDefFallbackPattern, -1); UErrorCode tmpsts = U_ZERO_ERROR; // OK with fallback warning.. UResourceBundle *zoneStrings = ures_open(U_ICUDATA_ZONE, locale.getName(), &tmpsts); zoneStrings = ures_getByKeyWithFallback(zoneStrings, gZoneStrings, zoneStrings, &tmpsts); if (U_SUCCESS(tmpsts)) { const UChar *regionPattern = ures_getStringByKeyWithFallback(zoneStrings, gRegionFormatTag, NULL, &tmpsts); if (U_SUCCESS(tmpsts) && u_strlen(regionPattern) > 0) { rpat.setTo(regionPattern, -1); } tmpsts = U_ZERO_ERROR; const UChar *fallbackPattern = ures_getStringByKeyWithFallback(zoneStrings, gFallbackFormatTag, NULL, &tmpsts); if (U_SUCCESS(tmpsts) && u_strlen(fallbackPattern) > 0) { fpat.setTo(fallbackPattern, -1); } } ures_close(zoneStrings); fRegionFormat = new MessageFormat(rpat, status); if (fRegionFormat == NULL) { status = U_MEMORY_ALLOCATION_ERROR; } fFallbackFormat = new MessageFormat(fpat, status); if (fFallbackFormat == NULL) { status = U_MEMORY_ALLOCATION_ERROR; } if (U_FAILURE(status)) { cleanup(); return; } // locale display names fLocaleDisplayNames = LocaleDisplayNames::createInstance(locale); // hash table for names - no key/value deleters fLocationNamesMap = uhash_open(uhash_hashUChars, uhash_compareUChars, NULL, &status); if (U_FAILURE(status)) { cleanup(); return; } fPartialLocationNamesMap = uhash_open(hashPartialLocationKey, comparePartialLocationKey, NULL, &status); if (U_FAILURE(status)) { cleanup(); return; } uhash_setKeyDeleter(fPartialLocationNamesMap, uprv_free); // no value deleter // target region const char* region = fLocale.getCountry(); int32_t regionLen = uprv_strlen(region); if (regionLen == 0) { char loc[ULOC_FULLNAME_CAPACITY]; uloc_addLikelySubtags(fLocale.getName(), loc, sizeof(loc), &status); regionLen = uloc_getCountry(loc, fTargetRegion, sizeof(fTargetRegion), &status); if (U_SUCCESS(status)) { fTargetRegion[regionLen] = 0; } else { cleanup(); return; } } else if (regionLen < (int32_t)sizeof(fTargetRegion)) { uprv_strcpy(fTargetRegion, region); } else { fTargetRegion[0] = 0; } // preload generic names for the default zone TimeZone *tz = TimeZone::createDefault(); const UChar *tzID = ZoneMeta::getCanonicalCLDRID(*tz); if (tzID != NULL) { loadStrings(UnicodeString(tzID)); } delete tz; }
U_CAPI void U_EXPORT2 writeCCode(const char *filename, const char *destdir, const char *optName, const char *optFilename, char *outFilePath) { uint32_t column = MAX_COLUMN; char buffer[4096], entry[64]; FileStream *in, *out; size_t i, length; in=T_FileStream_open(filename, "rb"); if(in==NULL) { fprintf(stderr, "genccode: unable to open input file %s\n", filename); exit(U_FILE_ACCESS_ERROR); } if(optName != NULL) { /* prepend 'icudt28_' */ strcpy(entry, optName); strcat(entry, "_"); } else { entry[0] = 0; } getOutFilename(filename, destdir, buffer, entry+uprv_strlen(entry), ".c", optFilename); if (outFilePath != NULL) { uprv_strcpy(outFilePath, buffer); } out=T_FileStream_open(buffer, "w"); if(out==NULL) { fprintf(stderr, "genccode: unable to open output file %s\n", buffer); exit(U_FILE_ACCESS_ERROR); } /* turn dashes or dots in the entry name into underscores */ length=uprv_strlen(entry); for(i=0; i<length; ++i) { if(entry[i]=='-' || entry[i]=='.') { entry[i]='_'; } } #if U_PLATFORM == U_PF_OS400 /* TODO: Fix this once the compiler implements this feature. Keep in sync with udatamem.c This is here because this platform can't currently put const data into the read-only pages of an object or shared library (service program). Only strings are allowed in read-only pages, so we use char * strings to store the data. In order to prevent the beginning of the data from ever matching the magic numbers we must still use the initial double. [grhoten 4/24/2003] */ sprintf(buffer, "#ifndef IN_GENERATED_CCODE\n" "#define IN_GENERATED_CCODE\n" "#define U_DISABLE_RENAMING 1\n" "#include \"unicode/umachine.h\"\n" "#endif\n" "U_CDECL_BEGIN\n" "const struct {\n" " double bogus;\n" " const char *bytes; \n" "} %s={ 0.0, \n", entry); T_FileStream_writeLine(out, buffer); for(;;) { length=T_FileStream_read(in, buffer, sizeof(buffer)); if(length==0) { break; } for(i=0; i<length; ++i) { column = write8str(out, (uint8_t)buffer[i], column); } } T_FileStream_writeLine(out, "\"\n};\nU_CDECL_END\n"); #else /* Function renaming shouldn't be done in data */ sprintf(buffer, "#ifndef IN_GENERATED_CCODE\n" "#define IN_GENERATED_CCODE\n" "#define U_DISABLE_RENAMING 1\n" "#include \"unicode/umachine.h\"\n" "#endif\n" "U_CDECL_BEGIN\n" "const struct {\n" " double bogus;\n" " uint8_t bytes[%ld]; \n" "} %s={ 0.0, {\n", (long)T_FileStream_size(in), entry); T_FileStream_writeLine(out, buffer); for(;;) { length=T_FileStream_read(in, buffer, sizeof(buffer)); if(length==0) { break; } for(i=0; i<length; ++i) { column = write8(out, (uint8_t)buffer[i], column); } } T_FileStream_writeLine(out, "\n}\n};\nU_CDECL_END\n"); #endif if(T_FileStream_error(in)) { fprintf(stderr, "genccode: file read error while generating from file %s\n", filename); exit(U_FILE_ACCESS_ERROR); } if(T_FileStream_error(out)) { fprintf(stderr, "genccode: file write error while generating from file %s\n", filename); exit(U_FILE_ACCESS_ERROR); } T_FileStream_close(out); T_FileStream_close(in); }
U_CAPI UNewDataMemory * U_EXPORT2 udata_create(const char *dir, const char *type, const char *name, const UDataInfo *pInfo, const char *comment, UErrorCode *pErrorCode) { UNewDataMemory *pData; uint16_t headerSize, commentLength; char filename[512]; uint8_t bytes[16]; int length; if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { return NULL; } else if(name==NULL || *name==0 || pInfo==NULL) { *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; return NULL; } /* allocate the data structure */ pData=(UNewDataMemory *)uprv_malloc(sizeof(UNewDataMemory)); if(pData==NULL) { *pErrorCode=U_MEMORY_ALLOCATION_ERROR; return NULL; } /* Check that the full path won't be too long */ length = 0; /* Start with nothing */ if(dir != NULL && *dir !=0) /* Add directory length if one was given */ { length += strlen(dir); /* Add 1 if dir doesn't end with path sep */ if (dir[strlen(dir) - 1]!= U_FILE_SEP_CHAR) { length++; } } length += strlen(name); /* Add the filename length */ if(type != NULL && *type !=0) { /* Add directory length if given */ length += strlen(type); } /* LDH buffer Length error check */ if(length > (sizeof(filename) - 1)) { *pErrorCode = U_BUFFER_OVERFLOW_ERROR; uprv_free(pData); return NULL; } /* open the output file */ if(dir!=NULL && *dir!=0) { /* if dir has a value, we prepend it to the filename */ char *p=filename+strlen(dir); uprv_strcpy(filename, dir); if (*(p-1)!=U_FILE_SEP_CHAR) { *p++=U_FILE_SEP_CHAR; *p=0; } } else { /* otherwise, we'll output to the current dir */ filename[0]=0; } uprv_strcat(filename, name); if(type!=NULL && *type!=0) { uprv_strcat(filename, "."); uprv_strcat(filename, type); } pData->file=T_FileStream_open(filename, "wb"); if(pData->file==NULL) { uprv_free(pData); *pErrorCode=U_FILE_ACCESS_ERROR; return NULL; } /* write the header information */ headerSize=(uint16_t)(pInfo->size+4); if(comment!=NULL && *comment!=0) { commentLength=(uint16_t)(uprv_strlen(comment)+1); headerSize+=commentLength; } else { commentLength=0; } /* write the size of the header, take padding into account */ pData->headerSize=(uint16_t)((headerSize+15)&~0xf); pData->magic1=0xda; pData->magic2=0x27; T_FileStream_write(pData->file, &pData->headerSize, 4); /* write the information data */ T_FileStream_write(pData->file, pInfo, pInfo->size); /* write the comment */ if(commentLength>0) { T_FileStream_write(pData->file, comment, commentLength); } /* write padding bytes to align the data section to 16 bytes */ headerSize&=0xf; if(headerSize!=0) { headerSize=(uint16_t)(16-headerSize); uprv_memset(bytes, 0, headerSize); T_FileStream_write(pData->file, bytes, headerSize); } return pData; }
/* * Opens the given fileName and reads in the information storing the data in flagBuffer. */ U_CAPI int32_t U_EXPORT2 parseFlagsFile(const char *fileName, char **flagBuffer, int32_t flagBufferSize, const char ** flagNames, int32_t numOfFlags, UErrorCode *status) { char* buffer = NULL; char* tmpFlagBuffer = NULL; UBool allocateMoreSpace = FALSE; int32_t idx, i; int32_t result = 0; FileStream *f = T_FileStream_open(fileName, "r"); if (f == NULL) { *status = U_FILE_ACCESS_ERROR; goto parseFlagsFile_cleanup; } buffer = (char *)uprv_malloc(sizeof(char) * currentBufferSize); tmpFlagBuffer = (char *)uprv_malloc(sizeof(char) * flagBufferSize); if (buffer == NULL || tmpFlagBuffer == NULL) { *status = U_MEMORY_ALLOCATION_ERROR; goto parseFlagsFile_cleanup; } do { if (allocateMoreSpace) { allocateMoreSpace = FALSE; currentBufferSize *= 2; uprv_free(buffer); buffer = (char *)uprv_malloc(sizeof(char) * currentBufferSize); if (buffer == NULL) { *status = U_MEMORY_ALLOCATION_ERROR; goto parseFlagsFile_cleanup; } } for (i = 0; i < numOfFlags;) { if (T_FileStream_readLine(f, buffer, currentBufferSize) == NULL) { /* End of file reached. */ break; } if (buffer[0] == '#') { continue; } if ((int32_t)uprv_strlen(buffer) == (currentBufferSize - 1) && buffer[currentBufferSize-2] != '\n') { /* Allocate more space for buffer if it didnot read the entrire line */ allocateMoreSpace = TRUE; T_FileStream_rewind(f); break; } else { idx = extractFlag(buffer, currentBufferSize, tmpFlagBuffer, flagBufferSize, flagNames, numOfFlags, status); if (U_FAILURE(*status)) { if (*status == U_BUFFER_OVERFLOW_ERROR) { result = currentBufferSize; } else { result = -1; } break; } else { if (flagNames != NULL) { if (idx >= 0) { uprv_strcpy(flagBuffer[idx], tmpFlagBuffer); } else { /* No match found. Skip it. */ continue; } } else { uprv_strcpy(flagBuffer[i++], tmpFlagBuffer); } } } } } while (allocateMoreSpace && U_SUCCESS(*status)); parseFlagsFile_cleanup: uprv_free(tmpFlagBuffer); uprv_free(buffer); T_FileStream_close(f); if (U_FAILURE(*status) && *status != U_BUFFER_OVERFLOW_ERROR) { return -1; } if (U_SUCCESS(*status) && result == 0) { currentBufferSize = DEFAULT_BUFFER_SIZE; } return result; }
// srcPluralCount is the original plural count on which the pattern is // searched for. // searchPluralCount is the fallback plural count. // For example, to search for pattern for ""one" hour", // "one" is the srcPluralCount, // if the pattern is not found even in root, fallback to // using patterns of plural count "other", // then, "other" is the searchPluralCount. void TimeUnitFormat::searchInLocaleChain(EStyle style, const char* key, const char* localeName, TimeUnit::UTimeUnitFields srcTimeUnitField, const char* srcPluralCount, const char* searchPluralCount, Hashtable* countToPatterns, UErrorCode& err) { if (U_FAILURE(err)) { return; } UErrorCode status = U_ZERO_ERROR; char parentLocale[ULOC_FULLNAME_CAPACITY]; uprv_strcpy(parentLocale, localeName); int32_t locNameLen; while ((locNameLen = uloc_getParent(parentLocale, parentLocale, ULOC_FULLNAME_CAPACITY, &status)) >= 0){ // look for pattern for srcPluralCount in locale tree UResourceBundle *rb, *unitsRes, *countsToPatternRB; rb = ures_open(NULL, parentLocale, &status); unitsRes = ures_getByKey(rb, key, NULL, &status); const char* timeUnitName = getTimeUnitName(srcTimeUnitField, status); countsToPatternRB = ures_getByKey(unitsRes, timeUnitName, NULL, &status); const UChar* pattern; int32_t ptLength; pattern = ures_getStringByKeyWithFallback(countsToPatternRB, searchPluralCount, &ptLength, &status); if (U_SUCCESS(status)) { //found MessageFormat* messageFormat = new MessageFormat(pattern, fLocale, err); if (U_SUCCESS(err)) { if (fNumberFormat != NULL) { messageFormat->setFormat(0, *fNumberFormat); } MessageFormat** formatters = (MessageFormat**)countToPatterns->get(srcPluralCount); if (formatters == NULL) { formatters = (MessageFormat**)uprv_malloc(kTotal*sizeof(MessageFormat*)); formatters[kFull] = NULL; formatters[kAbbreviate] = NULL; countToPatterns->put(srcPluralCount, formatters, err); if (U_FAILURE(err)) { uprv_free(formatters); delete messageFormat; } } if (U_SUCCESS(err)) { //delete formatters[style]; formatters[style] = messageFormat; } } else { delete messageFormat; } ures_close(countsToPatternRB); ures_close(unitsRes); ures_close(rb); return; } ures_close(countsToPatternRB); ures_close(unitsRes); ures_close(rb); status = U_ZERO_ERROR; if ( locNameLen ==0 ) { break; } } // if no unitsShort resource was found even after fallback to root locale // then search the units resource fallback from the current level to root if ( locNameLen == 0 && uprv_strcmp(key, gShortUnitsTag) == 0) { #ifdef TMUTFMT_DEBUG std::cout << "loop into searchInLocaleChain since Short-Long-Alternative \n"; #endif char pLocale[ULOC_FULLNAME_CAPACITY]; uprv_strcpy(pLocale, localeName); // Add an underscore at the tail of locale name, // so that searchInLocaleChain will check the current locale before falling back uprv_strcat(pLocale, "_"); searchInLocaleChain(style, gUnitsTag, pLocale, srcTimeUnitField, srcPluralCount, searchPluralCount, countToPatterns, err); if (countToPatterns != NULL) { MessageFormat** formatters = (MessageFormat**)countToPatterns->get(srcPluralCount); if (formatters != NULL && formatters[style] != NULL) return; } } // if not found the pattern for this plural count at all, // fall-back to plural count "other" if ( uprv_strcmp(searchPluralCount, gPluralCountOther) == 0 ) { // set default fall back the same as the resource in root MessageFormat* messageFormat = NULL; if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_SECOND ) { messageFormat = new MessageFormat(DEFAULT_PATTERN_FOR_SECOND, fLocale, err); } else if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_MINUTE ) { messageFormat = new MessageFormat(DEFAULT_PATTERN_FOR_MINUTE, fLocale, err); } else if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_HOUR ) { messageFormat = new MessageFormat(DEFAULT_PATTERN_FOR_HOUR, fLocale, err); } else if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_WEEK ) { messageFormat = new MessageFormat(DEFAULT_PATTERN_FOR_WEEK, fLocale, err); } else if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_DAY ) { messageFormat = new MessageFormat(DEFAULT_PATTERN_FOR_DAY, fLocale, err); } else if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_MONTH ) { messageFormat = new MessageFormat(DEFAULT_PATTERN_FOR_MONTH, fLocale, err); } else if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_YEAR ) { messageFormat = new MessageFormat(DEFAULT_PATTERN_FOR_YEAR, fLocale, err); } if (U_SUCCESS(err)) { if (fNumberFormat != NULL && messageFormat != NULL) { messageFormat->setFormat(0, *fNumberFormat); } MessageFormat** formatters = (MessageFormat**)countToPatterns->get(srcPluralCount); if (formatters == NULL) { formatters = (MessageFormat**)uprv_malloc(kTotal*sizeof(MessageFormat*)); formatters[kFull] = NULL; formatters[kAbbreviate] = NULL; countToPatterns->put(srcPluralCount, formatters, err); if (U_FAILURE(err)) { uprv_free(formatters); delete messageFormat; } } if (U_SUCCESS(err)) { //delete formatters[style]; formatters[style] = messageFormat; } } else { delete messageFormat; } } else { // fall back to rule "other", and search in parents searchInLocaleChain(style, key, localeName, srcTimeUnitField, srcPluralCount, gPluralCountOther, countToPatterns, err); } }
void LocaleBased::setLocaleIDs(const Locale& validID, const Locale& actualID) { uprv_strcpy(valid, validID.getName()); uprv_strcpy(actual, actualID.getName()); }