Example #1
0
    static int32_t parseSetNum(const char *setNumStr, UErrorCode &errorCode) {
        if (U_FAILURE(errorCode)) { return -1; }

        if (uprv_strncmp(setNumStr, "set", 3) != 0) {
            errorCode = U_INVALID_FORMAT_ERROR;
            return -1;
        }

        int32_t i = 3;
        int32_t setNum = 0;
        while (setNumStr[i] != 0) {
            int32_t digit = setNumStr[i] - '0';
            if (digit < 0 || 9 < digit) {
                errorCode = U_INVALID_FORMAT_ERROR;
                return -1;
            }
            setNum = 10 * setNum + digit;
            ++i;
        }

        // Rule set number must not be zero. (0 is used to indicate "not found" by hashmap.)
        // Currently ICU data conveniently starts numbering rule sets from 1.
        if (setNum == 0) {
            errorCode = U_INVALID_FORMAT_ERROR;
            return -1;
        } else {
            return setNum;
        }
    }
Example #2
0
UBool
DigitList::operator==(const DigitList& that) const
{
    return ((this == &that) ||
            (fDecimalAt == that.fDecimalAt &&
             fCount == that.fCount &&
             fIsPositive == that.fIsPositive &&
             fRoundingMode == that.fRoundingMode &&
             uprv_strncmp(fDigits, that.fDigits, fCount) == 0));
}
Example #3
0
static int32_t
_getStringOrCopyKey(const char *path, const char *locale,
                    const char *tableKey, 
                    const char* subTableKey,
                    const char *itemKey,
                    const char *substitute,
                    UChar *dest, int32_t destCapacity,
                    UErrorCode *pErrorCode) {
    const UChar *s = NULL;
    int32_t length = 0;

    if(itemKey==NULL) {
        /* top-level item: normal resource bundle access */
        UResourceBundle *rb;

        rb=ures_open(path, locale, pErrorCode);

        if(U_SUCCESS(*pErrorCode)) {
            s=ures_getStringByKey(rb, tableKey, &length, pErrorCode);
            /* see comment about closing rb near "return item;" in _res_getTableStringWithFallback() */
            ures_close(rb);
        }
    } else {
        /* Language code should not be a number. If it is, set the error code. */
        if (!uprv_strncmp(tableKey, "Languages", 9) && uprv_strtol(itemKey, NULL, 10)) {
            *pErrorCode = U_MISSING_RESOURCE_ERROR;
        } else {
            /* second-level item, use special fallback */
            s=uloc_getTableStringWithFallback(path, locale,
                                               tableKey, 
                                               subTableKey,
                                               itemKey,
                                               &length,
                                               pErrorCode);
        }
    }

    if(U_SUCCESS(*pErrorCode)) {
        int32_t copyLength=uprv_min(length, destCapacity);
        if(copyLength>0 && s != NULL) {
            u_memcpy(dest, s, copyLength);
        }
    } else {
        /* no string from a resource bundle: convert the substitute */
        length=(int32_t)uprv_strlen(substitute);
        u_charsToUChars(substitute, dest, uprv_min(length, destCapacity));
        *pErrorCode=U_USING_DEFAULT_WARNING;
    }

    return u_terminateUChars(dest, destCapacity, length, pErrorCode);
}
Example #4
0
static void U_CALLCONV
ageLineFn(void *context,
          char *fields[][2], int32_t fieldCount,
          UErrorCode *pErrorCode) {
    char *s, *numberLimit;
    uint32_t value, start, end, version;

    u_parseCodePointRange(fields[0][0], &start, &end, pErrorCode);
    if(U_FAILURE(*pErrorCode)) {
        fprintf(stderr, "genprops: syntax error in DerivedAge.txt field 0 at %s\n", fields[0][0]);
        exit(*pErrorCode);
    }

    /* ignore "unassigned" (the default is already set to 0.0) */
    s=(char *)u_skipWhitespace(fields[1][0]);
    if(0==uprv_strncmp(s, "unassigned", 10)) {
        return;
    }

    /* parse version number */
    value=(uint32_t)uprv_strtoul(s, &numberLimit, 10);
    if(s==numberLimit || value==0 || value>15 || (*numberLimit!='.' && *numberLimit!=' ' && *numberLimit!='\t' && *numberLimit!=0)) {
        fprintf(stderr, "genprops: syntax error in DerivedAge.txt field 1 at %s\n", fields[1][0]);
        *pErrorCode=U_PARSE_ERROR;
        exit(U_PARSE_ERROR);
    }
    version=value<<4;

    /* parse minor version number */
    if(*numberLimit=='.') {
        s=(char *)u_skipWhitespace(numberLimit+1);
        value=(uint32_t)uprv_strtoul(s, &numberLimit, 10);
        if(s==numberLimit || value>15 || (*numberLimit!=' ' && *numberLimit!='\t' && *numberLimit!=0)) {
            fprintf(stderr, "genprops: syntax error in DerivedAge.txt field 1 at %s\n", fields[1][0]);
            *pErrorCode=U_PARSE_ERROR;
            exit(U_PARSE_ERROR);
        }
        version|=value;
    }

    if(start==0 && end==0x10ffff) {
        /* Also set bits for initialValue and errorValue. */
        end=UPVEC_MAX_CP;
    }
    upvec_setValue(pv, start, end, 0, version<<UPROPS_AGE_SHIFT, UPROPS_AGE_MASK, pErrorCode);
    if(U_FAILURE(*pErrorCode)) {
        fprintf(stderr, "genprops error: unable to set character age: %s\n", u_errorName(*pErrorCode));
        exit(*pErrorCode);
    }
}
Example #5
0
/*
 * Extract the setting after the '=' and store it in flag excluding the newline character.
 */
