static int32_t parseSetNum(const char *setNumStr, UErrorCode &errorCode) { if (U_FAILURE(errorCode)) { return -1; } if (uprv_strncmp(setNumStr, "set", 3) != 0) { errorCode = U_INVALID_FORMAT_ERROR; return -1; } int32_t i = 3; int32_t setNum = 0; while (setNumStr[i] != 0) { int32_t digit = setNumStr[i] - '0'; if (digit < 0 || 9 < digit) { errorCode = U_INVALID_FORMAT_ERROR; return -1; } setNum = 10 * setNum + digit; ++i; } // Rule set number must not be zero. (0 is used to indicate "not found" by hashmap.) // Currently ICU data conveniently starts numbering rule sets from 1. if (setNum == 0) { errorCode = U_INVALID_FORMAT_ERROR; return -1; } else { return setNum; } }
UBool DigitList::operator==(const DigitList& that) const { return ((this == &that) || (fDecimalAt == that.fDecimalAt && fCount == that.fCount && fIsPositive == that.fIsPositive && fRoundingMode == that.fRoundingMode && uprv_strncmp(fDigits, that.fDigits, fCount) == 0)); }
static int32_t _getStringOrCopyKey(const char *path, const char *locale, const char *tableKey, const char* subTableKey, const char *itemKey, const char *substitute, UChar *dest, int32_t destCapacity, UErrorCode *pErrorCode) { const UChar *s = NULL; int32_t length = 0; if(itemKey==NULL) { /* top-level item: normal resource bundle access */ UResourceBundle *rb; rb=ures_open(path, locale, pErrorCode); if(U_SUCCESS(*pErrorCode)) { s=ures_getStringByKey(rb, tableKey, &length, pErrorCode); /* see comment about closing rb near "return item;" in _res_getTableStringWithFallback() */ ures_close(rb); } } else { /* Language code should not be a number. If it is, set the error code. */ if (!uprv_strncmp(tableKey, "Languages", 9) && uprv_strtol(itemKey, NULL, 10)) { *pErrorCode = U_MISSING_RESOURCE_ERROR; } else { /* second-level item, use special fallback */ s=uloc_getTableStringWithFallback(path, locale, tableKey, subTableKey, itemKey, &length, pErrorCode); } } if(U_SUCCESS(*pErrorCode)) { int32_t copyLength=uprv_min(length, destCapacity); if(copyLength>0 && s != NULL) { u_memcpy(dest, s, copyLength); } } else { /* no string from a resource bundle: convert the substitute */ length=(int32_t)uprv_strlen(substitute); u_charsToUChars(substitute, dest, uprv_min(length, destCapacity)); *pErrorCode=U_USING_DEFAULT_WARNING; } return u_terminateUChars(dest, destCapacity, length, pErrorCode); }
static void U_CALLCONV ageLineFn(void *context, char *fields[][2], int32_t fieldCount, UErrorCode *pErrorCode) { char *s, *numberLimit; uint32_t value, start, end, version; u_parseCodePointRange(fields[0][0], &start, &end, pErrorCode); if(U_FAILURE(*pErrorCode)) { fprintf(stderr, "genprops: syntax error in DerivedAge.txt field 0 at %s\n", fields[0][0]); exit(*pErrorCode); } /* ignore "unassigned" (the default is already set to 0.0) */ s=(char *)u_skipWhitespace(fields[1][0]); if(0==uprv_strncmp(s, "unassigned", 10)) { return; } /* parse version number */ value=(uint32_t)uprv_strtoul(s, &numberLimit, 10); if(s==numberLimit || value==0 || value>15 || (*numberLimit!='.' && *numberLimit!=' ' && *numberLimit!='\t' && *numberLimit!=0)) { fprintf(stderr, "genprops: syntax error in DerivedAge.txt field 1 at %s\n", fields[1][0]); *pErrorCode=U_PARSE_ERROR; exit(U_PARSE_ERROR); } version=value<<4; /* parse minor version number */ if(*numberLimit=='.') { s=(char *)u_skipWhitespace(numberLimit+1); value=(uint32_t)uprv_strtoul(s, &numberLimit, 10); if(s==numberLimit || value>15 || (*numberLimit!=' ' && *numberLimit!='\t' && *numberLimit!=0)) { fprintf(stderr, "genprops: syntax error in DerivedAge.txt field 1 at %s\n", fields[1][0]); *pErrorCode=U_PARSE_ERROR; exit(U_PARSE_ERROR); } version|=value; } if(start==0 && end==0x10ffff) { /* Also set bits for initialValue and errorValue. */ end=UPVEC_MAX_CP; } upvec_setValue(pv, start, end, 0, version<<UPROPS_AGE_SHIFT, UPROPS_AGE_MASK, pErrorCode); if(U_FAILURE(*pErrorCode)) { fprintf(stderr, "genprops error: unable to set character age: %s\n", u_errorName(*pErrorCode)); exit(*pErrorCode); } }
/* * Extract the setting after the '=' and store it in flag excluding the newline character. */ static int32_t extractFlag(char* buffer, int32_t bufferSize, char* flag, int32_t flagSize, const char **flagNames, int32_t numOfFlags, UErrorCode *status) { int32_t i, idx = -1; char *pBuffer; int32_t offset=0; UBool bufferWritten = FALSE; if (buffer[0] != 0) { /* Get the offset (i.e. position after the '=') */ offset = getFlagOffset(buffer, bufferSize); pBuffer = buffer+offset; for(i = 0;;i++) { if (i >= flagSize) { *status = U_BUFFER_OVERFLOW_ERROR; return -1; } if (pBuffer[i+1] == 0) { /* Indicates a new line character. End here. */ flag[i] = 0; break; } flag[i] = pBuffer[i]; if (i == 0) { bufferWritten = TRUE; } } } if (!bufferWritten) { flag[0] = 0; } if (flagNames != NULL && offset>0) { offset--; /* Move offset back 1 because of '='*/ for (i = 0; i < numOfFlags; i++) { if (uprv_strncmp(buffer, flagNames[i], offset) == 0) { idx = i; break; } } } return idx; }
static const char *udata_pathiter_next(UDataPathIterator *iter) { const char *path = NULL; uint32_t pathLen = 0; const char *pathBasename; do { if( iter->nextPath == NULL ) { break; } path = iter->nextPath; if(iter->nextPath == iter->itemPath) { /* we were processing item's path. */ iter->nextPath = iter->path; /* start with regular path next tm. */ pathLen = (int32_t)uprv_strlen(path); } else { /* fix up next for next time */ iter->nextPath = uprv_strchr(path, U_PATH_SEP_CHAR); if(iter->nextPath == NULL) { /* segment: entire path */ pathLen = (int32_t)uprv_strlen(path); } else { /* segment: until next segment */ pathLen = (int32_t)(iter->nextPath - path); if(*iter->nextPath) { /* skip divider */ iter->nextPath ++; } } } if(pathLen == 0) { continue; } #ifdef UDATA_DEBUG fprintf(stderr, "rest of path (IDD) = %s\n", path); fprintf(stderr, " "); { uint32_t qqq; for(qqq=0;qqq<pathLen;qqq++) { fprintf(stderr, " "); } fprintf(stderr, "^\n"); } #endif uprv_strncpy(iter->pathBuffer, path, pathLen); iter->pathBuffer[pathLen] = 0; /* check for .dat files */ pathBasename = findBasename(iter->pathBuffer); if(iter->checkLastFour == TRUE && (pathLen>=4) && uprv_strncmp(iter->pathBuffer +(pathLen-4),iter->suffix,4)==0 && /* suffix matches */ uprv_strncmp(findBasename(iter->pathBuffer),iter->basename,iter->basenameLen)==0 && /* base matches */ uprv_strlen(pathBasename)==(iter->basenameLen+4)) { /* base+suffix = full len */ #ifdef UDATA_DEBUG fprintf(stderr, "Have %s file on the path: %s\n", iter->suffix, iter->pathBuffer); #endif /* do nothing */ } else { /* regular dir path */ if(iter->pathBuffer[pathLen-1] != U_FILE_SEP_CHAR) { if((pathLen>=4) && uprv_strncmp(iter->pathBuffer+(pathLen-4), ".dat", 4) == 0) { #ifdef UDATA_DEBUG fprintf(stderr, "skipping non-directory .dat file %s\n", iter->pathBuffer); #endif continue; } /* Check if it is a directory with the same name as our package */ if(iter->packageStubLen && (pathLen > iter->packageStubLen) && !uprv_strcmp(iter->pathBuffer + pathLen - iter->packageStubLen, iter->packageStub)) { #ifdef UDATA_DEBUG fprintf(stderr, "Found stub %s ( will add package %s of len %d)\n", iter->packageStub, iter->basename, iter->basenameLen); #endif pathLen -= iter->packageStubLen; } iter->pathBuffer[pathLen++] = U_FILE_SEP_CHAR; } uprv_strncpy(iter->pathBuffer + pathLen, /* + basename */ iter->packageStub+1, iter->packageStubLen-1); pathLen += iter->packageStubLen-1; if(*iter->suffix) /* tack on suffix */ { uprv_strcpy(iter->pathBuffer + pathLen, iter->suffix); pathLen += (int32_t)uprv_strlen(iter->suffix); } } #ifdef UDATA_DEBUG fprintf(stderr, " --> %s\n", iter->pathBuffer); #endif return iter->pathBuffer; } while(iter->path); /* fell way off the end */ return NULL; }
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); }
//------------------------------------------------------------------------------- // // Read a text data file, convert it from UTF-8 to UChars, and return the data // in one big UChar * buffer, which the caller must delete. // // (Lightly modified version of a similar function in regextst.cpp) // //-------------------------------------------------------------------------------- UChar *DecimalFormatTest::ReadAndConvertFile(const char *fileName, int32_t &ulen, UErrorCode &status) { UChar *retPtr = NULL; char *fileBuf = NULL; const char *fileBufNoBOM = NULL; FILE *f = NULL; ulen = 0; if (U_FAILURE(status)) { return retPtr; } // // Open the file. // f = fopen(fileName, "rb"); if (f == 0) { dataerrln("Error opening test data file %s\n", fileName); status = U_FILE_ACCESS_ERROR; return NULL; } // // Read it in // int32_t fileSize; int32_t amtRead; int32_t amtReadNoBOM; fseek( f, 0, SEEK_END); fileSize = ftell(f); fileBuf = new char[fileSize]; fseek(f, 0, SEEK_SET); amtRead = fread(fileBuf, 1, fileSize, f); if (amtRead != fileSize || fileSize <= 0) { errln("Error reading test data file."); goto cleanUpAndReturn; } // // Look for a UTF-8 BOM on the data just read. // The test data file is UTF-8. // The BOM needs to be there in the source file to keep the Windows & // EBCDIC machines happy, so force an error if it goes missing. // Many Linux editors will silently strip it. // fileBufNoBOM = fileBuf + 3; amtReadNoBOM = amtRead - 3; if (fileSize<3 || uprv_strncmp(fileBuf, "\xEF\xBB\xBF", 3) != 0) { // TODO: restore this check. errln("Test data file %s is missing its BOM", fileName); fileBufNoBOM = fileBuf; amtReadNoBOM = amtRead; } // // Find the length of the input in UTF-16 UChars // (by preflighting the conversion) // u_strFromUTF8(NULL, 0, &ulen, fileBufNoBOM, amtReadNoBOM, &status); // // Convert file contents from UTF-8 to UTF-16 // if (status == U_BUFFER_OVERFLOW_ERROR) { // Buffer Overflow is expected from the preflight operation. status = U_ZERO_ERROR; retPtr = new UChar[ulen+1]; u_strFromUTF8(retPtr, ulen+1, NULL, fileBufNoBOM, amtReadNoBOM, &status); } cleanUpAndReturn: fclose(f); delete[] fileBuf; if (U_FAILURE(status)) { errln("ICU Error \"%s\"\n", u_errorName(status)); delete retPtr; retPtr = NULL; }; return retPtr; }
/* * state table row grammar (ebnf-style): * (whitespace is allowed between all tokens) * * row=[[firstentry ','] entry (',' entry)*] * firstentry="initial" | "surrogates" * (initial state (default for state 0), output is all surrogate pairs) * entry=range [':' nextstate] ['.' action] * range=number ['-' number] * nextstate=number * (0..7f) * action='u' | 's' | 'p' | 'i' * (unassigned, state change only, surrogate pair, illegal) * number=(1- or 2-digit hexadecimal number) */ static const char * parseState(const char *s, int32_t state[256], uint32_t *pFlags) { const char *t; uint32_t start, end, i; int32_t entry; /* initialize the state: all illegal with U+ffff */ for(i=0; i<256; ++i) { state[i]=MBCS_ENTRY_FINAL(0, MBCS_STATE_ILLEGAL, 0xffff); } /* skip leading white space */ s=u_skipWhitespace(s); /* is there an "initial" or "surrogates" directive? */ if(uprv_strncmp("initial", s, 7)==0) { *pFlags=MBCS_STATE_FLAG_DIRECT; s=u_skipWhitespace(s+7); if(*s++!=',') { return s-1; } } else if(*pFlags==0 && uprv_strncmp("surrogates", s, 10)==0) { *pFlags=MBCS_STATE_FLAG_SURROGATES; s=u_skipWhitespace(s+10); if(*s++!=',') { return s-1; } } else if(*s==0) { /* empty state row: all-illegal */ return NULL; } for(;;) { /* read an entry, the start of the range first */ s=u_skipWhitespace(s); start=uprv_strtoul(s, (char **)&t, 16); if(s==t || 0xff<start) { return s; } s=u_skipWhitespace(t); /* read the end of the range if there is one */ if(*s=='-') { s=u_skipWhitespace(s+1); end=uprv_strtoul(s, (char **)&t, 16); if(s==t || end<start || 0xff<end) { return s; } s=u_skipWhitespace(t); } else { end=start; } /* determine the state entrys for this range */ if(*s!=':' && *s!='.') { /* the default is: final state with valid entries */ entry=MBCS_ENTRY_FINAL(0, MBCS_STATE_VALID_16, 0); } else { entry=MBCS_ENTRY_TRANSITION(0, 0); if(*s==':') { /* get the next state, default to 0 */ s=u_skipWhitespace(s+1); i=uprv_strtoul(s, (char **)&t, 16); if(s!=t) { if(0x7f<i) { return s; } s=u_skipWhitespace(t); entry=MBCS_ENTRY_SET_STATE(entry, i); } } /* get the state action, default to valid */ if(*s=='.') { /* this is a final state */ entry=MBCS_ENTRY_SET_FINAL(entry); s=u_skipWhitespace(s+1); if(*s=='u') { /* unassigned set U+fffe */ entry=MBCS_ENTRY_FINAL_SET_ACTION_VALUE(entry, MBCS_STATE_UNASSIGNED, 0xfffe); s=u_skipWhitespace(s+1); } else if(*s=='p') { if(*pFlags!=MBCS_STATE_FLAG_DIRECT) { entry=MBCS_ENTRY_FINAL_SET_ACTION(entry, MBCS_STATE_VALID_16_PAIR); } else { entry=MBCS_ENTRY_FINAL_SET_ACTION(entry, MBCS_STATE_VALID_16); } s=u_skipWhitespace(s+1); } else if(*s=='s') { entry=MBCS_ENTRY_FINAL_SET_ACTION(entry, MBCS_STATE_CHANGE_ONLY); s=u_skipWhitespace(s+1); } else if(*s=='i') { /* illegal set U+ffff */ entry=MBCS_ENTRY_FINAL_SET_ACTION_VALUE(entry, MBCS_STATE_ILLEGAL, 0xffff); s=u_skipWhitespace(s+1); } else { /* default to valid */ entry=MBCS_ENTRY_FINAL_SET_ACTION(entry, MBCS_STATE_VALID_16); } } else { /* this is an intermediate state, nothing to do */ } } /* adjust "final valid" states according to the state flags */ if(MBCS_ENTRY_FINAL_ACTION(entry)==MBCS_STATE_VALID_16) { switch(*pFlags) { case 0: /* no adjustment */ break; case MBCS_STATE_FLAG_DIRECT: /* set the valid-direct code point to "unassigned"==0xfffe */ entry=MBCS_ENTRY_FINAL_SET_ACTION_VALUE(entry, MBCS_STATE_VALID_DIRECT_16, 0xfffe); break; case MBCS_STATE_FLAG_SURROGATES: entry=MBCS_ENTRY_FINAL_SET_ACTION_VALUE(entry, MBCS_STATE_VALID_16_PAIR, 0); break; default: break; } } /* set this entry for the range */ for(i=start; i<=end; ++i) { state[i]=entry; } if(*s==',') { ++s; } else { return *s==0 ? NULL : s; } } }
U_CAPI const char* U_EXPORT2 uprv_tzname(int n) { #ifdef U_WINDOWS const char *id = uprv_detectWindowsTimeZone(); if (id != NULL) { return id; } #else const char *tzenv = NULL; /*#if defined(U_DARWIN) int ret; tzenv = getenv("TZFILE"); if (tzenv != NULL) { return tzenv; } #endif*/ tzenv = getenv("TZ"); if (tzenv != NULL && isValidOlsonID(tzenv)) { /* This might be a good Olson ID. */ if (uprv_strncmp(tzenv, "posix/", 6) == 0 || uprv_strncmp(tzenv, "right/", 6) == 0) { /* Remove the posix/ or right/ prefix. */ tzenv += 6; } return tzenv; } /* else U_TZNAME will give a better result. */ #if defined(CHECK_LOCALTIME_LINK) /* Caller must handle threading issues */ if (gTimeZoneBufferPtr == NULL) { /* This is a trick to look at the name of the link to get the Olson ID because the tzfile contents is underspecified. This isn't guaranteed to work because it may not be a symlink. */ int32_t ret = (int32_t)readlink(TZZONELINK, gTimeZoneBuffer, sizeof(gTimeZoneBuffer)); if (0 < ret) { int32_t tzZoneInfoLen = uprv_strlen(TZZONEINFO); gTimeZoneBuffer[ret] = 0; if (uprv_strncmp(gTimeZoneBuffer, TZZONEINFO, tzZoneInfoLen) == 0 && isValidOlsonID(gTimeZoneBuffer + tzZoneInfoLen)) { return (gTimeZoneBufferPtr = gTimeZoneBuffer + tzZoneInfoLen); } } } else { return gTimeZoneBufferPtr; } #endif #endif #ifdef U_TZNAME /* U_TZNAME is usually a non-unique abbreviation, which isn't normally usable. */ return U_TZNAME[n]; #else return ""; #endif }
/* NOTE: The caller should handle thread safety */ U_CAPI const char* U_EXPORT2 uprv_getDefaultLocaleID() { #if U_POSIX_LOCALE /* Note that: (a '!' means the ID is improper somehow) LC_ALL ----> default_loc codepage -------------------------------------------------------- ab.CD ab CD ab@CD ab__CD - [email protected] ab__CD EF ab_CD.EF@GH ab_CD_GH EF Some 'improper' ways to do the same as above: ! [email protected] ab_CD_GH EF ! [email protected] ab_CD_GH EF ! [email protected]@GH.IJ ab_CD_GH EF _CD@GH _CD_GH - _CD.EF@GH _CD_GH EF The variant cannot have dots in it. The 'rightmost' variant (@xxx) wins. The leftmost codepage (.xxx) wins. */ char *correctedPOSIXLocale = 0; const char* posixID = uprv_getPOSIXID(); const char *p; const char *q; int32_t len; /* Format: (no spaces) ll [ _CC ] [ . MM ] [ @ VV] l = lang, C = ctry, M = charmap, V = variant */ if (gCorrectedPOSIXLocale != NULL) { return gCorrectedPOSIXLocale; } if ((p = uprv_strchr(posixID, '.')) != NULL) { /* assume new locale can't be larger than old one? */ correctedPOSIXLocale = (char*) uprv_malloc(uprv_strlen(posixID)+1); uprv_strncpy(correctedPOSIXLocale, posixID, p-posixID); correctedPOSIXLocale[p-posixID] = 0; /* do not copy after the @ */ if ((p = uprv_strchr(correctedPOSIXLocale, '@')) != NULL) { correctedPOSIXLocale[p-correctedPOSIXLocale] = 0; } } /* Note that we scan the *uncorrected* ID. */ if ((p = uprv_strrchr(posixID, '@')) != NULL) { if (correctedPOSIXLocale == NULL) { correctedPOSIXLocale = (char*) uprv_malloc(uprv_strlen(posixID)+1); uprv_strncpy(correctedPOSIXLocale, posixID, p-posixID); correctedPOSIXLocale[p-posixID] = 0; } p++; /* Take care of any special cases here.. */ if (!uprv_strcmp(p, "nynorsk")) { p = "NY"; /* Don't worry about no__NY. In practice, it won't appear. */ } if (uprv_strchr(correctedPOSIXLocale,'_') == NULL) { uprv_strcat(correctedPOSIXLocale, "__"); /* aa@b -> aa__b */ } else { uprv_strcat(correctedPOSIXLocale, "_"); /* aa_CC@b -> aa_CC_b */ } if ((q = uprv_strchr(p, '.')) != NULL) { /* How big will the resulting string be? */ len = (int32_t)(uprv_strlen(correctedPOSIXLocale) + (q-p)); uprv_strncat(correctedPOSIXLocale, p, q-p); correctedPOSIXLocale[len] = 0; } else { /* Anything following the @ sign */ uprv_strcat(correctedPOSIXLocale, p); } /* Should there be a map from 'no@nynorsk' -> no_NO_NY here? * How about 'russian' -> 'ru'? * Many of the other locales using ISO codes will be handled by the * canonicalization functions in uloc_getDefault. */ } /* Was a correction made? */ if (correctedPOSIXLocale != NULL) { posixID = correctedPOSIXLocale; } else { /* copy it, just in case the original pointer goes away. See j2395 */ correctedPOSIXLocale = (char *)uprv_malloc(uprv_strlen(posixID) + 1); posixID = uprv_strcpy(correctedPOSIXLocale, posixID); } if (gCorrectedPOSIXLocale == NULL) { gCorrectedPOSIXLocale = correctedPOSIXLocale; ucln_common_registerCleanup(UCLN_COMMON_PUTIL, putil_cleanup); correctedPOSIXLocale = NULL; } if (correctedPOSIXLocale != NULL) { /* Was already set - clean up. */ uprv_free(correctedPOSIXLocale); } return posixID; #elif defined(U_WINDOWS) UErrorCode status = U_ZERO_ERROR; LCID id = GetThreadLocale(); const char* locID = uprv_convertToPosix(id, &status); if (U_FAILURE(status)) { locID = "en_US"; } return locID; #elif defined(XP_MAC) int32_t script = MAC_LC_INIT_NUMBER; /* = IntlScript(); or GetScriptManagerVariable(smSysScript);*/ int32_t region = MAC_LC_INIT_NUMBER; /* = GetScriptManagerVariable(smRegionCode);*/ int32_t lang = MAC_LC_INIT_NUMBER; /* = GetScriptManagerVariable(smScriptLang);*/ int32_t date_region = MAC_LC_INIT_NUMBER; const char* posixID = 0; int32_t count = sizeof(mac_lc_recs) / sizeof(mac_lc_rec); int32_t i; Intl1Hndl ih; ih = (Intl1Hndl) GetIntlResource(1); if (ih) date_region = ((uint16_t)(*ih)->intl1Vers) >> 8; for (i = 0; i < count; i++) { if ( ((mac_lc_recs[i].script == MAC_LC_MAGIC_NUMBER) || (mac_lc_recs[i].script == script)) && ((mac_lc_recs[i].region == MAC_LC_MAGIC_NUMBER) || (mac_lc_recs[i].region == region)) && ((mac_lc_recs[i].lang == MAC_LC_MAGIC_NUMBER) || (mac_lc_recs[i].lang == lang)) && ((mac_lc_recs[i].date_region == MAC_LC_MAGIC_NUMBER) || (mac_lc_recs[i].date_region == date_region)) ) { posixID = mac_lc_recs[i].posixID; break; } } return posixID; #elif defined(OS400) /* locales are process scoped and are by definition thread safe */ static char correctedLocale[64]; const char *localeID = getenv("LC_ALL"); char *p; if (localeID == NULL) localeID = getenv("LANG"); if (localeID == NULL) localeID = setlocale(LC_ALL, NULL); /* Make sure we have something... */ if (localeID == NULL) return "en_US_POSIX"; /* Extract the locale name from the path. */ if((p = uprv_strrchr(localeID, '/')) != NULL) { /* Increment p to start of locale name. */ p++; localeID = p; } /* Copy to work location. */ uprv_strcpy(correctedLocale, localeID); /* Strip off the '.locale' extension. */ if((p = uprv_strchr(correctedLocale, '.')) != NULL) { *p = 0; } /* Upper case the locale name. */ T_CString_toUpperCase(correctedLocale); /* See if we are using the POSIX locale. Any of the * following are equivalent and use the same QLGPGCMA * (POSIX) locale. * QLGPGCMA2 means UCS2 * QLGPGCMA_4 means UTF-32 * QLGPGCMA_8 means UTF-8 */ if ((uprv_strcmp("C", correctedLocale) == 0) || (uprv_strcmp("POSIX", correctedLocale) == 0) || (uprv_strncmp("QLGPGCMA", correctedLocale, 8) == 0)) { uprv_strcpy(correctedLocale, "en_US_POSIX"); } else { int16_t LocaleLen; /* Lower case the lang portion. */ for(p = correctedLocale; *p != 0 && *p != '_'; p++) { *p = uprv_tolower(*p); } /* Adjust for Euro. After '_E' add 'URO'. */ LocaleLen = uprv_strlen(correctedLocale); if (correctedLocale[LocaleLen - 2] == '_' && correctedLocale[LocaleLen - 1] == 'E') { uprv_strcat(correctedLocale, "URO"); } /* If using Lotus-based locale then convert to * equivalent non Lotus. */ else if (correctedLocale[LocaleLen - 2] == '_' && correctedLocale[LocaleLen - 1] == 'L') { correctedLocale[LocaleLen - 2] = 0; } /* There are separate simplified and traditional * locales called zh_HK_S and zh_HK_T. */ else if (uprv_strncmp(correctedLocale, "zh_HK", 5) == 0) { uprv_strcpy(correctedLocale, "zh_HK"); } /* A special zh_CN_GBK locale... */ else if (uprv_strcmp(correctedLocale, "zh_CN_GBK") == 0) { uprv_strcpy(correctedLocale, "zh_CN"); } } return correctedLocale; #endif }
static void TestGetKeywordValuesForLocale(void) { #define PREFERRED_SIZE 15 #define MAX_NUMBER_OF_KEYWORDS 4 const char *PREFERRED[PREFERRED_SIZE][MAX_NUMBER_OF_KEYWORDS] = { { "root", "USD", "USN", NULL }, { "und", "USD", "USN", NULL }, /* { "und_ZZ", "USD", NULL, NULL }, -- temporarily remove as this locale now has 15 entries */ { "en_US", "USD", "USN", NULL }, { "en_029", "USD", "USN", NULL }, { "en_TH", "THB", NULL, NULL }, { "de", "EUR", NULL, NULL }, { "de_DE", "EUR", NULL, NULL }, { "ar", "EGP", NULL, NULL }, { "ar_PS", "ILS", "JOD", NULL }, { "en@currency=CAD", "USD", "USN", NULL }, { "fr@currency=zzz", "EUR", NULL, NULL }, { "de_DE@currency=DEM", "EUR", NULL, NULL }, { "en_US@rg=THZZZZ", "THB", NULL, NULL }, { "de@rg=USZZZZ", "USD", "USN", NULL }, { "en_US@currency=CAD;rg=THZZZZ", "THB", NULL, NULL }, }; const int32_t EXPECTED_SIZE[PREFERRED_SIZE] = { 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 2, 1 }; /* ucurr_forLocale results for same locales; "" if no result expected */ const char *FORLOCALE[PREFERRED_SIZE] = { "", "", "USD", "", "THB", "", "EUR", "", "ILS", "CAD", "ZZZ", "DEM", "THB", "USD", "CAD" }; UErrorCode status = U_ZERO_ERROR; int32_t i, j, size; UEnumeration *pref, *all; const char *loc = NULL; UBool matchPref, matchAll; const char *value = NULL; int32_t valueLength = 0; UList *ALLList = NULL; UEnumeration *ALL = ucurr_getKeywordValuesForLocale("currency", uloc_getDefault(), FALSE, &status); if (ALL == NULL) { log_err_status(status, "ERROR getting keyword value for default locale. -> %s\n", u_errorName(status)); return; } for (i = 0; i < PREFERRED_SIZE; i++) { UChar getCurrU[4]; int32_t getCurrLen; status = U_ZERO_ERROR; pref = NULL; all = NULL; loc = PREFERRED[i][0]; pref = ucurr_getKeywordValuesForLocale("currency", loc, TRUE, &status); matchPref = FALSE; matchAll = FALSE; size = uenum_count(pref, &status); if (size == EXPECTED_SIZE[i]) { matchPref = TRUE; for (j = 0; j < size; j++) { if ((value = uenum_next(pref, &valueLength, &status)) != NULL && U_SUCCESS(status)) { if (uprv_strcmp(value, PREFERRED[i][j+1]) != 0) { log_err("ERROR: locale %s got keywords #%d %s expected %s\n", loc, j, value, PREFERRED[i][j+1]); matchPref = FALSE; break; } } else { matchPref = FALSE; log_err("ERROR getting keyword value for locale \"%s\"\n", loc); break; } } } else { log_err("FAIL: size of locale \"%s\" %d does not match expected size %d\n", loc, size, EXPECTED_SIZE[i]); } if (!matchPref) { log_err("FAIL: Preferred values for locale \"%s\" does not match expected.\n", loc); break; } uenum_close(pref); all = ucurr_getKeywordValuesForLocale("currency", loc, FALSE, &status); size = uenum_count(all, &status); if (U_SUCCESS(status) && size == uenum_count(ALL, &status)) { matchAll = TRUE; ALLList = ulist_getListFromEnum(ALL); for (j = 0; j < size; j++) { if ((value = uenum_next(all, &valueLength, &status)) != NULL && U_SUCCESS(status)) { if (!ulist_containsString(ALLList, value, uprv_strlen(value))) { log_err("Locale %s have %s not in ALL\n", loc, value); matchAll = FALSE; break; } } else { matchAll = FALSE; log_err("ERROR getting \"all\" keyword value for locale \"%s\"\n", loc); break; } } if (!matchAll) { log_err("FAIL: All values for locale \"%s\" does not match expected.\n", loc); } } else { if(U_FAILURE(status)) { log_err("ERROR: %s\n", u_errorName(status)); } else if(size!=uenum_count(ALL, &status)) { log_err("ERROR: got size of %d, wanted %d\n", size, uenum_count(ALL, &status)); } } uenum_close(all); status = U_ZERO_ERROR; getCurrLen = ucurr_forLocale(loc, getCurrU, 4, &status); if(U_FAILURE(status)) { if (FORLOCALE[i][0] != 0) { log_err("ERROR: ucurr_forLocale %s, status %s\n", loc, u_errorName(status)); } } else if (getCurrLen != 3) { if (FORLOCALE[i][0] != 0 || getCurrLen != -1) { log_err("ERROR: ucurr_forLocale %s, returned len %d\n", loc, getCurrLen); } } else { char getCurrB[4]; u_UCharsToChars(getCurrU, getCurrB, 4); if ( uprv_strncmp(getCurrB, FORLOCALE[i], 4) != 0 ) { log_err("ERROR: ucurr_forLocale %s, expected %s, got %s\n", loc, FORLOCALE[i], getCurrB); } } } uenum_close(ALL); }
static UDataMemory * doOpenChoice(const char *path, const char *type, const char *name, UDataMemoryIsAcceptable *isAcceptable, void *context, UErrorCode *pErrorCode) { UDataMemory *retVal = NULL; TinyString tocEntryName; /* entry name in tree format. ex: 'icudt28b/coll/ar.res' */ TinyString tocEntryPath; /* entry name in path format. ex: 'icudt28b\\coll\\ar.res' */ TinyString pkgName; TinyString treeName; #if (U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR) /* '/' vs '\' */ TinyString altSepPath; #endif const char *dataPath; int32_t tocEntrySuffixIndex; const char *tocEntryPathSuffix; UErrorCode subErrorCode=U_ZERO_ERROR; const char *treeChar; UBool isICUData = FALSE; /* Is this path ICU data? */ if(path == NULL || !strcmp(path, U_ICUDATA_ALIAS) || /* "ICUDATA" */ !uprv_strncmp(path, U_ICUDATA_NAME U_TREE_SEPARATOR_STRING, /* "icudt26e-" */ uprv_strlen(U_ICUDATA_NAME U_TREE_SEPARATOR_STRING)) || !uprv_strncmp(path, U_ICUDATA_ALIAS U_TREE_SEPARATOR_STRING, /* "ICUDATA-" */ uprv_strlen(U_ICUDATA_ALIAS U_TREE_SEPARATOR_STRING))) { isICUData = TRUE; } #if (U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR) /* Windows: try "foo\bar" and "foo/bar" */ /* remap from alternate path char to the main one */ TinyString_init(&altSepPath); if(path) { char *p; if((p=uprv_strchr(path,U_FILE_ALT_SEP_CHAR))) { TinyString_append(&altSepPath, path); while((p=uprv_strchr(altSepPath.s,U_FILE_ALT_SEP_CHAR))) { *p = U_FILE_SEP_CHAR; } #if defined (UDATA_DEBUG) fprintf(stderr, "Changed path from [%s] to [%s]\n", path, altSepPath.s); #endif path = altSepPath.s; } } #endif TinyString_init(&tocEntryName); TinyString_init(&tocEntryPath); TinyString_init(&pkgName); TinyString_init(&treeName); /* ======= Set up strings */ if(path==NULL) { TinyString_append(&pkgName, U_ICUDATA_NAME); } else { const char *pkg; const char *first; pkg = uprv_strrchr(path, U_FILE_SEP_CHAR); first = uprv_strchr(path, U_FILE_SEP_CHAR); if(uprv_pathIsAbsolute(path) || (pkg != first)) { /* more than one slash in the path- not a tree name */ /* see if this is an /absolute/path/to/package path */ if(pkg) { TinyString_append(&pkgName, pkg+1); } else { TinyString_append(&pkgName, path); } } else { treeChar = uprv_strchr(path, U_TREE_SEPARATOR); if(treeChar) { TinyString_append(&treeName, treeChar+1); /* following '-' */ if(isICUData) { TinyString_append(&pkgName, U_ICUDATA_NAME); } else { TinyString_appendn(&pkgName, path, (int32_t)(treeChar-path)); if (first == NULL) { /* This user data has no path, but there is a tree name. Look up the correct path from the data cache later. */ path = pkgName.s; } } } else { if(isICUData) { TinyString_append(&pkgName, U_ICUDATA_NAME); } else { TinyString_append(&pkgName, path); } } } } #ifdef UDATA_DEBUG fprintf(stderr, " P=%s T=%s\n", pkgName.s, treeName.s); #endif /* setting up the entry name and file name * Make up a full name by appending the type to the supplied * name, assuming that a type was supplied. */ /* prepend the package */ TinyString_append(&tocEntryName, pkgName.s); TinyString_append(&tocEntryPath, pkgName.s); tocEntrySuffixIndex = tocEntryName.length; if(treeName.s[0]) { TinyString_append(&tocEntryName, U_TREE_ENTRY_SEP_STRING); TinyString_append(&tocEntryName, treeName.s); TinyString_append(&tocEntryPath, U_FILE_SEP_STRING); TinyString_append(&tocEntryPath, treeName.s); } TinyString_append(&tocEntryName, U_TREE_ENTRY_SEP_STRING); TinyString_append(&tocEntryPath, U_FILE_SEP_STRING); TinyString_append(&tocEntryName, name); TinyString_append(&tocEntryPath, name); if(type!=NULL && *type!=0) { TinyString_append(&tocEntryName, "."); TinyString_append(&tocEntryName, type); TinyString_append(&tocEntryPath, "."); TinyString_append(&tocEntryPath, type); } tocEntryPathSuffix = tocEntryPath.s+tocEntrySuffixIndex; /* suffix starts here */ #ifdef UDATA_DEBUG fprintf(stderr, " tocEntryName = %s\n", tocEntryName.s); fprintf(stderr, " tocEntryPath = %s\n", tocEntryName.s); #endif if(path == NULL) { path = COMMON_DATA_NAME; /* "icudt26e" */ } /************************ Begin loop looking for ind. files ***************/ #ifdef UDATA_DEBUG fprintf(stderr, "IND: inBasename = %s, pkg=%s\n", "(n/a)", packageNameFromPath(path)); #endif /* End of dealing with a null basename */ dataPath = u_getDataDirectory(); /**** COMMON PACKAGE - only if packages are first. */ if(gDataFileAccess == UDATA_PACKAGES_FIRST) { #ifdef UDATA_DEBUG fprintf(stderr, "Trying packages (UDATA_PACKAGES_FIRST)\n"); #endif /* #2 */ retVal = doLoadFromCommonData(isICUData, pkgName.s, dataPath, tocEntryPathSuffix, tocEntryName.s, path, type, name, isAcceptable, context, &subErrorCode, pErrorCode); if((retVal != NULL) || U_FAILURE(*pErrorCode)) { goto commonReturn; } } /**** INDIVIDUAL FILES */ if((gDataFileAccess==UDATA_PACKAGES_FIRST) || (gDataFileAccess==UDATA_FILES_FIRST)) { #ifdef UDATA_DEBUG fprintf(stderr, "Trying individual files\n"); #endif /* Check to make sure that there is a dataPath to iterate over */ if ((dataPath && *dataPath) || !isICUData) { retVal = doLoadFromIndividualFiles(pkgName.s, dataPath, tocEntryPathSuffix, path, type, name, isAcceptable, context, &subErrorCode, pErrorCode); if((retVal != NULL) || U_FAILURE(*pErrorCode)) { goto commonReturn; } } } /**** COMMON PACKAGE */ if((gDataFileAccess==UDATA_ONLY_PACKAGES) || (gDataFileAccess==UDATA_FILES_FIRST)) { #ifdef UDATA_DEBUG fprintf(stderr, "Trying packages (UDATA_ONLY_PACKAGES || UDATA_FILES_FIRST)\n"); #endif retVal = doLoadFromCommonData(isICUData, pkgName.s, dataPath, tocEntryPathSuffix, tocEntryName.s, path, type, name, isAcceptable, context, &subErrorCode, pErrorCode); if((retVal != NULL) || U_FAILURE(*pErrorCode)) { goto commonReturn; } } /* Load from DLL. If we haven't attempted package load, we also haven't had any chance to try a DLL (static or setCommonData/etc) load. If we ever have a "UDATA_ONLY_FILES", add it to the or list here. */ if(gDataFileAccess==UDATA_NO_FILES) { #ifdef UDATA_DEBUG fprintf(stderr, "Trying common data (UDATA_NO_FILES)\n"); #endif retVal = doLoadFromCommonData(isICUData, pkgName.s, "", tocEntryPathSuffix, tocEntryName.s, path, type, name, isAcceptable, context, &subErrorCode, pErrorCode); if((retVal != NULL) || U_FAILURE(*pErrorCode)) { goto commonReturn; } } /* data not found */ if(U_SUCCESS(*pErrorCode)) { if(U_SUCCESS(subErrorCode)) { /* file not found */ *pErrorCode=U_FILE_ACCESS_ERROR; } else { /* entry point not found or rejected */ *pErrorCode=subErrorCode; } } commonReturn: TinyString_dt(&tocEntryName); TinyString_dt(&tocEntryPath); TinyString_dt(&pkgName); TinyString_dt(&treeName); #if (U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR) TinyString_dt(&altSepPath); #endif return retVal; }
UHashtable* ZoneMeta::createMetaToOlsonMap(void) { UErrorCode status = U_ZERO_ERROR; UHashtable *metaToOlson = NULL; UResourceBundle *metazones = NULL; UResourceBundle *mz = NULL; metaToOlson = uhash_open(uhash_hashUChars, uhash_compareUChars, NULL, &status); if (U_FAILURE(status)) { return NULL; } uhash_setKeyDeleter(metaToOlson, deleteUCharString); uhash_setValueDeleter(metaToOlson, deleteUVector); metazones = ures_openDirect(NULL, gSupplementalData, &status); metazones = ures_getByKey(metazones, gMapTimezonesTag, metazones, &status); metazones = ures_getByKey(metazones, gMetazonesTag, metazones, &status); if (U_FAILURE(status)) { goto error_cleanup; } while (ures_hasNext(metazones)) { mz = ures_getNextResource(metazones, mz, &status); if (U_FAILURE(status)) { status = U_ZERO_ERROR; continue; } const char *mzkey = ures_getKey(mz); if (uprv_strncmp(mzkey, gMetazoneIdPrefix, MZID_PREFIX_LEN) == 0) { const char *mzid = mzkey + MZID_PREFIX_LEN; const char *territory = uprv_strrchr(mzid, '_'); int32_t mzidLen = 0; int32_t territoryLen = 0; if (territory) { mzidLen = territory - mzid; territory++; territoryLen = uprv_strlen(territory); } if (mzidLen > 0 && territoryLen > 0) { int32_t tzidLen; const UChar *tzid = ures_getStringByIndex(mz, 0, &tzidLen, &status); if (U_SUCCESS(status)) { // Create MetaToOlsonMappingEntry MetaToOlsonMappingEntry *entry = (MetaToOlsonMappingEntry*)uprv_malloc(sizeof(MetaToOlsonMappingEntry)); if (entry == NULL) { status = U_MEMORY_ALLOCATION_ERROR; goto error_cleanup; } entry->id = tzid; entry->territory = (UChar*)uprv_malloc((territoryLen + 1) * sizeof(UChar)); if (entry->territory == NULL) { status = U_MEMORY_ALLOCATION_ERROR; uprv_free(entry); goto error_cleanup; } u_charsToUChars(territory, entry->territory, territoryLen + 1); // Check if mapping entries for metazone is already available if (mzidLen < ZID_KEY_MAX) { UChar mzidUChars[ZID_KEY_MAX]; u_charsToUChars(mzid, mzidUChars, mzidLen); mzidUChars[mzidLen++] = 0; // Add NUL terminator UVector *tzMappings = (UVector*)uhash_get(metaToOlson, mzidUChars); if (tzMappings == NULL) { // Create new UVector and put it into the hashtable tzMappings = new UVector(deleteMetaToOlsonMappingEntry, NULL, status); if (U_FAILURE(status)) { deleteMetaToOlsonMappingEntry(entry); goto error_cleanup; } UChar *key = (UChar*)uprv_malloc(mzidLen * sizeof(UChar)); if (key == NULL) { status = U_MEMORY_ALLOCATION_ERROR; delete tzMappings; deleteMetaToOlsonMappingEntry(entry); goto error_cleanup; } u_strncpy(key, mzidUChars, mzidLen); uhash_put(metaToOlson, key, tzMappings, &status); if (U_FAILURE(status)) { goto error_cleanup; } } tzMappings->addElement(entry, status); if (U_FAILURE(status)) { goto error_cleanup; } } else { deleteMetaToOlsonMappingEntry(entry); } } else { status = U_ZERO_ERROR; } } } } normal_cleanup: ures_close(mz); ures_close(metazones); return metaToOlson; error_cleanup: if (metaToOlson != NULL) { uhash_close(metaToOlson); metaToOlson = NULL; } goto normal_cleanup; }
static void U_CALLCONV strprepProfileLineFn(void *context, char *fields[][2], int32_t fieldCount, UErrorCode *pErrorCode) { uint32_t mapping[40]; char *end, *map; uint32_t code; int32_t length; /*UBool* mapWithNorm = (UBool*) context;*/ const char* typeName; uint32_t rangeStart=0,rangeEnd =0; const char* filename = (const char*) context; const char *s; s = u_skipWhitespace(fields[0][0]); if (*s == '@') { /* special directive */ s++; length = fields[0][1] - s; if (length >= NORMALIZE_DIRECTIVE_LEN && uprv_strncmp(s, NORMALIZE_DIRECTIVE, NORMALIZE_DIRECTIVE_LEN) == 0) { options[NORMALIZE].doesOccur = TRUE; return; } else if (length >= CHECK_BIDI_DIRECTIVE_LEN && uprv_strncmp(s, CHECK_BIDI_DIRECTIVE, CHECK_BIDI_DIRECTIVE_LEN) == 0) { options[CHECK_BIDI].doesOccur = TRUE; return; } else { fprintf(stderr, "gensprep error parsing a directive %s.", fields[0][0]); } } typeName = fields[2][0]; map = fields[1][0]; if(uprv_strstr(typeName, usprepTypeNames[USPREP_UNASSIGNED])!=NULL){ u_parseCodePointRange(s, &rangeStart,&rangeEnd, pErrorCode); if(U_FAILURE(*pErrorCode)){ fprintf(stderr, "Could not parse code point range. Error: %s\n",u_errorName(*pErrorCode)); return; } /* store the range */ storeRange(rangeStart,rangeEnd,USPREP_UNASSIGNED, pErrorCode); }else if(uprv_strstr(typeName, usprepTypeNames[USPREP_PROHIBITED])!=NULL){ u_parseCodePointRange(s, &rangeStart,&rangeEnd, pErrorCode); if(U_FAILURE(*pErrorCode)){ fprintf(stderr, "Could not parse code point range. Error: %s\n",u_errorName(*pErrorCode)); return; } /* store the range */ storeRange(rangeStart,rangeEnd,USPREP_PROHIBITED, pErrorCode); }else if(uprv_strstr(typeName, usprepTypeNames[USPREP_MAP])!=NULL){ /* get the character code, field 0 */ code=(uint32_t)uprv_strtoul(s, &end, 16); if(end<=s || end!=fields[0][1]) { fprintf(stderr, "gensprep: syntax error in field 0 at %s\n", fields[0][0]); *pErrorCode=U_PARSE_ERROR; exit(U_PARSE_ERROR); } /* parse the mapping string */ length=u_parseCodePoints(map, mapping, sizeof(mapping)/4, pErrorCode); /* store the mapping */ storeMapping(code,mapping, length,USPREP_MAP, pErrorCode); }else{ *pErrorCode = U_INVALID_FORMAT_ERROR; } if(U_FAILURE(*pErrorCode)) { fprintf(stderr, "gensprep error parsing %s line %s at %s. Error: %s\n",filename, fields[0][0],fields[2][0],u_errorName(*pErrorCode)); exit(*pErrorCode); } }
U_CAPI int32_t U_EXPORT2 ualoc_getAppleParent(const char* localeID, char * parent, int32_t parentCapacity, UErrorCode* err) { UResourceBundle *rb; int32_t len; UErrorCode tempStatus; char locbuf[ULOC_FULLNAME_CAPACITY+1]; char * foundDoubleUnderscore; if (U_FAILURE(*err)) { return 0; } if ( (parent==NULL)? parentCapacity!=0: parentCapacity<0 ) { *err = U_ILLEGAL_ARGUMENT_ERROR; return 0; } len = uloc_getBaseName(localeID, locbuf, ULOC_FULLNAME_CAPACITY, err); /* canonicalize and strip keywords */ if (U_FAILURE(*err)) { return 0; } if (*err == U_STRING_NOT_TERMINATED_WARNING) { locbuf[ULOC_FULLNAME_CAPACITY] = 0; *err = U_ZERO_ERROR; } foundDoubleUnderscore = uprv_strstr(locbuf, "__"); /* __ comes from bad/missing subtag or variant */ if (foundDoubleUnderscore != NULL) { *foundDoubleUnderscore = 0; /* terminate at the __ */ len = uprv_strlen(locbuf); } if (len >= 2 && uprv_strncmp(locbuf, "zh", 2) == 0) { const char ** forceParentPtr = forceParent; const char * testCurLoc; while ( (testCurLoc = *forceParentPtr++) != NULL ) { int cmp = uprv_strcmp(locbuf, testCurLoc); if (cmp <= 0) { if (cmp == 0) { len = uprv_strlen(*forceParentPtr); if (len < parentCapacity) { uprv_strcpy(parent, *forceParentPtr); } else { *err = U_BUFFER_OVERFLOW_ERROR; } return len; } break; } forceParentPtr++; } } tempStatus = U_ZERO_ERROR; rb = ures_openDirect(NULL, locbuf, &tempStatus); if (U_SUCCESS(tempStatus)) { const char * actualLocale = ures_getLocaleByType(rb, ULOC_ACTUAL_LOCALE, &tempStatus); if (U_SUCCESS(tempStatus) && uprv_strcmp(locbuf, actualLocale) != 0) { // we have followed an alias len = uprv_strlen(actualLocale); if (len < parentCapacity) { uprv_strcpy(parent, actualLocale); } else { *err = U_BUFFER_OVERFLOW_ERROR; } ures_close(rb); return len; } tempStatus = U_ZERO_ERROR; const UChar * parentUName = ures_getStringByKey(rb, "%%Parent", &len, &tempStatus); if (U_SUCCESS(tempStatus) && tempStatus != U_USING_FALLBACK_WARNING) { if (len < parentCapacity) { u_UCharsToChars(parentUName, parent, len + 1); } else { *err = U_BUFFER_OVERFLOW_ERROR; } ures_close(rb); return len; } ures_close(rb); } len = uloc_getParent(locbuf, parent, parentCapacity, err); if (U_SUCCESS(*err) && len == 0) { len = 4; if (len < parentCapacity) { uprv_strcpy(parent, "root"); } else { *err = U_BUFFER_OVERFLOW_ERROR; } } return len; }
static void parseConverterOptions(const char *inName, char *cnvName, char *locale, uint32_t *pFlags, UErrorCode *err) { char c; int32_t len = 0; /* copy the converter name itself to cnvName */ while((c=*inName)!=0 && c!=UCNV_OPTION_SEP_CHAR) { if (++len>=UCNV_MAX_CONVERTER_NAME_LENGTH) { *err = U_ILLEGAL_ARGUMENT_ERROR; /* bad name */ *cnvName=0; return; } *cnvName++=c; inName++; } *cnvName=0; /* parse options. No more name copying should occur. */ while((c=*inName)!=0) { if(c==UCNV_OPTION_SEP_CHAR) { ++inName; } /* inName is behind an option separator */ if(uprv_strncmp(inName, "locale=", 7)==0) { /* do not modify locale itself in case we have multiple locale options */ char *dest=locale; /* copy the locale option value */ inName+=7; len=0; while((c=*inName)!=0 && c!=UCNV_OPTION_SEP_CHAR) { ++inName; if(++len>=ULOC_FULLNAME_CAPACITY) { *err=U_ILLEGAL_ARGUMENT_ERROR; /* bad name */ *locale=0; return; } *dest++=c; } *dest=0; } else if(uprv_strncmp(inName, "version=", 8)==0) { /* copy the version option value into bits 3..0 of *pFlags */ inName+=8; c=*inName; if(c==0) { *pFlags&=~UCNV_OPTION_VERSION; return; } else if((uint8_t)(c-'0')<10) { *pFlags=(*pFlags&~UCNV_OPTION_VERSION)|(uint32_t)(c-'0'); ++inName; } } else if(uprv_strncmp(inName, "swaplfnl", 8)==0) { inName+=8; *pFlags|=UCNV_OPTION_SWAP_LFNL; /* add processing for new options here with another } else if(uprv_strncmp(inName, "option-name=", XX)==0) { */ } else { /* ignore any other options until we define some */ while(((c = *inName++) != 0) && (c != UCNV_OPTION_SEP_CHAR)) { } if(c==0) { return; } } } }