static uint16_t getTagNumber(const char *tag, uint16_t tagLen) { char *atag; uint16_t t; UBool preferredName = ((tagLen > 0) ? (tag[tagLen - 1] == '*') : (FALSE)); if (tagCount >= MAX_TAG_COUNT) { fprintf(stderr, "%s:%d: too many tags\n", path, lineNum); exit(U_BUFFER_OVERFLOW_ERROR); } if (preferredName) { /* puts(tag);*/ tagLen--; } for (t = 0; t < tagCount; ++t) { const char *currTag = GET_TAG_STR(tags[t].tag); if (uprv_strlen(currTag) == tagLen && !uprv_strnicmp(currTag, tag, tagLen)) { return t; } } /* we need to add this tag */ if (tagCount >= MAX_TAG_COUNT) { fprintf(stderr, "%s:%d: error: too many tags\n", path, lineNum); exit(U_BUFFER_OVERFLOW_ERROR); } /* allocate a new entry in the tag table */ atag = allocString(&tagBlock, tag, tagLen); if (standardTagsUsed) { fprintf(stderr, "%s:%d: error: Tag \"%s\" is not declared at the beginning of the alias table.\n", path, lineNum, atag); exit(1); } else if (tagLen > 0 && strcmp(tag, ALL_TAG_STR) != 0) { fprintf(stderr, "%s:%d: warning: Tag \"%s\" was added to the list of standards because it was not declared at beginning of the alias table.\n", path, lineNum, atag); } /* add the tag to the tag table */ tags[tagCount].tag = GET_TAG_NUM(atag); /* The aliasList should be set to 0's already */ return tagCount++; }
static int32_t _uloc_minimizeSubtags(const char* localeID, char* minimizedLocaleID, int32_t minimizedLocaleIDCapacity, UErrorCode* err) { /** * ULOC_FULLNAME_CAPACITY will provide enough capacity * that we can build a string that contains the language, * script and region code without worrying about overrunning * the user-supplied buffer. **/ char maximizedTagBuffer[ULOC_FULLNAME_CAPACITY]; int32_t maximizedTagBufferLength = sizeof(maximizedTagBuffer); char lang[ULOC_LANG_CAPACITY]; int32_t langLength = sizeof(lang); char script[ULOC_SCRIPT_CAPACITY]; int32_t scriptLength = sizeof(script); char region[ULOC_COUNTRY_CAPACITY]; int32_t regionLength = sizeof(region); const char* trailing = ""; int32_t trailingLength = 0; int32_t trailingIndex = 0; if(U_FAILURE(*err)) { goto error; } else if (localeID == NULL || minimizedLocaleID == NULL || minimizedLocaleIDCapacity <= 0) { goto error; } trailingIndex = parseTagString( localeID, lang, &langLength, script, &scriptLength, region, ®ionLength, err); if(U_FAILURE(*err)) { /* Overflow indicates an illegal argument error */ if (*err == U_BUFFER_OVERFLOW_ERROR) { *err = U_ILLEGAL_ARGUMENT_ERROR; } goto error; } /* Find the spot where the variants or the keywords begin, if any. */ while (_isIDSeparator(localeID[trailingIndex])) { trailingIndex++; } trailing = &localeID[trailingIndex]; trailingLength = (int32_t)uprv_strlen(trailing); CHECK_TRAILING_VARIANT_SIZE(trailing, trailingLength); createTagString( lang, langLength, script, scriptLength, region, regionLength, NULL, 0, maximizedTagBuffer, maximizedTagBufferLength, err); if(U_FAILURE(*err)) { goto error; } /** * First, we need to first get the maximization * from AddLikelySubtags. **/ maximizedTagBufferLength = uloc_addLikelySubtags( maximizedTagBuffer, maximizedTagBuffer, maximizedTagBufferLength, err); if(U_FAILURE(*err)) { goto error; } /** * Start first with just the language. **/ { char tagBuffer[ULOC_FULLNAME_CAPACITY]; const int32_t tagBufferLength = createLikelySubtagsString( lang, langLength, NULL, 0, NULL, 0, NULL, 0, tagBuffer, sizeof(tagBuffer), err); if(U_FAILURE(*err)) { goto error; } else if (uprv_strnicmp( maximizedTagBuffer, tagBuffer, tagBufferLength) == 0) { return createTagString( lang, langLength, NULL, 0, NULL, 0, trailing, trailingLength, minimizedLocaleID, minimizedLocaleIDCapacity, err); } } /** * Next, try the language and region. **/ if (regionLength > 0) { char tagBuffer[ULOC_FULLNAME_CAPACITY]; const int32_t tagBufferLength = createLikelySubtagsString( lang, langLength, NULL, 0, region, regionLength, NULL, 0, tagBuffer, sizeof(tagBuffer), err); if(U_FAILURE(*err)) { goto error; } else if (uprv_strnicmp( maximizedTagBuffer, tagBuffer, tagBufferLength) == 0) { return createTagString( lang, langLength, NULL, 0, region, regionLength, trailing, trailingLength, minimizedLocaleID, minimizedLocaleIDCapacity, err); } } /** * Finally, try the language and script. This is our last chance, * since trying with all three subtags would only yield the * maximal version that we already have. **/ if (scriptLength > 0 && regionLength > 0) { char tagBuffer[ULOC_FULLNAME_CAPACITY]; const int32_t tagBufferLength = createLikelySubtagsString( lang, langLength, script, scriptLength, NULL, 0, NULL, 0, tagBuffer, sizeof(tagBuffer), err); if(U_FAILURE(*err)) { goto error; } else if (uprv_strnicmp( maximizedTagBuffer, tagBuffer, tagBufferLength) == 0) { return createTagString( lang, langLength, script, scriptLength, NULL, 0, trailing, trailingLength, minimizedLocaleID, minimizedLocaleIDCapacity, err); } } { /** * If we got here, return the locale ID parameter. **/ const int32_t localeIDLength = (int32_t)uprv_strlen(localeID); uprv_memcpy( minimizedLocaleID, localeID, localeIDLength <= minimizedLocaleIDCapacity ? localeIDLength : minimizedLocaleIDCapacity); return u_terminateChars( minimizedLocaleID, minimizedLocaleIDCapacity, localeIDLength, err); } error: if (!U_FAILURE(*err)) { *err = U_ILLEGAL_ARGUMENT_ERROR; } return -1; }
/** * Parse the language, script, and region subtags from a tag string, and copy the * results into the corresponding output parameters. The buffers are null-terminated, * unless overflow occurs. * * The langLength, scriptLength, and regionLength parameters are input/output * parameters, and must contain the capacity of their corresponding buffers on * input. On output, they will contain the actual length of the buffers, not * including the null terminator. * * If the length of any of the output subtags exceeds the capacity of the corresponding * buffer, the function copies as many bytes to the output buffer as it can, and returns * the error U_BUFFER_OVERFLOW_ERROR. It will not parse any more subtags once overflow * occurs. * * If an illegal argument is provided, the function returns the error * U_ILLEGAL_ARGUMENT_ERROR. * * @param localeID The locale ID to parse. * @param lang The language tag buffer. * @param langLength The length of the language tag. * @param script The script tag buffer. * @param scriptLength The length of the script tag. * @param region The region tag buffer. * @param regionLength The length of the region tag. * @param err A pointer to a UErrorCode for error reporting. * @return The number of chars of the localeID parameter consumed. **/ static int32_t U_CALLCONV parseTagString( const char* localeID, char* lang, int32_t* langLength, char* script, int32_t* scriptLength, char* region, int32_t* regionLength, UErrorCode* err) { const char* position = localeID; int32_t subtagLength = 0; if(U_FAILURE(*err) || localeID == NULL || lang == NULL || langLength == NULL || script == NULL || scriptLength == NULL || region == NULL || regionLength == NULL) { goto error; } subtagLength = ulocimp_getLanguage(position, lang, *langLength, &position); u_terminateChars(lang, *langLength, subtagLength, err); /* * Note that we explicit consider U_STRING_NOT_TERMINATED_WARNING * to be an error, because it indicates the user-supplied tag is * not well-formed. */ if(U_FAILURE(*err)) { goto error; } *langLength = subtagLength; /* * If no language was present, use the value of unknownLanguage * instead. Otherwise, move past any separator. */ if (*langLength == 0) { uprv_strcpy( lang, unknownLanguage); *langLength = (int32_t)uprv_strlen(lang); } else if (_isIDSeparator(*position)) { ++position; } subtagLength = ulocimp_getScript(position, script, *scriptLength, &position); u_terminateChars(script, *scriptLength, subtagLength, err); if(U_FAILURE(*err)) { goto error; } *scriptLength = subtagLength; if (*scriptLength > 0) { if (uprv_strnicmp(script, unknownScript, *scriptLength) == 0) { /** * If the script part is the "unknown" script, then don't return it. **/ *scriptLength = 0; } /* * Move past any separator. */ if (_isIDSeparator(*position)) { ++position; } } subtagLength = ulocimp_getCountry(position, region, *regionLength, &position); u_terminateChars(region, *regionLength, subtagLength, err); if(U_FAILURE(*err)) { goto error; } *regionLength = subtagLength; if (*regionLength > 0) { if (uprv_strnicmp(region, unknownRegion, *regionLength) == 0) { /** * If the region part is the "unknown" region, then don't return it. **/ *regionLength = 0; } } else if (*position != 0 && *position != '@') { /* back up over consumed trailing separator */ --position; } exit: return (int32_t)(position - localeID); error: /** * If we get here, we have no explicit error, it's the result of an * illegal argument. **/ if (!U_FAILURE(*err)) { *err = U_ILLEGAL_ARGUMENT_ERROR; } goto exit; }
static void TestAPI(void) { int32_t intValue=0; char src[30]="HELLO THERE", dest[30]; static const char *const abc="abcdefghijklmnopqrstuvwxyz", *const ABC="ABCDEFGHIJKLMNOPQRSTUVWXYZ"; const char *temp; int32_t i; log_verbose("Testing uprv_tolower() and uprv_toupper()\n"); for(i=0; i<=26; ++i) { dest[i]=uprv_tolower(abc[i]); } if(0!=strcmp(abc, dest)) { log_err("uprv_tolower(abc) failed\n"); } for(i=0; i<=26; ++i) { dest[i]=uprv_tolower(ABC[i]); } if(0!=strcmp(abc, dest)) { log_err("uprv_tolower(ABC) failed\n"); } for(i=0; i<=26; ++i) { dest[i]=uprv_toupper(abc[i]); } if(0!=strcmp(ABC, dest)) { log_err("uprv_toupper(abc) failed\n"); } for(i=0; i<=26; ++i) { dest[i]=uprv_toupper(ABC[i]); } if(0!=strcmp(ABC, dest)) { log_err("uprv_toupper(ABC) failed\n"); } log_verbose("Testing the API in cstring\n"); T_CString_toLowerCase(src); if(uprv_strcmp(src, "hello there") != 0){ log_err("FAIL: *** T_CString_toLowerCase() failed. Expected: \"hello there\", Got: \"%s\"\n", src); } T_CString_toUpperCase(src); if(uprv_strcmp(src, "HELLO THERE") != 0){ log_err("FAIL: *** T_CString_toUpperCase() failed. Expected: \"HELLO THERE\", Got: \"%s\"\n", src); } intValue=T_CString_stringToInteger("34556", 10); if(intValue != 34556){ log_err("FAIL: ****T_CString_stringToInteger(\"34556\", 10) failed. Expected: 34556, Got: %d\n", intValue); } intValue=T_CString_stringToInteger("100", 16); if(intValue != 256){ log_err("FAIL: ****T_CString_stringToInteger(\"100\", 16) failed. Expected: 256, Got: %d\n", intValue); } i = T_CString_integerToString(src, 34556, 10); if(uprv_strcmp(src, "34556") != 0 || i != 5){ log_err("FAIL: ****integerToString(src, 34566, 10); failed. Expected: \"34556\", Got: %s\n", src); } i = T_CString_integerToString(src, 431, 16); if(uprv_stricmp(src, "1AF") != 0 || i != 3){ log_err("FAIL: ****integerToString(src, 431, 16); failed. Expected: \"1AF\", Got: %s\n", src); } i = T_CString_int64ToString(src, U_INT64_MAX, 10); if(uprv_strcmp(src, "9223372036854775807") != 0 || i != 19){ log_err("FAIL: ****integerToString(src, 9223372036854775807, 10); failed. Got: %s\n", src); } i = T_CString_int64ToString(src, U_INT64_MAX, 16); if(uprv_stricmp(src, "7FFFFFFFFFFFFFFF") != 0 || i != 16){ log_err("FAIL: ****integerToString(src, 7FFFFFFFFFFFFFFF, 16); failed. Got: %s\n", src); } uprv_strcpy(src, "this is lower case"); if(uprv_stricmp(src, "THIS is lower CASE") != 0){ log_err("FAIL: *****uprv_stricmp() failed."); } if((intValue=uprv_stricmp(NULL, "first string is null") )!= -1){ log_err("FAIL: uprv_stricmp() where the first string is null failed. Expected: -1, returned %d\n", intValue); } if((intValue=uprv_stricmp("second string is null", NULL)) != 1){ log_err("FAIL: uprv_stricmp() where the second string is null failed. Expected: 1, returned %d\n", intValue); } if((intValue=uprv_stricmp(NULL, NULL)) != 0){ log_err("FAIL: uprv_stricmp(NULL, NULL) failed. Expected: 0, returned %d\n", intValue);; } if((intValue=uprv_stricmp("", "")) != 0){ log_err("FAIL: uprv_stricmp(\"\", \"\") failed. Expected: 0, returned %d\n", intValue);; } if((intValue=uprv_stricmp("", "abc")) != -1){ log_err("FAIL: uprv_stricmp(\"\", \"abc\") failed. Expected: -1, returned %d\n", intValue); } if((intValue=uprv_stricmp("abc", "")) != 1){ log_err("FAIL: uprv_stricmp(\"abc\", \"\") failed. Expected: 1, returned %d\n", intValue); } temp=uprv_strdup("strdup"); if(uprv_strcmp(temp, "strdup") !=0 ){ log_err("FAIL: uprv_strdup() failed. Expected: \"strdup\", Got: %s\n", temp); } uprv_free((char *)temp); uprv_strcpy(src, "this is lower case"); if(uprv_strnicmp(src, "THIS", 4 ) != 0){ log_err("FAIL: *****uprv_strnicmp() failed."); } if((intValue=uprv_strnicmp(NULL, "first string is null", 10) )!= -1){ log_err("FAIL: uprv_strnicmp() where the first string is null failed. Expected: -1, returned %d\n", intValue); } if((intValue=uprv_strnicmp("second string is null", NULL, 10)) != 1){ log_err("FAIL: uprv_strnicmp() where the second string is null failed. Expected: 1, returned %d\n", intValue); } if((intValue=uprv_strnicmp(NULL, NULL, 10)) != 0){ log_err("FAIL: uprv_strnicmp(NULL, NULL, 10) failed. Expected: 0, returned %d\n", intValue);; } if((intValue=uprv_strnicmp("", "", 10)) != 0){ log_err("FAIL: uprv_strnicmp(\"\", \"\") failed. Expected: 0, returned %d\n", intValue);; } if((intValue=uprv_strnicmp("", "abc", 10)) != -1){ log_err("FAIL: uprv_stricmp(\"\", \"abc\", 10) failed. Expected: -1, returned %d\n", intValue); } if((intValue=uprv_strnicmp("abc", "", 10)) != 1){ log_err("FAIL: uprv_strnicmp(\"abc\", \"\", 10) failed. Expected: 1, returned %d\n", intValue); } }