static int32_t extractFlag(char* buffer, int32_t bufferSize, char* flag, int32_t flagSize, const char **flagNames, int32_t numOfFlags, UErrorCode *status) {
    int32_t i, idx = -1;
    char *pBuffer;
    int32_t offset=0;
    UBool bufferWritten = FALSE;

    if (buffer[0] != 0) {
        /* Get the offset (i.e. position after the '=') */
        offset = getFlagOffset(buffer, bufferSize);
        pBuffer = buffer+offset;
        for(i = 0;;i++) {
            if (i >= flagSize) {
                *status = U_BUFFER_OVERFLOW_ERROR;
                return -1;
            }
            if (pBuffer[i+1] == 0) {
                /* Indicates a new line character. End here. */
                flag[i] = 0;
                break;
            }

            flag[i] = pBuffer[i];
            if (i == 0) {
                bufferWritten = TRUE;
            }
        }
    }

    if (!bufferWritten) {
        flag[0] = 0;
    }

    if (flagNames != NULL && offset>0) {
        offset--;  /* Move offset back 1 because of '='*/
        for (i = 0; i < numOfFlags; i++) {
            if (uprv_strncmp(buffer, flagNames[i], offset) == 0) {
                idx = i;
                break;
            }
        }
    }

    return idx;
}
Example #6
0
static const char *udata_pathiter_next(UDataPathIterator *iter)
{
    const char *path = NULL;
    uint32_t     pathLen = 0;
    const char *pathBasename;

    do
    {
        if( iter->nextPath == NULL ) {
            break;
        }
        
        path = iter->nextPath;
        
        if(iter->nextPath == iter->itemPath) { /* we were processing item's path. */
            iter->nextPath = iter->path; /* start with regular path next tm. */
            pathLen = (int32_t)uprv_strlen(path);
        } else {
            /* fix up next for next time */
            iter->nextPath = uprv_strchr(path, U_PATH_SEP_CHAR);
            if(iter->nextPath == NULL) {
                /* segment: entire path */
                pathLen = (int32_t)uprv_strlen(path); 
            } else {
                /* segment: until next segment */
                pathLen = (int32_t)(iter->nextPath - path);
                if(*iter->nextPath) { /* skip divider */
                    iter->nextPath ++;
                }
            }
        }

        if(pathLen == 0) {
            continue;
        }

#ifdef UDATA_DEBUG
        fprintf(stderr, "rest of path (IDD) = %s\n", path);
        fprintf(stderr, "                     ");
        { 
            uint32_t qqq;
            for(qqq=0;qqq<pathLen;qqq++)
            {
                fprintf(stderr, " ");
            }

            fprintf(stderr, "^\n");
        }
#endif
        uprv_strncpy(iter->pathBuffer, path, pathLen);
        iter->pathBuffer[pathLen] = 0;

        /* check for .dat files */
        pathBasename = findBasename(iter->pathBuffer);

        if(iter->checkLastFour == TRUE && 
           (pathLen>=4) &&
           uprv_strncmp(iter->pathBuffer +(pathLen-4),iter->suffix,4)==0 && /* suffix matches */
           uprv_strncmp(findBasename(iter->pathBuffer),iter->basename,iter->basenameLen)==0  && /* base matches */
           uprv_strlen(pathBasename)==(iter->basenameLen+4)) { /* base+suffix = full len */
            
#ifdef UDATA_DEBUG
            fprintf(stderr, "Have %s file on the path: %s\n", iter->suffix, iter->pathBuffer);
#endif
            /* do nothing */
        }
        else 
        {       /* regular dir path */
            if(iter->pathBuffer[pathLen-1] != U_FILE_SEP_CHAR) {
                if((pathLen>=4) &&
                   uprv_strncmp(iter->pathBuffer+(pathLen-4), ".dat", 4) == 0)
                {
#ifdef UDATA_DEBUG
                    fprintf(stderr, "skipping non-directory .dat file %s\n", iter->pathBuffer);
#endif
                    continue;
                }

                /* Check if it is a directory with the same name as our package */
                if(iter->packageStubLen &&  
                   (pathLen > iter->packageStubLen) &&
                   !uprv_strcmp(iter->pathBuffer + pathLen - iter->packageStubLen, iter->packageStub)) {
#ifdef UDATA_DEBUG
                  fprintf(stderr, "Found stub %s ( will add package %s of len %d)\n", iter->packageStub, iter->basename, iter->basenameLen);
#endif
                  pathLen -= iter->packageStubLen;
                }
                     
                iter->pathBuffer[pathLen++] = U_FILE_SEP_CHAR;
            } 
            
            uprv_strncpy(iter->pathBuffer + pathLen,  /* + basename */
                         iter->packageStub+1,
                         iter->packageStubLen-1);

            pathLen += iter->packageStubLen-1;

            if(*iter->suffix)  /* tack on suffix */
            {
                uprv_strcpy(iter->pathBuffer + pathLen,
                            iter->suffix);
                pathLen += (int32_t)uprv_strlen(iter->suffix);
            }
            
        }

#ifdef UDATA_DEBUG
        fprintf(stderr, " -->  %s\n", iter->pathBuffer);
#endif

        return iter->pathBuffer;

    } while(iter->path);

    /* fell way off the end */
    return NULL;
}
Example #7
0
static void TestFileStream(void){
    int32_t c = 0;
    int32_t c1=0;
    UErrorCode status = U_ZERO_ERROR;
    const char* testdatapath = loadTestData(&status);
    char* fileName = (char*) malloc(uprv_strlen(testdatapath) +10);
    FileStream* stream = NULL;
    /* these should not be closed */
    FileStream* pStdin  = T_FileStream_stdin();
    FileStream* pStdout = T_FileStream_stdout();
    FileStream* pStderr = T_FileStream_stderr();

    const char* testline = "This is a test line";
    int32_t bufLen = (int32_t)strlen(testline)+10;
    char* buf = (char*) malloc(bufLen);
    int32_t retLen = 0;

    if(pStdin==NULL){
        log_err("failed to get T_FileStream_stdin()");
    }
    if(pStdout==NULL){
        log_err("failed to get T_FileStream_stdout()");
    }
    if(pStderr==NULL){
        log_err("failed to get T_FileStream_stderr()");
    }

    uprv_strcpy(fileName,testdatapath);
    uprv_strcat(fileName,".dat");
    stream = T_FileStream_open(fileName, "r");
    if(stream==NULL){
        log_data_err("T_FileStream_open failed to open %s\n",fileName);
    } else {
      if(!T_FileStream_file_exists(fileName)){
        log_data_err("T_FileStream_file_exists failed to verify existence of %s \n",fileName);
      }
      
      retLen=T_FileStream_read(stream,&c,1);
      if(retLen==0){
        log_data_err("T_FileStream_read failed to read from %s \n",fileName);
      }
      retLen=0;
      T_FileStream_rewind(stream);
      T_FileStream_read(stream,&c1,1);
      if(c!=c1){
        log_data_err("T_FileStream_rewind failed to rewind %s \n",fileName);
      }
      T_FileStream_rewind(stream);
      c1 = T_FileStream_peek(stream);
      if(c!=c1){
        log_data_err("T_FileStream_peek failed to peekd %s \n",fileName);
      }
      c = T_FileStream_getc(stream);
      T_FileStream_ungetc(c,stream);
      if(c!= T_FileStream_getc(stream)){
        log_data_err("T_FileStream_ungetc failed to d %s \n",fileName);
      }
      
      if(T_FileStream_size(stream)<=0){
        log_data_err("T_FileStream_size failed to d %s \n",fileName);
      }
      if(T_FileStream_error(stream)){
        log_data_err("T_FileStream_error shouldn't have an error %s\n",fileName);
      }
      if(!T_FileStream_error(NULL)){
        log_err("T_FileStream_error didn't get an error %s\n",fileName);
      }
      T_FileStream_putc(stream, 0x20);
      if(!T_FileStream_error(stream)){
        /*
          Warning 
          writing to a read-only file may not consistently fail on all platforms
          (e.g. HP-UX, FreeBSD, MacOSX)
        */
        log_verbose("T_FileStream_error didn't get an error when writing to a readonly file %s\n",fileName);
      }

      T_FileStream_close(stream);
    }
    /* test writing function */
    stream=NULL;
    uprv_strcpy(fileName,testdatapath);
    uprv_strcat(fileName,".tmp");
    stream = T_FileStream_open(fileName,"w+");

    if(stream == NULL){
        log_data_err("Could not open %s for writing\n",fileName);
    } else {
      c= '$';
      T_FileStream_putc(stream,c);
      T_FileStream_rewind(stream);
      if(c != T_FileStream_getc(stream)){
        log_data_err("T_FileStream_putc failed %s\n",fileName);
      }

      T_FileStream_rewind(stream);
      T_FileStream_writeLine(stream,testline);
      T_FileStream_rewind(stream);
      T_FileStream_readLine(stream,buf,bufLen);
      if(uprv_strncmp(testline, buf,uprv_strlen(buf))!=0){
        log_data_err("T_FileStream_writeLine failed %s\n",fileName);
      }

      T_FileStream_rewind(stream);
      T_FileStream_write(stream,testline,(int32_t)strlen(testline));
      T_FileStream_rewind(stream);
      retLen = T_FileStream_read(stream, buf, bufLen);
      if(uprv_strncmp(testline, buf,retLen)!=0){
        log_data_err("T_FileStream_write failed %s\n",fileName);
      }

      T_FileStream_close(stream);
    }
    if(!T_FileStream_remove(fileName)){
        log_data_err("T_FileStream_remove failed to delete %s\n",fileName);
    }


    free(fileName);
    free(buf);

}
//-------------------------------------------------------------------------------
//      
//  Read a text data file, convert it from UTF-8 to UChars, and return the data
//    in one big UChar * buffer, which the caller must delete.
//
//    (Lightly modified version of a similar function in regextst.cpp)
//
//--------------------------------------------------------------------------------
UChar *DecimalFormatTest::ReadAndConvertFile(const char *fileName, int32_t &ulen,
                                     UErrorCode &status) {
    UChar       *retPtr  = NULL;
    char        *fileBuf = NULL;
    const char  *fileBufNoBOM = NULL;
    FILE        *f       = NULL;

    ulen = 0;
    if (U_FAILURE(status)) {
        return retPtr;
    }

    //
    //  Open the file.
    //
    f = fopen(fileName, "rb");
    if (f == 0) {
        dataerrln("Error opening test data file %s\n", fileName);
        status = U_FILE_ACCESS_ERROR;
        return NULL;
    }
    //
    //  Read it in
    //
    int32_t            fileSize;
    int32_t            amtRead;
    int32_t            amtReadNoBOM;

    fseek( f, 0, SEEK_END);
    fileSize = ftell(f);
    fileBuf = new char[fileSize];
    fseek(f, 0, SEEK_SET);
    amtRead = fread(fileBuf, 1, fileSize, f);
    if (amtRead != fileSize || fileSize <= 0) {
        errln("Error reading test data file.");
        goto cleanUpAndReturn;
    }

    //
    // Look for a UTF-8 BOM on the data just read.
    //    The test data file is UTF-8.
    //    The BOM needs to be there in the source file to keep the Windows & 
    //    EBCDIC machines happy, so force an error if it goes missing.  
    //    Many Linux editors will silently strip it.
    //
    fileBufNoBOM = fileBuf + 3;
    amtReadNoBOM = amtRead - 3;
    if (fileSize<3 || uprv_strncmp(fileBuf, "\xEF\xBB\xBF", 3) != 0) {
        // TODO:  restore this check.
        errln("Test data file %s is missing its BOM", fileName);
        fileBufNoBOM = fileBuf;
        amtReadNoBOM = amtRead;
    }

    //
    // Find the length of the input in UTF-16 UChars
    //  (by preflighting the conversion)
    //
    u_strFromUTF8(NULL, 0, &ulen, fileBufNoBOM, amtReadNoBOM, &status);

    //
    // Convert file contents from UTF-8 to UTF-16
    //
    if (status == U_BUFFER_OVERFLOW_ERROR) {
        // Buffer Overflow is expected from the preflight operation.
        status = U_ZERO_ERROR;
        retPtr = new UChar[ulen+1];
        u_strFromUTF8(retPtr, ulen+1, NULL, fileBufNoBOM, amtReadNoBOM, &status);
    }

cleanUpAndReturn:
    fclose(f);
    delete[] fileBuf;
    if (U_FAILURE(status)) {
        errln("ICU Error \"%s\"\n", u_errorName(status));
        delete retPtr;
        retPtr = NULL;
    };
    return retPtr;
}
/*
 * state table row grammar (ebnf-style):
 * (whitespace is allowed between all tokens)
 *
 * row=[[firstentry ','] entry (',' entry)*]
 * firstentry="initial" | "surrogates"
 *            (initial state (default for state 0), output is all surrogate pairs)
 * entry=range [':' nextstate] ['.' action]
 * range=number ['-' number]
 * nextstate=number
 *           (0..7f)
 * action='u' | 's' | 'p' | 'i'
 *        (unassigned, state change only, surrogate pair, illegal)
 * number=(1- or 2-digit hexadecimal number)
 */
