1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
4 *******************************************************************************
6 * Copyright (C) 2003-2012, International Business Machines
7 * Corporation and others. All Rights Reserved.
9 *******************************************************************************
10 * file name: spreptst.c
12 * tab size: 8 (not used)
15 * created on: 2003jul11
16 * created by: Ram Viswanadha
18 #define USPREP_TYPE_NAMES_ARRAY
20 #include "unicode/utypes.h"
24 #include "unicode/ustring.h"
25 #include "unicode/putil.h"
27 #include "unicode/usprep.h"
28 #include "unicode/utf16.h"
36 parseMappings(const char *filename
, UStringPrepProfile
* data
, UBool reportError
, UErrorCode
*pErrorCode
);
39 compareMapping(UStringPrepProfile
* data
, uint32_t codepoint
, uint32_t* mapping
, int32_t mapLength
,
40 UStringPrepType option
);
43 compareFlagsForRange(UStringPrepProfile
* data
, uint32_t start
, uint32_t end
,UStringPrepType option
);
46 doStringPrepTest(const char* binFileName
, const char* txtFileName
, int32_t options
, UErrorCode
* errorCode
);
48 static void U_CALLCONV
49 strprepProfileLineFn(void *context
,
50 char *fields
[][2], int32_t fieldCount
,
51 UErrorCode
*pErrorCode
) {
56 UStringPrepProfile
* data
= (UStringPrepProfile
*) context
;
58 uint32_t rangeStart
=0,rangeEnd
=0;
60 typeName
= fields
[2][0];
63 if(strstr(typeName
, usprepTypeNames
[USPREP_UNASSIGNED
])!=NULL
){
65 u_parseCodePointRange(fields
[0][0], &rangeStart
,&rangeEnd
, pErrorCode
);
68 compareFlagsForRange(data
, rangeStart
,rangeEnd
,USPREP_UNASSIGNED
);
70 }else if(strstr(typeName
, usprepTypeNames
[USPREP_PROHIBITED
])!=NULL
){
72 u_parseCodePointRange(fields
[0][0], &rangeStart
,&rangeEnd
, pErrorCode
);
75 compareFlagsForRange(data
, rangeStart
,rangeEnd
,USPREP_PROHIBITED
);
77 }else if(strstr(typeName
, usprepTypeNames
[USPREP_MAP
])!=NULL
){
78 /* get the character code, field 0 */
79 code
=(uint32_t)uprv_strtoul(fields
[0][0], &end
, 16);
81 /* parse the mapping string */
82 length
=u_parseCodePoints(map
, mapping
, sizeof(mapping
)/4, pErrorCode
);
84 /* compare the mapping */
85 compareMapping(data
, code
,mapping
, length
,USPREP_MAP
);
87 *pErrorCode
= U_INVALID_FORMAT_ERROR
;
95 parseMappings(const char *filename
, UStringPrepProfile
* data
, UBool reportError
, UErrorCode
*pErrorCode
) {
98 if(pErrorCode
==NULL
|| U_FAILURE(*pErrorCode
)) {
102 u_parseDelimitedFile(filename
, ';', fields
, 3, strprepProfileLineFn
, (void*)data
, pErrorCode
);
104 /*fprintf(stdout,"Number of code points that have mappings with length >1 : %i\n",len);*/
106 if(U_FAILURE(*pErrorCode
) && (reportError
|| *pErrorCode
!=U_FILE_ACCESS_ERROR
)) {
107 log_err( "testidn error: u_parseDelimitedFile(\"%s\") failed - %s\n", filename
, u_errorName(*pErrorCode
));
112 static UStringPrepType
113 getValues(uint32_t result
, int32_t* value
, UBool
* isIndex
){
115 UStringPrepType type
;
118 * Initial value stored in the mapping table
119 * just return USPREP_TYPE_LIMIT .. so that
120 * the source codepoint is copied to the destination
122 type
= USPREP_TYPE_LIMIT
;
123 }else if(result
>= _SPREP_TYPE_THRESHOLD
){
124 type
= (UStringPrepType
) (result
- _SPREP_TYPE_THRESHOLD
);
128 /* ascertain if the value is index or delta */
131 *value
= result
>> 2;
135 *value
= (int16_t)result
;
136 *value
= (*value
>> 2);
139 if((result
>>2) == _SPREP_MAX_INDEX_VALUE
){
140 type
= USPREP_DELETE
;
149 compareMapping(UStringPrepProfile
* data
, uint32_t codepoint
, uint32_t* mapping
,int32_t mapLength
,
150 UStringPrepType type
){
153 UBool isIndex
= FALSE
;
154 UStringPrepType retType
;
155 int32_t value
=0, idx
=0, delta
=0;
156 int32_t* indexes
= data
->indexes
;
157 UTrie trie
= data
->sprepTrie
;
158 const uint16_t* mappingData
= data
->mappingData
;
159 int32_t realLength
=0;
163 UTRIE_GET16(&trie
, codepoint
, result
);
164 retType
= getValues(result
,&value
,&isIndex
);
167 if(type
!= retType
&& retType
!= USPREP_DELETE
){
169 log_err( "Did not get the assigned type for codepoint 0x%08X. Expected: %i Got: %i\n",codepoint
, USPREP_MAP
, type
);
175 if(idx
>= indexes
[_SPREP_ONE_UCHAR_MAPPING_INDEX_START
] &&
176 idx
< indexes
[_SPREP_TWO_UCHARS_MAPPING_INDEX_START
]){
178 }else if(idx
>= indexes
[_SPREP_TWO_UCHARS_MAPPING_INDEX_START
] &&
179 idx
< indexes
[_SPREP_THREE_UCHARS_MAPPING_INDEX_START
]){
181 }else if(idx
>= indexes
[_SPREP_THREE_UCHARS_MAPPING_INDEX_START
] &&
182 idx
< indexes
[_SPREP_FOUR_UCHARS_MAPPING_INDEX_START
]){
185 length
= mappingData
[idx
++];
189 length
= (retType
== USPREP_DELETE
)? 0 : 1;
192 /* figure out the real length */
193 for(j
=0; j
<mapLength
; j
++){
194 if(mapping
[j
] > 0xFFFF){
201 if(realLength
!= length
){
202 log_err( "Did not get the expected length. Expected: %i Got: %i\n", mapLength
, length
);
206 for(i
=0; i
< mapLength
; i
++){
207 if(mapping
[i
] <= 0xFFFF){
208 if(mappingData
[idx
+i
] != (uint16_t)mapping
[i
]){
209 log_err("Did not get the expected result. Expected: 0x%04X Got: 0x%04X \n", mapping
[i
], mappingData
[idx
+i
]);
212 UChar lead
= U16_LEAD(mapping
[i
]);
213 UChar trail
= U16_TRAIL(mapping
[i
]);
214 if(mappingData
[idx
+i
] != lead
||
215 mappingData
[idx
+i
+1] != trail
){
216 log_err( "Did not get the expected result. Expected: 0x%04X 0x%04X Got: 0x%04X 0x%04X\n", lead
, trail
, mappingData
[idx
+i
], mappingData
[idx
+i
+1]);
221 if(retType
!=USPREP_DELETE
&& (codepoint
-delta
) != (uint16_t)mapping
[0]){
222 log_err("Did not get the expected result. Expected: 0x%04X Got: 0x%04X \n", mapping
[0],(codepoint
-delta
));
229 compareFlagsForRange(UStringPrepProfile
* data
,
230 uint32_t start
, uint32_t end
,
231 UStringPrepType type
){
234 UStringPrepType retType
;
237 UTrie trie
= data
->sprepTrie
;
239 // supplementary code point
240 UChar __lead16=U16_LEAD(0x2323E);
243 // get data for lead surrogate
244 (result)=_UTRIE_GET_RAW((&idnTrie), index, 0, (__lead16));
245 __offset=(&idnTrie)->getFoldingOffset(result);
247 // get the real data from the folded lead/trail units
249 (result)=_UTRIE_GET_RAW((&idnTrie), index, __offset, (0x2323E)&0x3ff);
251 (result)=(uint32_t)((&idnTrie)->initialValue);
254 UTRIE_GET16(&idnTrie,0x2323E, result);
256 while(start
< end
+1){
257 UTRIE_GET16(&trie
,start
, result
);
258 retType
= getValues(result
, &value
, &isIndex
);
259 if(result
> _SPREP_TYPE_THRESHOLD
){
261 log_err( "FAIL: Did not get the expected type for 0x%06X. Expected: %s Got: %s\n",start
,usprepTypeNames
[type
], usprepTypeNames
[retType
]);
264 if(type
== USPREP_PROHIBITED
&& ((result
& 0x01) != 0x01)){
265 log_err( "FAIL: Did not get the expected type for 0x%06X. Expected: %s Got: %s\n",start
,usprepTypeNames
[type
], usprepTypeNames
[retType
]);
275 doStringPrepTest(const char* binFileName
, const char* txtFileName
, int32_t options
, UErrorCode
* errorCode
){
277 const char *testdatapath
= loadTestData(errorCode
);
278 const char *srcdatapath
= NULL
;
279 const char *relativepath
= NULL
;
280 char *filename
= NULL
;
281 UStringPrepProfile
* profile
= NULL
;
284 srcdatapath
= U_TOPSRCDIR
;
285 relativepath
= U_FILE_SEP_STRING
"test"U_FILE_SEP_STRING
"testdata"U_FILE_SEP_STRING
;
287 srcdatapath
= ctest_dataOutDir();
288 relativepath
= ".."U_FILE_SEP_STRING
".."U_FILE_SEP_STRING
"test"U_FILE_SEP_STRING
"testdata"U_FILE_SEP_STRING
;
291 profile
= usprep_open(testdatapath
, binFileName
, errorCode
);
293 if(*errorCode
== U_FILE_ACCESS_ERROR
) {
294 log_data_err("Failed to load %s data file. Error: %s \n", binFileName
, u_errorName(*errorCode
));
296 } else if(U_FAILURE(*errorCode
)){
297 log_err("Failed to load %s data file. Error: %s \n", binFileName
, u_errorName(*errorCode
));
300 filename
= (char*) malloc(strlen(srcdatapath
)+strlen(relativepath
)+strlen(txtFileName
)+10 );
301 /* open and load the txt file */
302 strcpy(filename
,srcdatapath
);
303 strcat(filename
,relativepath
);
304 strcat(filename
,txtFileName
);
306 parseMappings(filename
,profile
, TRUE
,errorCode
);
312 * Hey, Emacs, please set the following:
315 * indent-tabs-mode: nil