150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/*
250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*******************************************************************************
350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*
4103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius*   Copyright (C) 1997-2012, International Business Machines
550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*   Corporation and others.  All Rights Reserved.
650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*
750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*******************************************************************************
850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*   file name:  loclikely.cpp
950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*   encoding:   US-ASCII
1050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*   tab size:   8 (not used)
1150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*   indentation:4
1250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*
1350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*   created on: 2010feb25
1450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*   created by: Markus W. Scherer
1550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*
1650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*   Code for likely and minimized locale subtags, separated out from other .cpp files
1750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*   that then do not depend on resource bundle code and likely-subtags data.
1850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*/
1950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
2050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/utypes.h"
2150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/putil.h"
2250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/uloc.h"
2350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/ures.h"
2450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "cmemory.h"
2550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "cstring.h"
2650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "ulocimp.h"
2750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "ustr_imp.h"
2850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
2950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/**
3050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * This function looks for the localeID in the likelySubtags resource.
3150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *
3250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param localeID The tag to find.
3350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param buffer A buffer to hold the matching entry
3450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param bufferLength The length of the output buffer
3550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @return A pointer to "buffer" if found, or a null pointer if not.
3650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */
3750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic const char*  U_CALLCONV
3850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehofindLikelySubtags(const char* localeID,
3950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                  char* buffer,
4050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                  int32_t bufferLength,
4150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                  UErrorCode* err) {
4250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    const char* result = NULL;
4350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
4450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (!U_FAILURE(*err)) {
4550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        int32_t resLen = 0;
4650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        const UChar* s = NULL;
4750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        UErrorCode tmpErr = U_ZERO_ERROR;
4850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        UResourceBundle* subtags = ures_openDirect(NULL, "likelySubtags", &tmpErr);
4950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (U_SUCCESS(tmpErr)) {
5050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            s = ures_getStringByKey(subtags, localeID, &resLen, &tmpErr);
5150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
5250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            if (U_FAILURE(tmpErr)) {
5350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                /*
5450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                 * If a resource is missing, it's not really an error, it's
5550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                 * just that we don't have any data for that particular locale ID.
5650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                 */
5750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                if (tmpErr != U_MISSING_RESOURCE_ERROR) {
5850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    *err = tmpErr;
5950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                }
6050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            }
6150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            else if (resLen >= bufferLength) {
6250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                /* The buffer should never overflow. */
6350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                *err = U_INTERNAL_PROGRAM_ERROR;
6450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            }
6550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            else {
6650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                u_UCharsToChars(s, buffer, resLen + 1);
6750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                result = buffer;
6850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            }
6950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
7050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            ures_close(subtags);
7150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        } else {
7250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            *err = tmpErr;
7350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
7450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
7550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
7650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return result;
7750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
7850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
7950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/**
8050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Append a tag to a buffer, adding the separator if necessary.  The buffer
8150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * must be large enough to contain the resulting tag plus any separator
8250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * necessary. The tag must not be a zero-length string.
8350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *
8450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param tag The tag to add.
8550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param tagLength The length of the tag.
8650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param buffer The output buffer.
8750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param bufferLength The length of the output buffer.  This is an input/ouput parameter.
8850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho **/
8950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic void U_CALLCONV
9050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoappendTag(
9150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    const char* tag,
9250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t tagLength,
9350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    char* buffer,
9450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t* bufferLength) {
9550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
9650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (*bufferLength > 0) {
9750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        buffer[*bufferLength] = '_';
9850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        ++(*bufferLength);
9950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
10050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
10150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    uprv_memmove(
10250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        &buffer[*bufferLength],
10350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        tag,
10450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        tagLength);
10550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
10650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    *bufferLength += tagLength;
10750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
10850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
10950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/**
11050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * These are the canonical strings for unknown languages, scripts and regions.
11150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho **/
11250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic const char* const unknownLanguage = "und";
11350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic const char* const unknownScript = "Zzzz";
11450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic const char* const unknownRegion = "ZZ";
11550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
11650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/**
11750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Create a tag string from the supplied parameters.  The lang, script and region
11850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * parameters may be NULL pointers. If they are, their corresponding length parameters
11950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * must be less than or equal to 0.
12050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *
12150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * If any of the language, script or region parameters are empty, and the alternateTags
12250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * parameter is not NULL, it will be parsed for potential language, script and region tags
12350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * to be used when constructing the new tag.  If the alternateTags parameter is NULL, or
12450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * it contains no language tag, the default tag for the unknown language is used.
12550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *
12650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * If the length of the new string exceeds the capacity of the output buffer,
12750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * the function copies as many bytes to the output buffer as it can, and returns
12850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * the error U_BUFFER_OVERFLOW_ERROR.
12950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *
13050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * If an illegal argument is provided, the function returns the error
13150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * U_ILLEGAL_ARGUMENT_ERROR.
13250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *
13350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Note that this function can return the warning U_STRING_NOT_TERMINATED_WARNING if
13450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * the tag string fits in the output buffer, but the null terminator doesn't.
13550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *
13650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param lang The language tag to use.
13750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param langLength The length of the language tag.
13850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param script The script tag to use.
13950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param scriptLength The length of the script tag.
14050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param region The region tag to use.
14150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param regionLength The length of the region tag.
14250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param trailing Any trailing data to append to the new tag.
14350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param trailingLength The length of the trailing data.
14450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param alternateTags A string containing any alternate tags.
14550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param tag The output buffer.
14650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param tagCapacity The capacity of the output buffer.
14750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param err A pointer to a UErrorCode for error reporting.
14850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @return The length of the tag string, which may be greater than tagCapacity, or -1 on error.
14950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho **/
15050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic int32_t U_CALLCONV
15150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehocreateTagStringWithAlternates(
15250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    const char* lang,
15350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t langLength,
15450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    const char* script,
15550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t scriptLength,
15650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    const char* region,
15750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t regionLength,
15850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    const char* trailing,
15950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t trailingLength,
16050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    const char* alternateTags,
16150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    char* tag,
16250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t tagCapacity,
16350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UErrorCode* err) {
16450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
16550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (U_FAILURE(*err)) {
16650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        goto error;
16750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
16850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    else if (tag == NULL ||
16950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho             tagCapacity <= 0 ||
17050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho             langLength >= ULOC_LANG_CAPACITY ||
17150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho             scriptLength >= ULOC_SCRIPT_CAPACITY ||
17250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho             regionLength >= ULOC_COUNTRY_CAPACITY) {
17350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        goto error;
17450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
17550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    else {
17650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        /**
17750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho         * ULOC_FULLNAME_CAPACITY will provide enough capacity
17850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho         * that we can build a string that contains the language,
17950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho         * script and region code without worrying about overrunning
18050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho         * the user-supplied buffer.
18150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho         **/
18250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        char tagBuffer[ULOC_FULLNAME_CAPACITY];
18350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        int32_t tagLength = 0;
18450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        int32_t capacityRemaining = tagCapacity;
18550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        UBool regionAppended = FALSE;
18650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
18750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (langLength > 0) {
18850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            appendTag(
18950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                lang,
19050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                langLength,
19150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                tagBuffer,
19250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                &tagLength);
19350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
19450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        else if (alternateTags == NULL) {
19550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            /*
19650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho             * Append the value for an unknown language, if
19750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho             * we found no language.
19850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho             */
19950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            appendTag(
20050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                unknownLanguage,
20150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                (int32_t)uprv_strlen(unknownLanguage),
20250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                tagBuffer,
20350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                &tagLength);
20450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
20550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        else {
20650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            /*
20750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho             * Parse the alternateTags string for the language.
20850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho             */
20950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            char alternateLang[ULOC_LANG_CAPACITY];
21050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            int32_t alternateLangLength = sizeof(alternateLang);
21150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
21250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            alternateLangLength =
21350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                uloc_getLanguage(
21450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    alternateTags,
21550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    alternateLang,
21650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    alternateLangLength,
21750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    err);
21850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            if(U_FAILURE(*err) ||
21950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                alternateLangLength >= ULOC_LANG_CAPACITY) {
22050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                goto error;
22150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            }
22250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            else if (alternateLangLength == 0) {
22350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                /*
22450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                 * Append the value for an unknown language, if
22550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                 * we found no language.
22650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                 */
22750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                appendTag(
22850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    unknownLanguage,
22950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    (int32_t)uprv_strlen(unknownLanguage),
23050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    tagBuffer,
23150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    &tagLength);
23250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            }
23350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            else {
23450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                appendTag(
23550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    alternateLang,
23650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    alternateLangLength,
23750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    tagBuffer,
23850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    &tagLength);
23950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            }
24050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
24150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
24250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (scriptLength > 0) {
24350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            appendTag(
24450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                script,
24550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                scriptLength,
24650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                tagBuffer,
24750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                &tagLength);
24850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
24950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        else if (alternateTags != NULL) {
25050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            /*
25150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho             * Parse the alternateTags string for the script.
25250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho             */
25350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            char alternateScript[ULOC_SCRIPT_CAPACITY];
25450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
25550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            const int32_t alternateScriptLength =
25650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                uloc_getScript(
25750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    alternateTags,
25850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    alternateScript,
25950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    sizeof(alternateScript),
26050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    err);
26150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
26250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            if (U_FAILURE(*err) ||
26350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                alternateScriptLength >= ULOC_SCRIPT_CAPACITY) {
26450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                goto error;
26550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            }
26650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            else if (alternateScriptLength > 0) {
26750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                appendTag(
26850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    alternateScript,
26950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    alternateScriptLength,
27050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    tagBuffer,
27150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    &tagLength);
27250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            }
27350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
27450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
27550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (regionLength > 0) {
27650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            appendTag(
27750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                region,
27850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                regionLength,
27950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                tagBuffer,
28050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                &tagLength);
28150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
28250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            regionAppended = TRUE;
28350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
28450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        else if (alternateTags != NULL) {
28550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            /*
28650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho             * Parse the alternateTags string for the region.
28750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho             */
28850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            char alternateRegion[ULOC_COUNTRY_CAPACITY];
28950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
29050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            const int32_t alternateRegionLength =
29150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                uloc_getCountry(
29250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    alternateTags,
29350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    alternateRegion,
29450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    sizeof(alternateRegion),
29550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    err);
29650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            if (U_FAILURE(*err) ||
29750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                alternateRegionLength >= ULOC_COUNTRY_CAPACITY) {
29850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                goto error;
29950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            }
30050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            else if (alternateRegionLength > 0) {
30150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                appendTag(
30250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    alternateRegion,
30350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    alternateRegionLength,
30450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    tagBuffer,
30550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    &tagLength);
30650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
30750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                regionAppended = TRUE;
30850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            }
30950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
31050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
31150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        {
31250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            const int32_t toCopy =
31350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                tagLength >= tagCapacity ? tagCapacity : tagLength;
31450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
31550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            /**
31650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho             * Copy the partial tag from our internal buffer to the supplied
31750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho             * target.
31850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho             **/
31950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            uprv_memcpy(
32050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                tag,
32150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                tagBuffer,
32250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                toCopy);
32350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
32450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            capacityRemaining -= toCopy;
32550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
32650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
32750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (trailingLength > 0) {
328b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            if (*trailing != '@' && capacityRemaining > 0) {
32950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                tag[tagLength++] = '_';
33050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                --capacityRemaining;
331b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                if (capacityRemaining > 0 && !regionAppended) {
332b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    /* extra separator is required */
333b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    tag[tagLength++] = '_';
334b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    --capacityRemaining;
335b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                }
33650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            }
33750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
33850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            if (capacityRemaining > 0) {
33950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                /*
34050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                 * Copy the trailing data into the supplied buffer.  Use uprv_memmove, since we
34150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                 * don't know if the user-supplied buffers overlap.
34250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                 */
34350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                const int32_t toCopy =
34450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    trailingLength >= capacityRemaining ? capacityRemaining : trailingLength;
34550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
34650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                uprv_memmove(
34750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    &tag[tagLength],
34850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    trailing,
34950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    toCopy);
35050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            }
35150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
35250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
35350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        tagLength += trailingLength;
35450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
35550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return u_terminateChars(
35650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    tag,
35750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    tagCapacity,
35850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    tagLength,
35950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    err);
36050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
36150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
36250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoerror:
36350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
36450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /**
36550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * An overflow indicates the locale ID passed in
36650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * is ill-formed.  If we got here, and there was
36750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * no previous error, it's an implicit overflow.
36850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     **/
36950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (*err ==  U_BUFFER_OVERFLOW_ERROR ||
37050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        U_SUCCESS(*err)) {
37150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        *err = U_ILLEGAL_ARGUMENT_ERROR;
37250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
37350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
37450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return -1;
37550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
37650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
37750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/**
37850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Create a tag string from the supplied parameters.  The lang, script and region
37950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * parameters may be NULL pointers. If they are, their corresponding length parameters
38050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * must be less than or equal to 0.  If the lang parameter is an empty string, the
38150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * default value for an unknown language is written to the output buffer.
38250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *
38350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * If the length of the new string exceeds the capacity of the output buffer,
38450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * the function copies as many bytes to the output buffer as it can, and returns
38550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * the error U_BUFFER_OVERFLOW_ERROR.
38650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *
38750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * If an illegal argument is provided, the function returns the error
38850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * U_ILLEGAL_ARGUMENT_ERROR.
38950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *
39050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param lang The language tag to use.
39150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param langLength The length of the language tag.
39250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param script The script tag to use.
39350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param scriptLength The length of the script tag.
39450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param region The region tag to use.
39550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param regionLength The length of the region tag.
39650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param trailing Any trailing data to append to the new tag.
39750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param trailingLength The length of the trailing data.
39850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param tag The output buffer.
39950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param tagCapacity The capacity of the output buffer.
40050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param err A pointer to a UErrorCode for error reporting.
40150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @return The length of the tag string, which may be greater than tagCapacity.
40250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho **/
40350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic int32_t U_CALLCONV
40450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehocreateTagString(
40550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    const char* lang,
40650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t langLength,
40750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    const char* script,
40850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t scriptLength,
40950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    const char* region,
41050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t regionLength,
41150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    const char* trailing,
41250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t trailingLength,
41350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    char* tag,
41450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t tagCapacity,
41550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UErrorCode* err)
41650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
41750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return createTagStringWithAlternates(
41850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                lang,
41950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                langLength,
42050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                script,
42150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                scriptLength,
42250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                region,
42350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                regionLength,
42450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                trailing,
42550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                trailingLength,
42650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                NULL,
42750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                tag,
42850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                tagCapacity,
42950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                err);
43050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
43150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
43250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/**
43350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Parse the language, script, and region subtags from a tag string, and copy the
43450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * results into the corresponding output parameters. The buffers are null-terminated,
43550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * unless overflow occurs.
43650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *
43750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * The langLength, scriptLength, and regionLength parameters are input/output
43850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * parameters, and must contain the capacity of their corresponding buffers on
43950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * input.  On output, they will contain the actual length of the buffers, not
44050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * including the null terminator.
44150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *
44250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * If the length of any of the output subtags exceeds the capacity of the corresponding
44350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * buffer, the function copies as many bytes to the output buffer as it can, and returns
44450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * the error U_BUFFER_OVERFLOW_ERROR.  It will not parse any more subtags once overflow
44550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * occurs.
44650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *
44750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * If an illegal argument is provided, the function returns the error
44850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * U_ILLEGAL_ARGUMENT_ERROR.
44950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *
45050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param localeID The locale ID to parse.
45150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param lang The language tag buffer.
45250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param langLength The length of the language tag.
45350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param script The script tag buffer.
45450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param scriptLength The length of the script tag.
45550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param region The region tag buffer.
45650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param regionLength The length of the region tag.
45750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param err A pointer to a UErrorCode for error reporting.
45850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @return The number of chars of the localeID parameter consumed.
45950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho **/
46050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic int32_t U_CALLCONV
46150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoparseTagString(
46250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    const char* localeID,
46350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    char* lang,
46450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t* langLength,
46550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    char* script,
46650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t* scriptLength,
46750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    char* region,
46850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t* regionLength,
46950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UErrorCode* err)
47050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
47150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    const char* position = localeID;
47250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t subtagLength = 0;
47350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
47450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(U_FAILURE(*err) ||
47550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho       localeID == NULL ||
47650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho       lang == NULL ||
47750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho       langLength == NULL ||
47850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho       script == NULL ||
47950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho       scriptLength == NULL ||
48050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho       region == NULL ||
48150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho       regionLength == NULL) {
48250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        goto error;
48350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
48450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
48550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    subtagLength = ulocimp_getLanguage(position, lang, *langLength, &position);
48650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    u_terminateChars(lang, *langLength, subtagLength, err);
48750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
48850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /*
48950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * Note that we explicit consider U_STRING_NOT_TERMINATED_WARNING
49050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * to be an error, because it indicates the user-supplied tag is
49150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * not well-formed.
49250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     */
49350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(U_FAILURE(*err)) {
49450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        goto error;
49550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
49650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
49750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    *langLength = subtagLength;
49850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
49950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /*
50050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * If no language was present, use the value of unknownLanguage
50150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * instead.  Otherwise, move past any separator.
50250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     */
50350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (*langLength == 0) {
50450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        uprv_strcpy(
50550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            lang,
50650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            unknownLanguage);
50750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        *langLength = (int32_t)uprv_strlen(lang);
50850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
50950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    else if (_isIDSeparator(*position)) {
51050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        ++position;
51150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
51250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
51350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    subtagLength = ulocimp_getScript(position, script, *scriptLength, &position);
51450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    u_terminateChars(script, *scriptLength, subtagLength, err);
51550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
51650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(U_FAILURE(*err)) {
51750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        goto error;
51850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
51950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
52050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    *scriptLength = subtagLength;
52150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
52250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (*scriptLength > 0) {
52350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (uprv_strnicmp(script, unknownScript, *scriptLength) == 0) {
52450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            /**
52550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho             * If the script part is the "unknown" script, then don't return it.
52650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho             **/
52750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            *scriptLength = 0;
52850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
52950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
53050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        /*
53150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho         * Move past any separator.
53250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho         */
53350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (_isIDSeparator(*position)) {
53450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            ++position;
53550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
53650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
53750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
53850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    subtagLength = ulocimp_getCountry(position, region, *regionLength, &position);
53950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    u_terminateChars(region, *regionLength, subtagLength, err);
54050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
54150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(U_FAILURE(*err)) {
54250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        goto error;
54350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
54450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
54550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    *regionLength = subtagLength;
54650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
54750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (*regionLength > 0) {
54850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (uprv_strnicmp(region, unknownRegion, *regionLength) == 0) {
54950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            /**
55050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho             * If the region part is the "unknown" region, then don't return it.
55150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho             **/
55250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            *regionLength = 0;
55350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
554b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    } else if (*position != 0 && *position != '@') {
555b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        /* back up over consumed trailing separator */
556b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        --position;
55750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
55850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
55950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoexit:
56050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
56150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return (int32_t)(position - localeID);
56250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
56350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoerror:
56450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
56550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /**
56650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * If we get here, we have no explicit error, it's the result of an
56750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * illegal argument.
56850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     **/
56950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (!U_FAILURE(*err)) {
57050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        *err = U_ILLEGAL_ARGUMENT_ERROR;
57150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
57250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
57350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    goto exit;
57450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
57550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
57650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic int32_t U_CALLCONV
57750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehocreateLikelySubtagsString(
57850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    const char* lang,
57950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t langLength,
58050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    const char* script,
58150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t scriptLength,
58250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    const char* region,
58350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t regionLength,
58450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    const char* variants,
58550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t variantsLength,
58650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    char* tag,
58750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t tagCapacity,
58850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UErrorCode* err)
58950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
59050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /**
59150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * ULOC_FULLNAME_CAPACITY will provide enough capacity
59250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * that we can build a string that contains the language,
59350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * script and region code without worrying about overrunning
59450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * the user-supplied buffer.
59550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     **/
59650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    char tagBuffer[ULOC_FULLNAME_CAPACITY];
59750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    char likelySubtagsBuffer[ULOC_FULLNAME_CAPACITY];
59850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
59950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(U_FAILURE(*err)) {
60050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        goto error;
60150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
60250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
60350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /**
60450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * Try the language with the script and region first.
60550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     **/
60650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (scriptLength > 0 && regionLength > 0) {
60750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
60850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        const char* likelySubtags = NULL;
60950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
610103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        createTagString(
61150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            lang,
61250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            langLength,
61350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            script,
61450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            scriptLength,
61550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            region,
61650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            regionLength,
61750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            NULL,
61850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            0,
61950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            tagBuffer,
62050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            sizeof(tagBuffer),
62150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            err);
62250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if(U_FAILURE(*err)) {
62350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            goto error;
62450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
62550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
62650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        likelySubtags =
62750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            findLikelySubtags(
62850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                tagBuffer,
62950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                likelySubtagsBuffer,
63050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                sizeof(likelySubtagsBuffer),
63150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                err);
63250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if(U_FAILURE(*err)) {
63350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            goto error;
63450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
63550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
63650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (likelySubtags != NULL) {
63750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            /* Always use the language tag from the
63850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho               maximal string, since it may be more
63950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho               specific than the one provided. */
64050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            return createTagStringWithAlternates(
64150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        NULL,
64250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        0,
64350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        NULL,
64450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        0,
64550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        NULL,
64650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        0,
64750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        variants,
64850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        variantsLength,
64950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        likelySubtags,
65050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        tag,
65150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        tagCapacity,
65250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        err);
65350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
65450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
65550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
65650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /**
65750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * Try the language with just the script.
65850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     **/
65950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (scriptLength > 0) {
66050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
66150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        const char* likelySubtags = NULL;
66250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
663103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        createTagString(
66450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            lang,
66550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            langLength,
66650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            script,
66750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            scriptLength,
66850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            NULL,
66950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            0,
67050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            NULL,
67150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            0,
67250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            tagBuffer,
67350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            sizeof(tagBuffer),
67450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            err);
67550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if(U_FAILURE(*err)) {
67650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            goto error;
67750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
67850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
67950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        likelySubtags =
68050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            findLikelySubtags(
68150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                tagBuffer,
68250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                likelySubtagsBuffer,
68350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                sizeof(likelySubtagsBuffer),
68450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                err);
68550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if(U_FAILURE(*err)) {
68650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            goto error;
68750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
68850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
68950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (likelySubtags != NULL) {
69050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            /* Always use the language tag from the
69150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho               maximal string, since it may be more
69250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho               specific than the one provided. */
69350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            return createTagStringWithAlternates(
69450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        NULL,
69550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        0,
69650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        NULL,
69750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        0,
69850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        region,
69950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        regionLength,
70050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        variants,
70150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        variantsLength,
70250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        likelySubtags,
70350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        tag,
70450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        tagCapacity,
70550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        err);
70650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
70750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
70850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
70950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /**
71050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * Try the language with just the region.
71150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     **/
71250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (regionLength > 0) {
71350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
71450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        const char* likelySubtags = NULL;
71550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
71650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        createTagString(
71750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            lang,
71850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            langLength,
71950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            NULL,
72050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            0,
72150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            region,
72250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            regionLength,
72350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            NULL,
72450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            0,
72550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            tagBuffer,
72650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            sizeof(tagBuffer),
72750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            err);
72850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if(U_FAILURE(*err)) {
72950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            goto error;
73050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
73150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
73250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        likelySubtags =
73350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            findLikelySubtags(
73450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                tagBuffer,
73550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                likelySubtagsBuffer,
73650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                sizeof(likelySubtagsBuffer),
73750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                err);
73850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if(U_FAILURE(*err)) {
73950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            goto error;
74050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
74150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
74250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (likelySubtags != NULL) {
74350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            /* Always use the language tag from the
74450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho               maximal string, since it may be more
74550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho               specific than the one provided. */
74650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            return createTagStringWithAlternates(
74750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        NULL,
74850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        0,
74950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        script,
75050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        scriptLength,
75150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        NULL,
75250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        0,
75350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        variants,
75450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        variantsLength,
75550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        likelySubtags,
75650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        tag,
75750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        tagCapacity,
75850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        err);
75950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
76050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
76150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
76250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /**
76350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * Finally, try just the language.
76450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     **/
76550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    {
76650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        const char* likelySubtags = NULL;
76750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
76850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        createTagString(
76950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            lang,
77050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            langLength,
77150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            NULL,
77250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            0,
77350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            NULL,
77450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            0,
77550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            NULL,
77650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            0,
77750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            tagBuffer,
77850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            sizeof(tagBuffer),
77950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            err);
78050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if(U_FAILURE(*err)) {
78150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            goto error;
78250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
78350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
78450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        likelySubtags =
78550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            findLikelySubtags(
78650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                tagBuffer,
78750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                likelySubtagsBuffer,
78850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                sizeof(likelySubtagsBuffer),
78950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                err);
79050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if(U_FAILURE(*err)) {
79150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            goto error;
79250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
79350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
79450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (likelySubtags != NULL) {
79550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            /* Always use the language tag from the
79650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho               maximal string, since it may be more
79750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho               specific than the one provided. */
79850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            return createTagStringWithAlternates(
79950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        NULL,
80050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        0,
80150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        script,
80250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        scriptLength,
80350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        region,
80450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        regionLength,
80550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        variants,
80650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        variantsLength,
80750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        likelySubtags,
80850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        tag,
80950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        tagCapacity,
81050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        err);
81150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
81250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
81350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
81450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return u_terminateChars(
81550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                tag,
81650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                tagCapacity,
81750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                0,
81850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                err);
81950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
82050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoerror:
82150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
82250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (!U_FAILURE(*err)) {
82350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        *err = U_ILLEGAL_ARGUMENT_ERROR;
82450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
82550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
82650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return -1;
82750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
82850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
82950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define CHECK_TRAILING_VARIANT_SIZE(trailing, trailingLength) \
83050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    {   int32_t count = 0; \
83150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        int32_t i; \
83250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        for (i = 0; i < trailingLength; i++) { \
83350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            if (trailing[i] == '-' || trailing[i] == '_') { \
83450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                count = 0; \
83550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                if (count > 8) { \
83650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    goto error; \
83750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                } \
83850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            } else if (trailing[i] == '@') { \
83950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                break; \
84050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            } else if (count > 8) { \
84150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                goto error; \
84250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            } else { \
84350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                count++; \
84450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            } \
84550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        } \
84650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
84750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
84850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic int32_t
84950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho_uloc_addLikelySubtags(const char*    localeID,
85050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho         char* maximizedLocaleID,
85150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho         int32_t maximizedLocaleIDCapacity,
85250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho         UErrorCode* err)
85350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
85450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    char lang[ULOC_LANG_CAPACITY];
85550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t langLength = sizeof(lang);
85650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    char script[ULOC_SCRIPT_CAPACITY];
85750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t scriptLength = sizeof(script);
85850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    char region[ULOC_COUNTRY_CAPACITY];
85950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t regionLength = sizeof(region);
86050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    const char* trailing = "";
86150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t trailingLength = 0;
86250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t trailingIndex = 0;
86350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t resultLength = 0;
86450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
86550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(U_FAILURE(*err)) {
86650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        goto error;
86750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
86850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    else if (localeID == NULL ||
86950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho             maximizedLocaleID == NULL ||
87050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho             maximizedLocaleIDCapacity <= 0) {
87150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        goto error;
87250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
87350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
87450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    trailingIndex = parseTagString(
87550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        localeID,
87650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        lang,
87750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        &langLength,
87850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        script,
87950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        &scriptLength,
88050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        region,
88150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        &regionLength,
88250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        err);
88350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(U_FAILURE(*err)) {
88450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        /* Overflow indicates an illegal argument error */
88550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (*err == U_BUFFER_OVERFLOW_ERROR) {
88650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            *err = U_ILLEGAL_ARGUMENT_ERROR;
88750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
88850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
88950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        goto error;
89050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
89150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
89250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /* Find the length of the trailing portion. */
893b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    while (_isIDSeparator(localeID[trailingIndex])) {
894b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        trailingIndex++;
895b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
89650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    trailing = &localeID[trailingIndex];
89750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    trailingLength = (int32_t)uprv_strlen(trailing);
89850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
89950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    CHECK_TRAILING_VARIANT_SIZE(trailing, trailingLength);
90050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
90150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    resultLength =
90250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        createLikelySubtagsString(
90350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            lang,
90450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            langLength,
90550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            script,
90650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            scriptLength,
90750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            region,
90850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            regionLength,
90950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            trailing,
91050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            trailingLength,
91150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            maximizedLocaleID,
91250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            maximizedLocaleIDCapacity,
91350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            err);
91450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
91550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (resultLength == 0) {
91650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        const int32_t localIDLength = (int32_t)uprv_strlen(localeID);
91750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
91850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        /*
91950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho         * If we get here, we need to return localeID.
92050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho         */
92150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        uprv_memcpy(
92250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            maximizedLocaleID,
92350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            localeID,
92450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            localIDLength <= maximizedLocaleIDCapacity ?
92550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                localIDLength : maximizedLocaleIDCapacity);
92650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
92750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        resultLength =
92850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            u_terminateChars(
92950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                maximizedLocaleID,
93050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                maximizedLocaleIDCapacity,
93150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                localIDLength,
93250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                err);
93350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
93450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
93550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return resultLength;
93650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
93750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoerror:
93850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
93950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (!U_FAILURE(*err)) {
94050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        *err = U_ILLEGAL_ARGUMENT_ERROR;
94150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
94250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
94350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return -1;
94450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
94550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
94650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic int32_t
94750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho_uloc_minimizeSubtags(const char*    localeID,
94850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho         char* minimizedLocaleID,
94950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho         int32_t minimizedLocaleIDCapacity,
95050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho         UErrorCode* err)
95150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
95250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /**
95350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * ULOC_FULLNAME_CAPACITY will provide enough capacity
95450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * that we can build a string that contains the language,
95550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * script and region code without worrying about overrunning
95650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * the user-supplied buffer.
95750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     **/
95850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    char maximizedTagBuffer[ULOC_FULLNAME_CAPACITY];
95950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t maximizedTagBufferLength = sizeof(maximizedTagBuffer);
96050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
96150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    char lang[ULOC_LANG_CAPACITY];
96250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t langLength = sizeof(lang);
96350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    char script[ULOC_SCRIPT_CAPACITY];
96450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t scriptLength = sizeof(script);
96550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    char region[ULOC_COUNTRY_CAPACITY];
96650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t regionLength = sizeof(region);
96750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    const char* trailing = "";
96850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t trailingLength = 0;
96950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t trailingIndex = 0;
97050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
97150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(U_FAILURE(*err)) {
97250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        goto error;
97350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
97450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    else if (localeID == NULL ||
97550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho             minimizedLocaleID == NULL ||
97650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho             minimizedLocaleIDCapacity <= 0) {
97750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        goto error;
97850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
97950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
98050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    trailingIndex =
98150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        parseTagString(
98250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            localeID,
98350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            lang,
98450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            &langLength,
98550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            script,
98650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            &scriptLength,
98750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            region,
98850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            &regionLength,
98950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            err);
99050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(U_FAILURE(*err)) {
99150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
99250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        /* Overflow indicates an illegal argument error */
99350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (*err == U_BUFFER_OVERFLOW_ERROR) {
99450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            *err = U_ILLEGAL_ARGUMENT_ERROR;
99550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
99650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
99750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        goto error;
99850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
99950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
1000b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    /* Find the spot where the variants or the keywords begin, if any. */
1001b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    while (_isIDSeparator(localeID[trailingIndex])) {
1002b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        trailingIndex++;
1003b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
100450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    trailing = &localeID[trailingIndex];
100550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    trailingLength = (int32_t)uprv_strlen(trailing);
100650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
100750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    CHECK_TRAILING_VARIANT_SIZE(trailing, trailingLength);
100850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
100950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    createTagString(
101050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        lang,
101150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        langLength,
101250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        script,
101350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        scriptLength,
101450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        region,
101550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        regionLength,
101650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        NULL,
101750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        0,
101850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        maximizedTagBuffer,
101950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        maximizedTagBufferLength,
102050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        err);
102150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(U_FAILURE(*err)) {
102250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        goto error;
102350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
102450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
102550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /**
102650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * First, we need to first get the maximization
102750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * from AddLikelySubtags.
102850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     **/
102950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    maximizedTagBufferLength =
103050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        uloc_addLikelySubtags(
103150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            maximizedTagBuffer,
103250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            maximizedTagBuffer,
103350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            maximizedTagBufferLength,
103450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            err);
103550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
103650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(U_FAILURE(*err)) {
103750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        goto error;
103850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
103950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
104050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /**
104150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * Start first with just the language.
104250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     **/
104350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    {
104450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        char tagBuffer[ULOC_FULLNAME_CAPACITY];
104550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
104650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        const int32_t tagBufferLength =
104750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            createLikelySubtagsString(
104850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                lang,
104950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                langLength,
105050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                NULL,
105150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                0,
105250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                NULL,
105350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                0,
105450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                NULL,
105550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                0,
105650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                tagBuffer,
105750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                sizeof(tagBuffer),
105850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                err);
105950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
106050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if(U_FAILURE(*err)) {
106150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            goto error;
106250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
106350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        else if (uprv_strnicmp(
106450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    maximizedTagBuffer,
106550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    tagBuffer,
106650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    tagBufferLength) == 0) {
106750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
106850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            return createTagString(
106950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        lang,
107050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        langLength,
107150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        NULL,
107250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        0,
107350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        NULL,
107450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        0,
107550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        trailing,
107650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        trailingLength,
107750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        minimizedLocaleID,
107850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        minimizedLocaleIDCapacity,
107950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        err);
108050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
108150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
108250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
108350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /**
108450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * Next, try the language and region.
108550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     **/
108650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (regionLength > 0) {
108750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
108850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        char tagBuffer[ULOC_FULLNAME_CAPACITY];
108950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
109050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        const int32_t tagBufferLength =
109150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            createLikelySubtagsString(
109250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                lang,
109350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                langLength,
109450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                NULL,
109550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                0,
109650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                region,
109750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                regionLength,
109850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                NULL,
109950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                0,
110050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                tagBuffer,
110150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                sizeof(tagBuffer),
110250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                err);
110350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
110450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if(U_FAILURE(*err)) {
110550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            goto error;
110650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
110750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        else if (uprv_strnicmp(
110850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    maximizedTagBuffer,
110950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    tagBuffer,
111050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    tagBufferLength) == 0) {
111150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
111250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            return createTagString(
111350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        lang,
111450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        langLength,
111550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        NULL,
111650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        0,
111750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        region,
111850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        regionLength,
111950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        trailing,
112050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        trailingLength,
112150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        minimizedLocaleID,
112250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        minimizedLocaleIDCapacity,
112350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        err);
112450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
112550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
112650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
112750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /**
112850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * Finally, try the language and script.  This is our last chance,
112950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * since trying with all three subtags would only yield the
113050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * maximal version that we already have.
113150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     **/
113250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (scriptLength > 0 && regionLength > 0) {
113350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        char tagBuffer[ULOC_FULLNAME_CAPACITY];
113450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
113550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        const int32_t tagBufferLength =
113650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            createLikelySubtagsString(
113750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                lang,
113850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                langLength,
113950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                script,
114050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                scriptLength,
114150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                NULL,
114250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                0,
114350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                NULL,
114450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                0,
114550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                tagBuffer,
114650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                sizeof(tagBuffer),
114750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                err);
114850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
114950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if(U_FAILURE(*err)) {
115050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            goto error;
115150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
115250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        else if (uprv_strnicmp(
115350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    maximizedTagBuffer,
115450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    tagBuffer,
115550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    tagBufferLength) == 0) {
115650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
115750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            return createTagString(
115850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        lang,
115950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        langLength,
116050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        script,
116150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        scriptLength,
116250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        NULL,
116350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        0,
116450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        trailing,
116550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        trailingLength,
116650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        minimizedLocaleID,
116750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        minimizedLocaleIDCapacity,
116850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                        err);
116950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
117050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
117150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
117250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    {
117350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        /**
117450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho         * If we got here, return the locale ID parameter.
117550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho         **/
117650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        const int32_t localeIDLength = (int32_t)uprv_strlen(localeID);
117750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
117850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        uprv_memcpy(
117950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            minimizedLocaleID,
118050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            localeID,
118150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            localeIDLength <= minimizedLocaleIDCapacity ?
118250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                localeIDLength : minimizedLocaleIDCapacity);
118350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
118450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return u_terminateChars(
118550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    minimizedLocaleID,
118650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    minimizedLocaleIDCapacity,
118750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    localeIDLength,
118850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    err);
118950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
119050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
119150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoerror:
119250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
119350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (!U_FAILURE(*err)) {
119450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        *err = U_ILLEGAL_ARGUMENT_ERROR;
119550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
119650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
119750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return -1;
119850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
119950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
120050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
120150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
120250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic UBool
120350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehodo_canonicalize(const char*    localeID,
120450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho         char* buffer,
120550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho         int32_t bufferCapacity,
120650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho         UErrorCode* err)
120750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
120850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    uloc_canonicalize(
120950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        localeID,
121050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        buffer,
121150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        bufferCapacity,
121250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        err);
121350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
121450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (*err == U_STRING_NOT_TERMINATED_WARNING ||
121550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        *err == U_BUFFER_OVERFLOW_ERROR) {
121650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        *err = U_ILLEGAL_ARGUMENT_ERROR;
121750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
121850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return FALSE;
121950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
122050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    else if (U_FAILURE(*err)) {
122150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
122250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return FALSE;
122350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
122450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    else {
122550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return TRUE;
122650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
122750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
122850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
122954dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusU_CAPI int32_t U_EXPORT2
123050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehouloc_addLikelySubtags(const char*    localeID,
123150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho         char* maximizedLocaleID,
123250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho         int32_t maximizedLocaleIDCapacity,
123350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho         UErrorCode* err)
123450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
123550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    char localeBuffer[ULOC_FULLNAME_CAPACITY];
123650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
123750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (!do_canonicalize(
123850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        localeID,
123950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        localeBuffer,
124050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        sizeof(localeBuffer),
124150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        err)) {
124250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return -1;
124350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
124450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    else {
124550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return _uloc_addLikelySubtags(
124650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    localeBuffer,
124750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    maximizedLocaleID,
124850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    maximizedLocaleIDCapacity,
124950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    err);
125050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
125150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
125250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
125354dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusU_CAPI int32_t U_EXPORT2
125450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehouloc_minimizeSubtags(const char*    localeID,
125550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho         char* minimizedLocaleID,
125650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho         int32_t minimizedLocaleIDCapacity,
125750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho         UErrorCode* err)
125850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
125950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    char localeBuffer[ULOC_FULLNAME_CAPACITY];
126050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
126150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (!do_canonicalize(
126250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        localeID,
126350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        localeBuffer,
126450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        sizeof(localeBuffer),
126550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        err)) {
126650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return -1;
126750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
126850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    else {
126950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return _uloc_minimizeSubtags(
127050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    localeBuffer,
127150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    minimizedLocaleID,
127250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    minimizedLocaleIDCapacity,
127350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    err);
127450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
127550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
1276