static const char *
parseState(const char *s, int32_t state[256], uint32_t *pFlags) {
    const char *t;
    uint32_t start, end, i;
    int32_t entry;

    /* initialize the state: all illegal with U+ffff */
    for(i=0; i<256; ++i) {
        state[i]=MBCS_ENTRY_FINAL(0, MBCS_STATE_ILLEGAL, 0xffff);
    }

    /* skip leading white space */
    s=u_skipWhitespace(s);

    /* is there an "initial" or "surrogates" directive? */
    if(uprv_strncmp("initial", s, 7)==0) {
        *pFlags=MBCS_STATE_FLAG_DIRECT;
        s=u_skipWhitespace(s+7);
        if(*s++!=',') {
            return s-1;
        }
    } else if(*pFlags==0 && uprv_strncmp("surrogates", s, 10)==0) {
        *pFlags=MBCS_STATE_FLAG_SURROGATES;
        s=u_skipWhitespace(s+10);
        if(*s++!=',') {
            return s-1;
        }
    } else if(*s==0) {
        /* empty state row: all-illegal */
        return NULL;
    }

    for(;;) {
        /* read an entry, the start of the range first */
        s=u_skipWhitespace(s);
        start=uprv_strtoul(s, (char **)&t, 16);
        if(s==t || 0xff<start) {
            return s;
        }
        s=u_skipWhitespace(t);

        /* read the end of the range if there is one */
        if(*s=='-') {
            s=u_skipWhitespace(s+1);
            end=uprv_strtoul(s, (char **)&t, 16);
            if(s==t || end<start || 0xff<end) {
                return s;
            }
            s=u_skipWhitespace(t);
        } else {
            end=start;
        }

        /* determine the state entrys for this range */
        if(*s!=':' && *s!='.') {
            /* the default is: final state with valid entries */
            entry=MBCS_ENTRY_FINAL(0, MBCS_STATE_VALID_16, 0);
        } else {
            entry=MBCS_ENTRY_TRANSITION(0, 0);
            if(*s==':') {
                /* get the next state, default to 0 */
                s=u_skipWhitespace(s+1);
                i=uprv_strtoul(s, (char **)&t, 16);
                if(s!=t) {
                    if(0x7f<i) {
                        return s;
                    }
                    s=u_skipWhitespace(t);
                    entry=MBCS_ENTRY_SET_STATE(entry, i);
                }
            }

            /* get the state action, default to valid */
            if(*s=='.') {
                /* this is a final state */
                entry=MBCS_ENTRY_SET_FINAL(entry);

                s=u_skipWhitespace(s+1);
                if(*s=='u') {
                    /* unassigned set U+fffe */
                    entry=MBCS_ENTRY_FINAL_SET_ACTION_VALUE(entry, MBCS_STATE_UNASSIGNED, 0xfffe);
                    s=u_skipWhitespace(s+1);
                } else if(*s=='p') {
                    if(*pFlags!=MBCS_STATE_FLAG_DIRECT) {
                        entry=MBCS_ENTRY_FINAL_SET_ACTION(entry, MBCS_STATE_VALID_16_PAIR);
                    } else {
                        entry=MBCS_ENTRY_FINAL_SET_ACTION(entry, MBCS_STATE_VALID_16);
                    }
                    s=u_skipWhitespace(s+1);
                } else if(*s=='s') {
                    entry=MBCS_ENTRY_FINAL_SET_ACTION(entry, MBCS_STATE_CHANGE_ONLY);
                    s=u_skipWhitespace(s+1);
                } else if(*s=='i') {
                    /* illegal set U+ffff */
                    entry=MBCS_ENTRY_FINAL_SET_ACTION_VALUE(entry, MBCS_STATE_ILLEGAL, 0xffff);
                    s=u_skipWhitespace(s+1);
                } else {
                    /* default to valid */
                    entry=MBCS_ENTRY_FINAL_SET_ACTION(entry, MBCS_STATE_VALID_16);
                }
            } else {
                /* this is an intermediate state, nothing to do */
            }
        }

        /* adjust "final valid" states according to the state flags */
        if(MBCS_ENTRY_FINAL_ACTION(entry)==MBCS_STATE_VALID_16) {
            switch(*pFlags) {
            case 0:
                /* no adjustment */
                break;
            case MBCS_STATE_FLAG_DIRECT:
                /* set the valid-direct code point to "unassigned"==0xfffe */
                entry=MBCS_ENTRY_FINAL_SET_ACTION_VALUE(entry, MBCS_STATE_VALID_DIRECT_16, 0xfffe);
                break;
            case MBCS_STATE_FLAG_SURROGATES:
                entry=MBCS_ENTRY_FINAL_SET_ACTION_VALUE(entry, MBCS_STATE_VALID_16_PAIR, 0);
                break;
            default:
                break;
            }
        }

        /* set this entry for the range */
        for(i=start; i<=end; ++i) {
            state[i]=entry;
        }

        if(*s==',') {
            ++s;
        } else {
            return *s==0 ? NULL : s;
        }
    }
}
Example #10
0
U_CAPI const char* U_EXPORT2
uprv_tzname(int n)
{
#ifdef U_WINDOWS
    const char *id = uprv_detectWindowsTimeZone();

    if (id != NULL) {
        return id;
    }
#else
    const char *tzenv = NULL;

/*#if defined(U_DARWIN)
    int ret;

    tzenv = getenv("TZFILE");
    if (tzenv != NULL) {
        return tzenv;
    }
#endif*/

    tzenv = getenv("TZ");
    if (tzenv != NULL && isValidOlsonID(tzenv))
    {
        /* This might be a good Olson ID. */
        if (uprv_strncmp(tzenv, "posix/", 6) == 0
            || uprv_strncmp(tzenv, "right/", 6) == 0)
        {
            /* Remove the posix/ or right/ prefix. */
            tzenv += 6;
        }
        return tzenv;
    }
    /* else U_TZNAME will give a better result. */

#if defined(CHECK_LOCALTIME_LINK)
    /* Caller must handle threading issues */
    if (gTimeZoneBufferPtr == NULL) {
        /*
        This is a trick to look at the name of the link to get the Olson ID
        because the tzfile contents is underspecified.
        This isn't guaranteed to work because it may not be a symlink.
        */
        int32_t ret = (int32_t)readlink(TZZONELINK, gTimeZoneBuffer, sizeof(gTimeZoneBuffer));
        if (0 < ret) {
            int32_t tzZoneInfoLen = uprv_strlen(TZZONEINFO);
            gTimeZoneBuffer[ret] = 0;
            if (uprv_strncmp(gTimeZoneBuffer, TZZONEINFO, tzZoneInfoLen) == 0
                && isValidOlsonID(gTimeZoneBuffer + tzZoneInfoLen))
            {
                return (gTimeZoneBufferPtr = gTimeZoneBuffer + tzZoneInfoLen);
            }
        }
    }
    else {
        return gTimeZoneBufferPtr;
    }
#endif
#endif

#ifdef U_TZNAME
    /*
    U_TZNAME is usually a non-unique abbreviation,
    which isn't normally usable.
    */
    return U_TZNAME[n];
#else
    return "";
#endif
}
Example #11
0
/* NOTE: The caller should handle thread safety */
U_CAPI const char* U_EXPORT2
uprv_getDefaultLocaleID()
{
#if U_POSIX_LOCALE
/*
  Note that:  (a '!' means the ID is improper somehow)
     LC_ALL  ---->     default_loc          codepage
--------------------------------------------------------
     ab.CD             ab                   CD
     ab@CD             ab__CD               -
     [email protected]          ab__CD               EF

     ab_CD.EF@GH       ab_CD_GH             EF

Some 'improper' ways to do the same as above:
  !  [email protected]       ab_CD_GH             EF
  !  [email protected]    ab_CD_GH             EF
  !  [email protected]@GH.IJ ab_CD_GH             EF

     _CD@GH            _CD_GH               -
     _CD.EF@GH         _CD_GH               EF

The variant cannot have dots in it.
The 'rightmost' variant (@xxx) wins.
The leftmost codepage (.xxx) wins.
*/
    char *correctedPOSIXLocale = 0;
    const char* posixID = uprv_getPOSIXID();
    const char *p;
    const char *q;
    int32_t len;

    /* Format: (no spaces)
    ll [ _CC ] [ . MM ] [ @ VV]

      l = lang, C = ctry, M = charmap, V = variant
    */

    if (gCorrectedPOSIXLocale != NULL) {
        return gCorrectedPOSIXLocale; 
    }

    if ((p = uprv_strchr(posixID, '.')) != NULL) {
        /* assume new locale can't be larger than old one? */
        correctedPOSIXLocale = (char*) uprv_malloc(uprv_strlen(posixID)+1);
        uprv_strncpy(correctedPOSIXLocale, posixID, p-posixID);
        correctedPOSIXLocale[p-posixID] = 0;

        /* do not copy after the @ */
        if ((p = uprv_strchr(correctedPOSIXLocale, '@')) != NULL) {
            correctedPOSIXLocale[p-correctedPOSIXLocale] = 0;
        }
    }

    /* Note that we scan the *uncorrected* ID. */
    if ((p = uprv_strrchr(posixID, '@')) != NULL) {
        if (correctedPOSIXLocale == NULL) {
            correctedPOSIXLocale = (char*) uprv_malloc(uprv_strlen(posixID)+1);
            uprv_strncpy(correctedPOSIXLocale, posixID, p-posixID);
            correctedPOSIXLocale[p-posixID] = 0;
        }
        p++;

        /* Take care of any special cases here.. */
        if (!uprv_strcmp(p, "nynorsk")) {
            p = "NY";
            /* Don't worry about no__NY. In practice, it won't appear. */
        }

        if (uprv_strchr(correctedPOSIXLocale,'_') == NULL) {
            uprv_strcat(correctedPOSIXLocale, "__"); /* aa@b -> aa__b */
        }
        else {
            uprv_strcat(correctedPOSIXLocale, "_"); /* aa_CC@b -> aa_CC_b */
        }

        if ((q = uprv_strchr(p, '.')) != NULL) {
            /* How big will the resulting string be? */
            len = (int32_t)(uprv_strlen(correctedPOSIXLocale) + (q-p));
            uprv_strncat(correctedPOSIXLocale, p, q-p);
            correctedPOSIXLocale[len] = 0;
        }
        else {
            /* Anything following the @ sign */
            uprv_strcat(correctedPOSIXLocale, p);
        }

        /* Should there be a map from 'no@nynorsk' -> no_NO_NY here?
         * How about 'russian' -> 'ru'?
         * Many of the other locales using ISO codes will be handled by the
         * canonicalization functions in uloc_getDefault.
         */
    }

    /* Was a correction made? */
    if (correctedPOSIXLocale != NULL) {
        posixID = correctedPOSIXLocale;
    }
    else {
        /* copy it, just in case the original pointer goes away.  See j2395 */
        correctedPOSIXLocale = (char *)uprv_malloc(uprv_strlen(posixID) + 1);
        posixID = uprv_strcpy(correctedPOSIXLocale, posixID);
    }

    if (gCorrectedPOSIXLocale == NULL) {
        gCorrectedPOSIXLocale = correctedPOSIXLocale;
        ucln_common_registerCleanup(UCLN_COMMON_PUTIL, putil_cleanup);
        correctedPOSIXLocale = NULL;
    }

    if (correctedPOSIXLocale != NULL) {  /* Was already set - clean up. */
        uprv_free(correctedPOSIXLocale); 
    }

    return posixID;

#elif defined(U_WINDOWS)
    UErrorCode status = U_ZERO_ERROR;
    LCID id = GetThreadLocale();
    const char* locID = uprv_convertToPosix(id, &status);

    if (U_FAILURE(status)) {
        locID = "en_US";
    }
    return locID;

#elif defined(XP_MAC)
    int32_t script = MAC_LC_INIT_NUMBER;
    /* = IntlScript(); or GetScriptManagerVariable(smSysScript);*/
    int32_t region = MAC_LC_INIT_NUMBER;
    /* = GetScriptManagerVariable(smRegionCode);*/
    int32_t lang = MAC_LC_INIT_NUMBER;
    /* = GetScriptManagerVariable(smScriptLang);*/
    int32_t date_region = MAC_LC_INIT_NUMBER;
    const char* posixID = 0;
    int32_t count = sizeof(mac_lc_recs) / sizeof(mac_lc_rec);
    int32_t i;
    Intl1Hndl ih;

    ih = (Intl1Hndl) GetIntlResource(1);
    if (ih)
        date_region = ((uint16_t)(*ih)->intl1Vers) >> 8;

    for (i = 0; i < count; i++) {
        if (   ((mac_lc_recs[i].script == MAC_LC_MAGIC_NUMBER)
             || (mac_lc_recs[i].script == script))
            && ((mac_lc_recs[i].region == MAC_LC_MAGIC_NUMBER)
             || (mac_lc_recs[i].region == region))
            && ((mac_lc_recs[i].lang == MAC_LC_MAGIC_NUMBER)
             || (mac_lc_recs[i].lang == lang))
            && ((mac_lc_recs[i].date_region == MAC_LC_MAGIC_NUMBER)
             || (mac_lc_recs[i].date_region == date_region))
            )
        {
            posixID = mac_lc_recs[i].posixID;
            break;
        }
    }

    return posixID;

#elif defined(OS400)
    /* locales are process scoped and are by definition thread safe */
    static char correctedLocale[64];
    const  char *localeID = getenv("LC_ALL");
           char *p;

    if (localeID == NULL)
        localeID = getenv("LANG");
    if (localeID == NULL)
        localeID = setlocale(LC_ALL, NULL);
    /* Make sure we have something... */
    if (localeID == NULL)
        return "en_US_POSIX";

    /* Extract the locale name from the path. */
    if((p = uprv_strrchr(localeID, '/')) != NULL)
    {
        /* Increment p to start of locale name. */
        p++;
        localeID = p;
    }

    /* Copy to work location. */
    uprv_strcpy(correctedLocale, localeID);

    /* Strip off the '.locale' extension. */
    if((p = uprv_strchr(correctedLocale, '.')) != NULL) {
        *p = 0;
    }

    /* Upper case the locale name. */
    T_CString_toUpperCase(correctedLocale);

    /* See if we are using the POSIX locale.  Any of the
    * following are equivalent and use the same QLGPGCMA
    * (POSIX) locale.
    * QLGPGCMA2 means UCS2
    * QLGPGCMA_4 means UTF-32
    * QLGPGCMA_8 means UTF-8
    */
    if ((uprv_strcmp("C", correctedLocale) == 0) ||
        (uprv_strcmp("POSIX", correctedLocale) == 0) ||
        (uprv_strncmp("QLGPGCMA", correctedLocale, 8) == 0))
    {
        uprv_strcpy(correctedLocale, "en_US_POSIX");
    }
    else
    {
        int16_t LocaleLen;

        /* Lower case the lang portion. */
        for(p = correctedLocale; *p != 0 && *p != '_'; p++)
        {
            *p = uprv_tolower(*p);
        }

        /* Adjust for Euro.  After '_E' add 'URO'. */
        LocaleLen = uprv_strlen(correctedLocale);
        if (correctedLocale[LocaleLen - 2] == '_' &&
            correctedLocale[LocaleLen - 1] == 'E')
        {
            uprv_strcat(correctedLocale, "URO");
        }

        /* If using Lotus-based locale then convert to
         * equivalent non Lotus.
         */
        else if (correctedLocale[LocaleLen - 2] == '_' &&
            correctedLocale[LocaleLen - 1] == 'L')
        {
            correctedLocale[LocaleLen - 2] = 0;
        }

        /* There are separate simplified and traditional
         * locales called zh_HK_S and zh_HK_T.
         */
        else if (uprv_strncmp(correctedLocale, "zh_HK", 5) == 0)
        {
            uprv_strcpy(correctedLocale, "zh_HK");
        }

        /* A special zh_CN_GBK locale...
        */
        else if (uprv_strcmp(correctedLocale, "zh_CN_GBK") == 0)
        {
            uprv_strcpy(correctedLocale, "zh_CN");
        }

    }

    return correctedLocale;
#endif

}
Example #12
0
static void TestGetKeywordValuesForLocale(void) {
#define PREFERRED_SIZE 15
#define MAX_NUMBER_OF_KEYWORDS 4
    const char *PREFERRED[PREFERRED_SIZE][MAX_NUMBER_OF_KEYWORDS] = {
            { "root",               "USD", "USN", NULL },
            { "und",                "USD", "USN", NULL },
 /*           { "und_ZZ",             "USD", NULL, NULL },  -- temporarily remove as this locale now has 15 entries */
            { "en_US",              "USD", "USN", NULL },
            { "en_029",             "USD", "USN", NULL },
            { "en_TH",              "THB", NULL, NULL },
            { "de",                 "EUR", NULL, NULL },
            { "de_DE",              "EUR", NULL, NULL },
            { "ar",                 "EGP", NULL, NULL },
            { "ar_PS",              "ILS", "JOD", NULL },
            { "en@currency=CAD",    "USD", "USN", NULL },
            { "fr@currency=zzz",    "EUR", NULL, NULL },
            { "de_DE@currency=DEM", "EUR", NULL, NULL },
            { "en_US@rg=THZZZZ",    "THB", NULL, NULL },
            { "de@rg=USZZZZ",       "USD", "USN", NULL },
            { "en_US@currency=CAD;rg=THZZZZ", "THB", NULL, NULL },
    };
    const int32_t EXPECTED_SIZE[PREFERRED_SIZE] = {
            2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 2, 1
    };
    /* ucurr_forLocale results for same locales; "" if no result expected */
    const char *FORLOCALE[PREFERRED_SIZE] = {
            "",    "",    "USD", "",
            "THB", "",    "EUR", "",
            "ILS", "CAD", "ZZZ", "DEM",
            "THB", "USD", "CAD"
    };
    UErrorCode status = U_ZERO_ERROR;
    int32_t i, j, size;
    UEnumeration *pref, *all;
    const char *loc = NULL;
    UBool matchPref, matchAll;
    const char *value = NULL;
    int32_t valueLength = 0;
    
    UList *ALLList = NULL;
    
    UEnumeration *ALL = ucurr_getKeywordValuesForLocale("currency", uloc_getDefault(), FALSE, &status);
    if (ALL == NULL) {
        log_err_status(status, "ERROR getting keyword value for default locale. -> %s\n", u_errorName(status));
        return;
    }
    
    for (i = 0; i < PREFERRED_SIZE; i++) {
        UChar getCurrU[4];
        int32_t getCurrLen;

        status = U_ZERO_ERROR;
        pref = NULL;
        all = NULL;
        loc = PREFERRED[i][0];
        pref = ucurr_getKeywordValuesForLocale("currency", loc, TRUE, &status);
        matchPref = FALSE;
        matchAll = FALSE;
        
        size = uenum_count(pref, &status);
        
        if (size == EXPECTED_SIZE[i]) {
            matchPref = TRUE;
            for (j = 0; j < size; j++) {
                if ((value = uenum_next(pref, &valueLength, &status)) != NULL && U_SUCCESS(status)) {
                    if (uprv_strcmp(value, PREFERRED[i][j+1]) != 0) {
                        log_err("ERROR: locale %s got keywords #%d %s expected %s\n", loc, j, value, PREFERRED[i][j+1]);

                        matchPref = FALSE;
                        break;
                    }
                } else {
                    matchPref = FALSE;
                    log_err("ERROR getting keyword value for locale \"%s\"\n", loc);
                    break;
                }
            }
        } else {
            log_err("FAIL: size of locale \"%s\" %d does not match expected size %d\n", loc, size, EXPECTED_SIZE[i]);
        }
        
        if (!matchPref) {
            log_err("FAIL: Preferred values for locale \"%s\" does not match expected.\n", loc);
            break;
        }
        uenum_close(pref);
        
        all = ucurr_getKeywordValuesForLocale("currency", loc, FALSE, &status);
        
        size = uenum_count(all, &status);
        
        if (U_SUCCESS(status) && size == uenum_count(ALL, &status)) {
            matchAll = TRUE;
            ALLList = ulist_getListFromEnum(ALL);
            for (j = 0; j < size; j++) {
                if ((value = uenum_next(all, &valueLength, &status)) != NULL && U_SUCCESS(status)) {
                    if (!ulist_containsString(ALLList, value, uprv_strlen(value))) {
                        log_err("Locale %s have %s not in ALL\n", loc, value);
                        matchAll = FALSE;
                        break;
                    }
                } else {
                    matchAll = FALSE;
                    log_err("ERROR getting \"all\" keyword value for locale \"%s\"\n", loc);
                    break;
                }
            }
           if (!matchAll) {
            log_err("FAIL: All values for locale \"%s\" does not match expected.\n", loc);
           }
        } else {
            if(U_FAILURE(status)) {
               log_err("ERROR: %s\n", u_errorName(status));
            } else if(size!=uenum_count(ALL, &status)) {
               log_err("ERROR: got size of %d, wanted %d\n", size, uenum_count(ALL, &status));
            }
        }
        
        uenum_close(all);
        
        status = U_ZERO_ERROR;
        getCurrLen = ucurr_forLocale(loc, getCurrU, 4, &status);
        if(U_FAILURE(status)) {
            if (FORLOCALE[i][0] != 0) {
                log_err("ERROR: ucurr_forLocale %s, status %s\n", loc, u_errorName(status));
            }
        } else if (getCurrLen != 3) {
            if (FORLOCALE[i][0] != 0 || getCurrLen != -1) {
                log_err("ERROR: ucurr_forLocale %s, returned len %d\n", loc, getCurrLen);
            }
        } else {
            char getCurrB[4];
            u_UCharsToChars(getCurrU, getCurrB, 4);
            if ( uprv_strncmp(getCurrB, FORLOCALE[i], 4) != 0 ) {
                log_err("ERROR: ucurr_forLocale %s, expected %s, got %s\n", loc, FORLOCALE[i], getCurrB);
            }
        }
    }
    
    uenum_close(ALL);
    
}
Example #13
0
static UDataMemory *
doOpenChoice(const char *path, const char *type, const char *name,
             UDataMemoryIsAcceptable *isAcceptable, void *context,
             UErrorCode *pErrorCode)
{
    UDataMemory         *retVal = NULL;
    
    TinyString          tocEntryName; /* entry name in tree format. ex:  'icudt28b/coll/ar.res' */
    TinyString          tocEntryPath; /* entry name in path format. ex:  'icudt28b\\coll\\ar.res' */

    TinyString          pkgName;
    TinyString          treeName;
#if (U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR)  /*  '/' vs '\' */
    TinyString          altSepPath;
#endif

    const char         *dataPath;

    int32_t             tocEntrySuffixIndex;
    const char         *tocEntryPathSuffix;
    UErrorCode          subErrorCode=U_ZERO_ERROR;
    const char         *treeChar;

    UBool               isICUData = FALSE;


    /* Is this path ICU data? */
    if(path == NULL ||
       !strcmp(path, U_ICUDATA_ALIAS) ||  /* "ICUDATA" */
       !uprv_strncmp(path, U_ICUDATA_NAME U_TREE_SEPARATOR_STRING, /* "icudt26e-" */
                     uprv_strlen(U_ICUDATA_NAME U_TREE_SEPARATOR_STRING)) ||  
       !uprv_strncmp(path, U_ICUDATA_ALIAS U_TREE_SEPARATOR_STRING, /* "ICUDATA-" */
                     uprv_strlen(U_ICUDATA_ALIAS U_TREE_SEPARATOR_STRING))) {
      isICUData = TRUE;
    }

#if (U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR)  /* Windows:  try "foo\bar" and "foo/bar" */
    /* remap from alternate path char to the main one */
    TinyString_init(&altSepPath);
    if(path) {
        char *p;
        if((p=uprv_strchr(path,U_FILE_ALT_SEP_CHAR))) {
            TinyString_append(&altSepPath, path);
            while((p=uprv_strchr(altSepPath.s,U_FILE_ALT_SEP_CHAR))) {
                *p = U_FILE_SEP_CHAR;
            }
#if defined (UDATA_DEBUG)
            fprintf(stderr, "Changed path from [%s] to [%s]\n", path, altSepPath.s);
#endif
            path = altSepPath.s;
        }
    }
#endif

    TinyString_init(&tocEntryName);
    TinyString_init(&tocEntryPath);

    TinyString_init(&pkgName);
    TinyString_init(&treeName);

    /* ======= Set up strings */
    if(path==NULL) {
        TinyString_append(&pkgName, U_ICUDATA_NAME); 
    } else {
        const char *pkg;
        const char *first;
        pkg = uprv_strrchr(path, U_FILE_SEP_CHAR);
        first = uprv_strchr(path, U_FILE_SEP_CHAR);
        if(uprv_pathIsAbsolute(path) || (pkg != first)) { /* more than one slash in the path- not a tree name */
            /* see if this is an /absolute/path/to/package  path */
            if(pkg) {
                TinyString_append(&pkgName, pkg+1);
            } else {
                TinyString_append(&pkgName, path);
            }
        } else {
            treeChar = uprv_strchr(path, U_TREE_SEPARATOR);
            if(treeChar) { 
                TinyString_append(&treeName, treeChar+1); /* following '-' */
                if(isICUData) {
                    TinyString_append(&pkgName, U_ICUDATA_NAME);
                } else {
                    TinyString_appendn(&pkgName, path, (int32_t)(treeChar-path));
                    if (first == NULL) {
                        /*
                        This user data has no path, but there is a tree name.
                        Look up the correct path from the data cache later.
                        */
                        path = pkgName.s;
                    }
                }
            } else {
                if(isICUData) {
                    TinyString_append(&pkgName, U_ICUDATA_NAME);
                } else {
                    TinyString_append(&pkgName, path);
                }
            }
        }
    }

#ifdef UDATA_DEBUG
    fprintf(stderr, " P=%s T=%s\n", pkgName.s, treeName.s);
#endif

    /* setting up the entry name and file name 
     * Make up a full name by appending the type to the supplied
     *  name, assuming that a type was supplied.
     */

    /* prepend the package */
    TinyString_append(&tocEntryName, pkgName.s);
    TinyString_append(&tocEntryPath, pkgName.s);
    tocEntrySuffixIndex = tocEntryName.length;

    if(treeName.s[0]) {
        TinyString_append(&tocEntryName, U_TREE_ENTRY_SEP_STRING);
        TinyString_append(&tocEntryName, treeName.s);

        TinyString_append(&tocEntryPath, U_FILE_SEP_STRING);
        TinyString_append(&tocEntryPath, treeName.s);
    }

    TinyString_append(&tocEntryName, U_TREE_ENTRY_SEP_STRING);
    TinyString_append(&tocEntryPath, U_FILE_SEP_STRING);
    TinyString_append(&tocEntryName, name);
    TinyString_append(&tocEntryPath, name);
    if(type!=NULL && *type!=0) {
        TinyString_append(&tocEntryName, ".");
        TinyString_append(&tocEntryName, type);
        TinyString_append(&tocEntryPath, ".");
        TinyString_append(&tocEntryPath, type);
    }
    tocEntryPathSuffix = tocEntryPath.s+tocEntrySuffixIndex; /* suffix starts here */

#ifdef UDATA_DEBUG
    fprintf(stderr, " tocEntryName = %s\n", tocEntryName.s);
    fprintf(stderr, " tocEntryPath = %s\n", tocEntryName.s);
#endif    

    if(path == NULL) {
        path = COMMON_DATA_NAME; /* "icudt26e" */
    }

    /************************ Begin loop looking for ind. files ***************/
#ifdef UDATA_DEBUG
    fprintf(stderr, "IND: inBasename = %s, pkg=%s\n", "(n/a)", packageNameFromPath(path));
#endif

    /* End of dealing with a null basename */
    dataPath = u_getDataDirectory();

    /****    COMMON PACKAGE  - only if packages are first. */
    if(gDataFileAccess == UDATA_PACKAGES_FIRST) {
#ifdef UDATA_DEBUG
        fprintf(stderr, "Trying packages (UDATA_PACKAGES_FIRST)\n");
#endif
        /* #2 */
        retVal = doLoadFromCommonData(isICUData, 
                            pkgName.s, dataPath, tocEntryPathSuffix, tocEntryName.s,
                            path, type, name, isAcceptable, context, &subErrorCode, pErrorCode);
        if((retVal != NULL) || U_FAILURE(*pErrorCode)) {
            goto commonReturn;
        }
    }
    
    /****    INDIVIDUAL FILES  */
    if((gDataFileAccess==UDATA_PACKAGES_FIRST) ||
       (gDataFileAccess==UDATA_FILES_FIRST)) {
#ifdef UDATA_DEBUG
        fprintf(stderr, "Trying individual files\n");
#endif
        /* Check to make sure that there is a dataPath to iterate over */
        if ((dataPath && *dataPath) || !isICUData) {
            retVal = doLoadFromIndividualFiles(pkgName.s, dataPath, tocEntryPathSuffix,
                            path, type, name, isAcceptable, context, &subErrorCode, pErrorCode);
            if((retVal != NULL) || U_FAILURE(*pErrorCode)) {
                goto commonReturn;
            }
        }
    }

    /****    COMMON PACKAGE  */
    if((gDataFileAccess==UDATA_ONLY_PACKAGES) || 
       (gDataFileAccess==UDATA_FILES_FIRST)) {
#ifdef UDATA_DEBUG
        fprintf(stderr, "Trying packages (UDATA_ONLY_PACKAGES || UDATA_FILES_FIRST)\n");
#endif
        retVal = doLoadFromCommonData(isICUData, 
                            pkgName.s, dataPath, tocEntryPathSuffix, tocEntryName.s,
                            path, type, name, isAcceptable, context, &subErrorCode, pErrorCode);
        if((retVal != NULL) || U_FAILURE(*pErrorCode)) {
            goto commonReturn;
        }
    }
    
    /* Load from DLL.  If we haven't attempted package load, we also haven't had any chance to
        try a DLL (static or setCommonData/etc)  load.
         If we ever have a "UDATA_ONLY_FILES", add it to the or list here.  */  
    if(gDataFileAccess==UDATA_NO_FILES) {
#ifdef UDATA_DEBUG
        fprintf(stderr, "Trying common data (UDATA_NO_FILES)\n");
#endif
        retVal = doLoadFromCommonData(isICUData, 
                            pkgName.s, "", tocEntryPathSuffix, tocEntryName.s,
                            path, type, name, isAcceptable, context, &subErrorCode, pErrorCode);
        if((retVal != NULL) || U_FAILURE(*pErrorCode)) {
            goto commonReturn;
        }
    }

    /* data not found */
    if(U_SUCCESS(*pErrorCode)) {
        if(U_SUCCESS(subErrorCode)) {
            /* file not found */
            *pErrorCode=U_FILE_ACCESS_ERROR;
        } else {
            /* entry point not found or rejected */
            *pErrorCode=subErrorCode;
        }
    }

commonReturn:
    TinyString_dt(&tocEntryName);
    TinyString_dt(&tocEntryPath);
    TinyString_dt(&pkgName);
    TinyString_dt(&treeName);
#if (U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR)
    TinyString_dt(&altSepPath);
#endif
    return retVal;
}
UHashtable*
ZoneMeta::createMetaToOlsonMap(void) {
    UErrorCode status = U_ZERO_ERROR;

    UHashtable *metaToOlson = NULL;
    UResourceBundle *metazones = NULL;
    UResourceBundle *mz = NULL;

    metaToOlson = uhash_open(uhash_hashUChars, uhash_compareUChars, NULL, &status);
    if (U_FAILURE(status)) {
        return NULL;
    }
    uhash_setKeyDeleter(metaToOlson, deleteUCharString);
    uhash_setValueDeleter(metaToOlson, deleteUVector);

    metazones = ures_openDirect(NULL, gSupplementalData, &status);
    metazones = ures_getByKey(metazones, gMapTimezonesTag, metazones, &status);
    metazones = ures_getByKey(metazones, gMetazonesTag, metazones, &status);
    if (U_FAILURE(status)) {
        goto error_cleanup;
    }

    while (ures_hasNext(metazones)) {
        mz = ures_getNextResource(metazones, mz, &status);
        if (U_FAILURE(status)) {
            status = U_ZERO_ERROR;
            continue;
        }
        const char *mzkey = ures_getKey(mz);
        if (uprv_strncmp(mzkey, gMetazoneIdPrefix, MZID_PREFIX_LEN) == 0) {
            const char *mzid = mzkey + MZID_PREFIX_LEN;
            const char *territory = uprv_strrchr(mzid, '_');
            int32_t mzidLen = 0;
            int32_t territoryLen = 0;
            if (territory) {
                mzidLen = territory - mzid;
                territory++;
                territoryLen = uprv_strlen(territory);
            }
            if (mzidLen > 0 && territoryLen > 0) {
                int32_t tzidLen;
                const UChar *tzid = ures_getStringByIndex(mz, 0, &tzidLen, &status);
                if (U_SUCCESS(status)) {
                    // Create MetaToOlsonMappingEntry
                    MetaToOlsonMappingEntry *entry = (MetaToOlsonMappingEntry*)uprv_malloc(sizeof(MetaToOlsonMappingEntry));
                    if (entry == NULL) {
                        status = U_MEMORY_ALLOCATION_ERROR;
                        goto error_cleanup;
                    }
                    entry->id = tzid;
                    entry->territory = (UChar*)uprv_malloc((territoryLen + 1) * sizeof(UChar));
                    if (entry->territory == NULL) {
                        status = U_MEMORY_ALLOCATION_ERROR;
                        uprv_free(entry);
                        goto error_cleanup;
                    }
                    u_charsToUChars(territory, entry->territory, territoryLen + 1);

                    // Check if mapping entries for metazone is already available
                    if (mzidLen < ZID_KEY_MAX) {
                        UChar mzidUChars[ZID_KEY_MAX];
                        u_charsToUChars(mzid, mzidUChars, mzidLen);
                        mzidUChars[mzidLen++] = 0; // Add NUL terminator
                        UVector *tzMappings = (UVector*)uhash_get(metaToOlson, mzidUChars);
                        if (tzMappings == NULL) {
                            // Create new UVector and put it into the hashtable
                            tzMappings = new UVector(deleteMetaToOlsonMappingEntry, NULL, status);
                            if (U_FAILURE(status)) {
                                deleteMetaToOlsonMappingEntry(entry);
                                goto error_cleanup;
                            }
                            UChar *key = (UChar*)uprv_malloc(mzidLen * sizeof(UChar));
                            if (key == NULL) {
                                status = U_MEMORY_ALLOCATION_ERROR;
                                delete tzMappings;
                                deleteMetaToOlsonMappingEntry(entry);
                                goto error_cleanup;
                            }
                            u_strncpy(key, mzidUChars, mzidLen);
                            uhash_put(metaToOlson, key, tzMappings, &status);
                            if (U_FAILURE(status)) {
                                goto error_cleanup;
                            }
                        }
                        tzMappings->addElement(entry, status);
                        if (U_FAILURE(status)) {
                            goto error_cleanup;
                        }
                    } else {
                        deleteMetaToOlsonMappingEntry(entry);
                    }
                } else {
                    status = U_ZERO_ERROR;
                }
            }
        }
    }

normal_cleanup:
    ures_close(mz);
    ures_close(metazones);
    return metaToOlson;

error_cleanup:
    if (metaToOlson != NULL) {
        uhash_close(metaToOlson);
        metaToOlson = NULL;
    }
    goto normal_cleanup;
}
Example #15
0
static void U_CALLCONV
strprepProfileLineFn(void *context,
              char *fields[][2], int32_t fieldCount,
              UErrorCode *pErrorCode) {
    uint32_t mapping[40];
    char *end, *map;
    uint32_t code;
    int32_t length;
   /*UBool* mapWithNorm = (UBool*) context;*/
    const char* typeName;
    uint32_t rangeStart=0,rangeEnd =0;
    const char* filename = (const char*) context;
    const char *s;

    s = u_skipWhitespace(fields[0][0]);
    if (*s == '@') {
        /* special directive */
        s++;
        length = fields[0][1] - s;
        if (length >= NORMALIZE_DIRECTIVE_LEN
            && uprv_strncmp(s, NORMALIZE_DIRECTIVE, NORMALIZE_DIRECTIVE_LEN) == 0) {
            options[NORMALIZE].doesOccur = TRUE;
            return;
        }
        else if (length >= CHECK_BIDI_DIRECTIVE_LEN
            && uprv_strncmp(s, CHECK_BIDI_DIRECTIVE, CHECK_BIDI_DIRECTIVE_LEN) == 0) {
            options[CHECK_BIDI].doesOccur = TRUE;
            return;
        }
        else {
            fprintf(stderr, "gensprep error parsing a directive %s.", fields[0][0]);
        }
    }

    typeName = fields[2][0];
    map = fields[1][0];

    if(uprv_strstr(typeName, usprepTypeNames[USPREP_UNASSIGNED])!=NULL){

        u_parseCodePointRange(s, &rangeStart,&rangeEnd, pErrorCode);
        if(U_FAILURE(*pErrorCode)){
            fprintf(stderr, "Could not parse code point range. Error: %s\n",u_errorName(*pErrorCode));
            return;
        }

        /* store the range */
        storeRange(rangeStart,rangeEnd,USPREP_UNASSIGNED, pErrorCode);

    }else if(uprv_strstr(typeName, usprepTypeNames[USPREP_PROHIBITED])!=NULL){

        u_parseCodePointRange(s, &rangeStart,&rangeEnd, pErrorCode);
        if(U_FAILURE(*pErrorCode)){
            fprintf(stderr, "Could not parse code point range. Error: %s\n",u_errorName(*pErrorCode));
            return;
        }

        /* store the range */
        storeRange(rangeStart,rangeEnd,USPREP_PROHIBITED, pErrorCode);

    }else if(uprv_strstr(typeName, usprepTypeNames[USPREP_MAP])!=NULL){

        /* get the character code, field 0 */
        code=(uint32_t)uprv_strtoul(s, &end, 16);
        if(end<=s || end!=fields[0][1]) {
            fprintf(stderr, "gensprep: syntax error in field 0 at %s\n", fields[0][0]);
            *pErrorCode=U_PARSE_ERROR;
            exit(U_PARSE_ERROR);
        }

        /* parse the mapping string */
        length=u_parseCodePoints(map, mapping, sizeof(mapping)/4, pErrorCode);
        
        /* store the mapping */
        storeMapping(code,mapping, length,USPREP_MAP, pErrorCode);

    }else{
        *pErrorCode = U_INVALID_FORMAT_ERROR;
    }
    
    if(U_FAILURE(*pErrorCode)) {
        fprintf(stderr, "gensprep error parsing  %s line %s at %s. Error: %s\n",filename,
               fields[0][0],fields[2][0],u_errorName(*pErrorCode));
        exit(*pErrorCode);
    }

}
Example #16
0
U_CAPI int32_t U_EXPORT2
ualoc_getAppleParent(const char* localeID,
                     char * parent,
                     int32_t parentCapacity,
                     UErrorCode* err)
{
    UResourceBundle *rb;
    int32_t len;
    UErrorCode tempStatus;
    char locbuf[ULOC_FULLNAME_CAPACITY+1];
    char * foundDoubleUnderscore;

    if (U_FAILURE(*err)) {
        return 0;
    }
    if ( (parent==NULL)? parentCapacity!=0: parentCapacity<0 ) {
        *err = U_ILLEGAL_ARGUMENT_ERROR;
        return 0;
    }
    len = uloc_getBaseName(localeID, locbuf, ULOC_FULLNAME_CAPACITY, err); /* canonicalize and strip keywords */
    if (U_FAILURE(*err)) {
        return 0;
    }
    if (*err == U_STRING_NOT_TERMINATED_WARNING) {
        locbuf[ULOC_FULLNAME_CAPACITY] = 0;
        *err = U_ZERO_ERROR;
    }
    foundDoubleUnderscore = uprv_strstr(locbuf, "__"); /* __ comes from bad/missing subtag or variant */
    if (foundDoubleUnderscore != NULL) {
        *foundDoubleUnderscore = 0; /* terminate at the __ */
        len = uprv_strlen(locbuf);
    }
    if (len >= 2 && uprv_strncmp(locbuf, "zh", 2) == 0) {
        const char ** forceParentPtr = forceParent;
        const char * testCurLoc;
        while ( (testCurLoc = *forceParentPtr++) != NULL ) {
            int cmp = uprv_strcmp(locbuf, testCurLoc);
            if (cmp <= 0) {
                if (cmp == 0) {
                    len = uprv_strlen(*forceParentPtr);
                    if (len < parentCapacity) {
                        uprv_strcpy(parent, *forceParentPtr);
                    } else {
                        *err = U_BUFFER_OVERFLOW_ERROR;
                    }
                    return len;
                }
                break;
            }
            forceParentPtr++;
        }
    }
    tempStatus = U_ZERO_ERROR;
    rb = ures_openDirect(NULL, locbuf, &tempStatus);
    if (U_SUCCESS(tempStatus)) {
        const char * actualLocale = ures_getLocaleByType(rb, ULOC_ACTUAL_LOCALE, &tempStatus);
        if (U_SUCCESS(tempStatus) && uprv_strcmp(locbuf, actualLocale) != 0) {
            // we have followed an alias
            len = uprv_strlen(actualLocale);
            if (len < parentCapacity) {
                uprv_strcpy(parent, actualLocale);
            } else {
                *err = U_BUFFER_OVERFLOW_ERROR;
            }
            ures_close(rb);
            return len;
        }
        tempStatus = U_ZERO_ERROR;
        const UChar * parentUName = ures_getStringByKey(rb, "%%Parent", &len, &tempStatus);
        if (U_SUCCESS(tempStatus) && tempStatus != U_USING_FALLBACK_WARNING) {
            if (len < parentCapacity) {
                u_UCharsToChars(parentUName, parent, len + 1);
            } else {
                *err = U_BUFFER_OVERFLOW_ERROR;
            }
            ures_close(rb);
            return len;
        }
        ures_close(rb);
    }
    len = uloc_getParent(locbuf, parent, parentCapacity, err);
    if (U_SUCCESS(*err) && len == 0) {
        len = 4;
        if (len < parentCapacity) {
            uprv_strcpy(parent, "root");
        } else {
            *err = U_BUFFER_OVERFLOW_ERROR;
        }
    }
    return len;
}
Example #17
0
static void
parseConverterOptions(const char *inName,
                      char *cnvName,
                      char *locale,
                      uint32_t *pFlags,
                      UErrorCode *err)
{
    char c;
    int32_t len = 0;

    /* copy the converter name itself to cnvName */
    while((c=*inName)!=0 && c!=UCNV_OPTION_SEP_CHAR) {
        if (++len>=UCNV_MAX_CONVERTER_NAME_LENGTH) {
            *err = U_ILLEGAL_ARGUMENT_ERROR;    /* bad name */
            *cnvName=0;
            return;
        }
        *cnvName++=c;
        inName++;
    }
    *cnvName=0;

    /* parse options. No more name copying should occur. */
    while((c=*inName)!=0) {
        if(c==UCNV_OPTION_SEP_CHAR) {
            ++inName;
        }

        /* inName is behind an option separator */
        if(uprv_strncmp(inName, "locale=", 7)==0) {
            /* do not modify locale itself in case we have multiple locale options */
            char *dest=locale;

            /* copy the locale option value */
            inName+=7;
            len=0;
            while((c=*inName)!=0 && c!=UCNV_OPTION_SEP_CHAR) {
                ++inName;

                if(++len>=ULOC_FULLNAME_CAPACITY) {
                    *err=U_ILLEGAL_ARGUMENT_ERROR;    /* bad name */
                    *locale=0;
                    return;
                }

                *dest++=c;
            }
            *dest=0;
        } else if(uprv_strncmp(inName, "version=", 8)==0) {
            /* copy the version option value into bits 3..0 of *pFlags */
            inName+=8;
            c=*inName;
            if(c==0) {
                *pFlags&=~UCNV_OPTION_VERSION;
                return;
            } else if((uint8_t)(c-'0')<10) {
                *pFlags=(*pFlags&~UCNV_OPTION_VERSION)|(uint32_t)(c-'0');
                ++inName;
            }
        } else if(uprv_strncmp(inName, "swaplfnl", 8)==0) {
            inName+=8;
            *pFlags|=UCNV_OPTION_SWAP_LFNL;
        /* add processing for new options here with another } else if(uprv_strncmp(inName, "option-name=", XX)==0) { */
        } else {
            /* ignore any other options until we define some */
            while(((c = *inName++) != 0) && (c != UCNV_OPTION_SEP_CHAR)) {
            }
            if(c==0) {
                return;
            }
        }
    }
}