Home | History | Annotate | Download | only in cintltst
      1 /*
      2  *******************************************************************************
      3  *
      4  *   Copyright (C) 2003-2011, International Business Machines
      5  *   Corporation and others.  All Rights Reserved.
      6  *
      7  *******************************************************************************
      8  *   file name:  spreptst.c
      9  *   encoding:   US-ASCII
     10  *   tab size:   8 (not used)
     11  *   indentation:4
     12  *
     13  *   created on: 2003jul11
     14  *   created by: Ram Viswanadha
     15  */
     16 #define USPREP_TYPE_NAMES_ARRAY
     17 
     18 #include "unicode/utypes.h"
     19 
     20 #if !UCONFIG_NO_IDNA
     21 
     22 #include "unicode/ustring.h"
     23 #include "unicode/putil.h"
     24 #include "cintltst.h"
     25 #include "unicode/usprep.h"
     26 #include "sprpimpl.h"
     27 #include "uparse.h"
     28 #include "cmemory.h"
     29 #include "ustr_imp.h"
     30 #include "cstring.h"
     31 
     32 static void
     33 parseMappings(const char *filename, UStringPrepProfile* data, UBool reportError, UErrorCode *pErrorCode);
     34 
     35 static void
     36 compareMapping(UStringPrepProfile* data, uint32_t codepoint, uint32_t* mapping, int32_t mapLength,
     37                UStringPrepType option);
     38 
     39 static void
     40 compareFlagsForRange(UStringPrepProfile* data, uint32_t start, uint32_t end,UStringPrepType option);
     41 
     42 void
     43 doStringPrepTest(const char* binFileName, const char* txtFileName, int32_t options, UErrorCode* errorCode);
     44 
     45 static void U_CALLCONV
     46 strprepProfileLineFn(void *context,
     47               char *fields[][2], int32_t fieldCount,
     48               UErrorCode *pErrorCode) {
     49     uint32_t mapping[40];
     50     char *end, *map;
     51     uint32_t code;
     52     int32_t length;
     53     UStringPrepProfile* data = (UStringPrepProfile*) context;
     54     const char* typeName;
     55     uint32_t rangeStart=0,rangeEnd =0;
     56 
     57     typeName = fields[2][0];
     58     map = fields[1][0];
     59 
     60     if(strstr(typeName, usprepTypeNames[USPREP_UNASSIGNED])!=NULL){
     61 
     62         u_parseCodePointRange(fields[0][0], &rangeStart,&rangeEnd, pErrorCode);
     63 
     64         /* store the range */
     65         compareFlagsForRange(data, rangeStart,rangeEnd,USPREP_UNASSIGNED);
     66 
     67     }else if(strstr(typeName, usprepTypeNames[USPREP_PROHIBITED])!=NULL){
     68 
     69         u_parseCodePointRange(fields[0][0], &rangeStart,&rangeEnd, pErrorCode);
     70 
     71         /* store the range */
     72         compareFlagsForRange(data, rangeStart,rangeEnd,USPREP_PROHIBITED);
     73 
     74     }else if(strstr(typeName, usprepTypeNames[USPREP_MAP])!=NULL){
     75         /* get the character code, field 0 */
     76         code=(uint32_t)uprv_strtoul(fields[0][0], &end, 16);
     77 
     78         /* parse the mapping string */
     79         length=u_parseCodePoints(map, mapping, sizeof(mapping)/4, pErrorCode);
     80 
     81         /* compare the mapping */
     82         compareMapping(data, code,mapping, length,USPREP_MAP);
     83     }else{
     84         *pErrorCode = U_INVALID_FORMAT_ERROR;
     85     }
     86 
     87 }
     88 
     89 
     90 
     91 static void
     92 parseMappings(const char *filename, UStringPrepProfile* data, UBool reportError, UErrorCode *pErrorCode) {
     93     char *fields[3][2];
     94 
     95     if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
     96         return;
     97     }
     98 
     99     u_parseDelimitedFile(filename, ';', fields, 3, strprepProfileLineFn, (void*)data, pErrorCode);
    100 
    101     /*fprintf(stdout,"Number of code points that have mappings with length >1 : %i\n",len);*/
    102 
    103     if(U_FAILURE(*pErrorCode) && (reportError || *pErrorCode!=U_FILE_ACCESS_ERROR)) {
    104         log_err( "testidn error: u_parseDelimitedFile(\"%s\") failed - %s\n", filename, u_errorName(*pErrorCode));
    105     }
    106 }
    107 
    108 
    109 static UStringPrepType
    110 getValues(uint32_t result, int32_t* value, UBool* isIndex){
    111 
    112     UStringPrepType type;
    113     if(result == 0){
    114         /*
    115          * Initial value stored in the mapping table
    116          * just return USPREP_TYPE_LIMIT .. so that
    117          * the source codepoint is copied to the destination
    118          */
    119         type = USPREP_TYPE_LIMIT;
    120     }else if(result >= _SPREP_TYPE_THRESHOLD){
    121         type = (UStringPrepType) (result - _SPREP_TYPE_THRESHOLD);
    122     }else{
    123         /* get the type */
    124         type = USPREP_MAP;
    125         /* ascertain if the value is index or delta */
    126         if(result & 0x02){
    127             *isIndex = TRUE;
    128             *value = result  >> 2;
    129 
    130         }else{
    131             *isIndex = FALSE;
    132             *value = (int16_t)result;
    133             *value =  (*value >> 2);
    134 
    135         }
    136         if((result>>2) == _SPREP_MAX_INDEX_VALUE){
    137             type = USPREP_DELETE;
    138             isIndex =FALSE;
    139             value = 0;
    140         }
    141     }
    142     return type;
    143 }
    144 
    145 static void
    146 compareMapping(UStringPrepProfile* data, uint32_t codepoint, uint32_t* mapping,int32_t mapLength,
    147                UStringPrepType type){
    148     uint32_t result = 0;
    149     int32_t length=0;
    150     UBool isIndex = FALSE;
    151     UStringPrepType retType;
    152     int32_t value=0, index=0, delta=0;
    153     int32_t* indexes = data->indexes;
    154     UTrie trie = data->sprepTrie;
    155     const uint16_t* mappingData = data->mappingData;
    156     int32_t realLength =0;
    157     int32_t j=0;
    158     int8_t i=0;
    159 
    160     UTRIE_GET16(&trie, codepoint, result);
    161     retType = getValues(result,&value,&isIndex);
    162 
    163 
    164     if(type != retType && retType != USPREP_DELETE){
    165 
    166         log_err( "Did not get the assigned type for codepoint 0x%08X. Expected: %i Got: %i\n",codepoint, USPREP_MAP, type);
    167 
    168     }
    169 
    170     if(isIndex){
    171         index = value;
    172         if(index >= indexes[_SPREP_ONE_UCHAR_MAPPING_INDEX_START] &&
    173                  index < indexes[_SPREP_TWO_UCHARS_MAPPING_INDEX_START]){
    174             length = 1;
    175         }else if(index >= indexes[_SPREP_TWO_UCHARS_MAPPING_INDEX_START] &&
    176                  index < indexes[_SPREP_THREE_UCHARS_MAPPING_INDEX_START]){
    177             length = 2;
    178         }else if(index >= indexes[_SPREP_THREE_UCHARS_MAPPING_INDEX_START] &&
    179                  index < indexes[_SPREP_FOUR_UCHARS_MAPPING_INDEX_START]){
    180             length = 3;
    181         }else{
    182             length = mappingData[index++];
    183         }
    184     }else{
    185         delta = value;
    186         length = (retType == USPREP_DELETE)? 0 :  1;
    187     }
    188 
    189     /* figure out the real length */
    190     for(j=0; j<mapLength; j++){
    191         if(mapping[j] > 0xFFFF){
    192             realLength +=2;
    193         }else{
    194             realLength++;
    195         }
    196     }
    197 
    198     if(realLength != length){
    199         log_err( "Did not get the expected length. Expected: %i Got: %i\n", mapLength, length);
    200     }
    201 
    202     if(isIndex){
    203         for(i =0; i< mapLength; i++){
    204             if(mapping[i] <= 0xFFFF){
    205                 if(mappingData[index+i] != (uint16_t)mapping[i]){
    206                     log_err("Did not get the expected result. Expected: 0x%04X Got: 0x%04X \n", mapping[i], mappingData[index+i]);
    207                 }
    208             }else{
    209                 UChar lead  = UTF16_LEAD(mapping[i]);
    210                 UChar trail = UTF16_TRAIL(mapping[i]);
    211                 if(mappingData[index+i] != lead ||
    212                     mappingData[index+i+1] != trail){
    213                     log_err( "Did not get the expected result. Expected: 0x%04X 0x%04X  Got: 0x%04X 0x%04X\n", lead, trail, mappingData[index+i], mappingData[index+i+1]);
    214                 }
    215             }
    216         }
    217     }else{
    218         if(retType!=USPREP_DELETE && (codepoint-delta) != (uint16_t)mapping[0]){
    219            log_err("Did not get the expected result. Expected: 0x%04X Got: 0x%04X \n", mapping[0],(codepoint-delta));
    220         }
    221     }
    222 
    223 }
    224 
    225 static void
    226 compareFlagsForRange(UStringPrepProfile* data,
    227                      uint32_t start, uint32_t end,
    228                      UStringPrepType type){
    229 
    230     uint32_t result =0 ;
    231     UStringPrepType retType;
    232     UBool isIndex=FALSE;
    233     int32_t value=0;
    234     UTrie trie = data->sprepTrie;
    235 /*
    236     // supplementary code point
    237     UChar __lead16=UTF16_LEAD(0x2323E);
    238     int32_t __offset;
    239 
    240     // get data for lead surrogate
    241     (result)=_UTRIE_GET_RAW((&idnTrie), index, 0, (__lead16));
    242     __offset=(&idnTrie)->getFoldingOffset(result);
    243 
    244     // get the real data from the folded lead/trail units
    245     if(__offset>0) {
    246         (result)=_UTRIE_GET_RAW((&idnTrie), index, __offset, (0x2323E)&0x3ff);
    247     } else {
    248         (result)=(uint32_t)((&idnTrie)->initialValue);
    249     }
    250 
    251     UTRIE_GET16(&idnTrie,0x2323E, result);
    252 */
    253     while(start < end+1){
    254         UTRIE_GET16(&trie,start, result);
    255         retType = getValues(result, &value, &isIndex);
    256         if(result > _SPREP_TYPE_THRESHOLD){
    257             if(retType != type){
    258                 log_err( "FAIL: Did not get the expected type for 0x%06X. Expected: %s Got: %s\n",start,usprepTypeNames[type], usprepTypeNames[retType]);
    259             }
    260         }else{
    261             if(type == USPREP_PROHIBITED && ((result & 0x01) != 0x01)){
    262                 log_err( "FAIL: Did not get the expected type for 0x%06X. Expected: %s Got: %s\n",start,usprepTypeNames[type], usprepTypeNames[retType]);
    263             }
    264         }
    265 
    266         start++;
    267     }
    268 
    269 }
    270 
    271 void
    272 doStringPrepTest(const char* binFileName, const char* txtFileName, int32_t options, UErrorCode* errorCode){
    273 
    274     const char *testdatapath = loadTestData(errorCode);
    275     const char *srcdatapath = NULL;
    276     const char *relativepath = NULL;
    277     char *filename = NULL;
    278     UStringPrepProfile* profile = NULL;
    279 
    280 #ifdef U_TOPSRCDIR
    281     srcdatapath = U_TOPSRCDIR;
    282     relativepath = U_FILE_SEP_STRING"test"U_FILE_SEP_STRING"testdata"U_FILE_SEP_STRING;
    283 #else
    284     srcdatapath = ctest_dataOutDir();
    285     relativepath = ".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING"test"U_FILE_SEP_STRING"testdata"U_FILE_SEP_STRING;
    286 #endif
    287 
    288     profile = usprep_open(testdatapath, binFileName, errorCode);
    289 
    290     if(*errorCode == U_FILE_ACCESS_ERROR) {
    291         log_data_err("Failed to load %s data file. Error: %s \n", binFileName, u_errorName(*errorCode));
    292         return;
    293     } else if(U_FAILURE(*errorCode)){
    294         log_err("Failed to load %s data file. Error: %s \n", binFileName, u_errorName(*errorCode));
    295         return;
    296     }
    297     filename = (char*) malloc(strlen(srcdatapath)+strlen(relativepath)+strlen(txtFileName)+10 );
    298     /* open and load the txt file */
    299     strcpy(filename,srcdatapath);
    300     strcat(filename,relativepath);
    301     strcat(filename,txtFileName);
    302 
    303     parseMappings(filename,profile, TRUE,errorCode);
    304 
    305     free(filename);
    306 }
    307 #endif
    308 /*
    309  * Hey, Emacs, please set the following:
    310  *
    311  * Local Variables:
    312  * indent-tabs-mode: nil
    313  * End:
    314  *
    315  */
    316