1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/intl/icu/source/i18n/ucol_wgt.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,577 @@ 1.4 +/* 1.5 +******************************************************************************* 1.6 +* 1.7 +* Copyright (C) 1999-2011, International Business Machines 1.8 +* Corporation and others. All Rights Reserved. 1.9 +* 1.10 +******************************************************************************* 1.11 +* file name: ucol_wgt.cpp 1.12 +* encoding: US-ASCII 1.13 +* tab size: 8 (not used) 1.14 +* indentation:4 1.15 +* 1.16 +* created on: 2001mar08 1.17 +* created by: Markus W. Scherer 1.18 +* 1.19 +* This file contains code for allocating n collation element weights 1.20 +* between two exclusive limits. 1.21 +* It is used only internally by ucol_bld. 1.22 +*/ 1.23 + 1.24 +#include "unicode/utypes.h" 1.25 + 1.26 +#if !UCONFIG_NO_COLLATION 1.27 + 1.28 +#include "ucol_imp.h" 1.29 +#include "ucol_wgt.h" 1.30 +#include "cmemory.h" 1.31 +#include "uarrsort.h" 1.32 + 1.33 +#ifdef UCOL_DEBUG 1.34 +# include <stdio.h> 1.35 +#endif 1.36 + 1.37 +/* collation element weight allocation -------------------------------------- */ 1.38 + 1.39 +/* helper functions for CE weights */ 1.40 + 1.41 +static inline int32_t 1.42 +lengthOfWeight(uint32_t weight) { 1.43 + if((weight&0xffffff)==0) { 1.44 + return 1; 1.45 + } else if((weight&0xffff)==0) { 1.46 + return 2; 1.47 + } else if((weight&0xff)==0) { 1.48 + return 3; 1.49 + } else { 1.50 + return 4; 1.51 + } 1.52 +} 1.53 + 1.54 +static inline uint32_t 1.55 +getWeightTrail(uint32_t weight, int32_t length) { 1.56 + return (uint32_t)(weight>>(8*(4-length)))&0xff; 1.57 +} 1.58 + 1.59 +static inline uint32_t 1.60 +setWeightTrail(uint32_t weight, int32_t length, uint32_t trail) { 1.61 + length=8*(4-length); 1.62 + return (uint32_t)((weight&(0xffffff00<<length))|(trail<<length)); 1.63 +} 1.64 + 1.65 +static inline uint32_t 1.66 +getWeightByte(uint32_t weight, int32_t idx) { 1.67 + return getWeightTrail(weight, idx); /* same calculation */ 1.68 +} 1.69 + 1.70 +static inline uint32_t 1.71 +setWeightByte(uint32_t weight, int32_t idx, uint32_t byte) { 1.72 + uint32_t mask; /* 0xffffffff except a 00 "hole" for the index-th byte */ 1.73 + 1.74 + idx*=8; 1.75 + if(idx<32) { 1.76 + mask=((uint32_t)0xffffffff)>>idx; 1.77 + } else { 1.78 + // Do not use uint32_t>>32 because on some platforms that does not shift at all 1.79 + // while we need it to become 0. 1.80 + // PowerPC: 0xffffffff>>32 = 0 (wanted) 1.81 + // x86: 0xffffffff>>32 = 0xffffffff (not wanted) 1.82 + // 1.83 + // ANSI C99 6.5.7 Bitwise shift operators: 1.84 + // "If the value of the right operand is negative 1.85 + // or is greater than or equal to the width of the promoted left operand, 1.86 + // the behavior is undefined." 1.87 + mask=0; 1.88 + } 1.89 + idx=32-idx; 1.90 + mask|=0xffffff00<<idx; 1.91 + return (uint32_t)((weight&mask)|(byte<<idx)); 1.92 +} 1.93 + 1.94 +static inline uint32_t 1.95 +truncateWeight(uint32_t weight, int32_t length) { 1.96 + return (uint32_t)(weight&(0xffffffff<<(8*(4-length)))); 1.97 +} 1.98 + 1.99 +static inline uint32_t 1.100 +incWeightTrail(uint32_t weight, int32_t length) { 1.101 + return (uint32_t)(weight+(1UL<<(8*(4-length)))); 1.102 +} 1.103 + 1.104 +static inline uint32_t 1.105 +decWeightTrail(uint32_t weight, int32_t length) { 1.106 + return (uint32_t)(weight-(1UL<<(8*(4-length)))); 1.107 +} 1.108 + 1.109 +static inline uint32_t 1.110 +incWeight(uint32_t weight, int32_t length, uint32_t maxByte) { 1.111 + uint32_t byte; 1.112 + 1.113 + for(;;) { 1.114 + byte=getWeightByte(weight, length); 1.115 + if(byte<maxByte) { 1.116 + return setWeightByte(weight, length, byte+1); 1.117 + } else { 1.118 + /* roll over, set this byte to UCOL_BYTE_FIRST_TAILORED and increment the previous one */ 1.119 + weight=setWeightByte(weight, length, UCOL_BYTE_FIRST_TAILORED); 1.120 + --length; 1.121 + } 1.122 + } 1.123 +} 1.124 + 1.125 +static inline int32_t 1.126 +lengthenRange(WeightRange *range, uint32_t maxByte, uint32_t countBytes) { 1.127 + int32_t length; 1.128 + 1.129 + length=range->length2+1; 1.130 + range->start=setWeightTrail(range->start, length, UCOL_BYTE_FIRST_TAILORED); 1.131 + range->end=setWeightTrail(range->end, length, maxByte); 1.132 + range->count2*=countBytes; 1.133 + range->length2=length; 1.134 + return length; 1.135 +} 1.136 + 1.137 +/* for uprv_sortArray: sort ranges in weight order */ 1.138 +static int32_t U_CALLCONV 1.139 +compareRanges(const void * /*context*/, const void *left, const void *right) { 1.140 + uint32_t l, r; 1.141 + 1.142 + l=((const WeightRange *)left)->start; 1.143 + r=((const WeightRange *)right)->start; 1.144 + if(l<r) { 1.145 + return -1; 1.146 + } else if(l>r) { 1.147 + return 1; 1.148 + } else { 1.149 + return 0; 1.150 + } 1.151 +} 1.152 + 1.153 +/* 1.154 + * take two CE weights and calculate the 1.155 + * possible ranges of weights between the two limits, excluding them 1.156 + * for weights with up to 4 bytes there are up to 2*4-1=7 ranges 1.157 + */ 1.158 +static inline int32_t 1.159 +getWeightRanges(uint32_t lowerLimit, uint32_t upperLimit, 1.160 + uint32_t maxByte, uint32_t countBytes, 1.161 + WeightRange ranges[7]) { 1.162 + WeightRange lower[5], middle, upper[5]; /* [0] and [1] are not used - this simplifies indexing */ 1.163 + uint32_t weight, trail; 1.164 + int32_t length, lowerLength, upperLength, rangeCount; 1.165 + 1.166 + /* assume that both lowerLimit & upperLimit are not 0 */ 1.167 + 1.168 + /* get the lengths of the limits */ 1.169 + lowerLength=lengthOfWeight(lowerLimit); 1.170 + upperLength=lengthOfWeight(upperLimit); 1.171 + 1.172 +#ifdef UCOL_DEBUG 1.173 + printf("length of lower limit 0x%08lx is %ld\n", lowerLimit, lowerLength); 1.174 + printf("length of upper limit 0x%08lx is %ld\n", upperLimit, upperLength); 1.175 +#endif 1.176 + 1.177 + if(lowerLimit>=upperLimit) { 1.178 +#ifdef UCOL_DEBUG 1.179 + printf("error: no space between lower & upper limits\n"); 1.180 +#endif 1.181 + return 0; 1.182 + } 1.183 + 1.184 + /* check that neither is a prefix of the other */ 1.185 + if(lowerLength<upperLength) { 1.186 + if(lowerLimit==truncateWeight(upperLimit, lowerLength)) { 1.187 +#ifdef UCOL_DEBUG 1.188 + printf("error: lower limit 0x%08lx is a prefix of upper limit 0x%08lx\n", lowerLimit, upperLimit); 1.189 +#endif 1.190 + return 0; 1.191 + } 1.192 + } 1.193 + /* if the upper limit is a prefix of the lower limit then the earlier test lowerLimit>=upperLimit has caught it */ 1.194 + 1.195 + /* reset local variables */ 1.196 + uprv_memset(lower, 0, sizeof(lower)); 1.197 + uprv_memset(&middle, 0, sizeof(middle)); 1.198 + uprv_memset(upper, 0, sizeof(upper)); 1.199 + 1.200 + /* 1.201 + * With the limit lengths of 1..4, there are up to 7 ranges for allocation: 1.202 + * range minimum length 1.203 + * lower[4] 4 1.204 + * lower[3] 3 1.205 + * lower[2] 2 1.206 + * middle 1 1.207 + * upper[2] 2 1.208 + * upper[3] 3 1.209 + * upper[4] 4 1.210 + * 1.211 + * We are now going to calculate up to 7 ranges. 1.212 + * Some of them will typically overlap, so we will then have to merge and eliminate ranges. 1.213 + */ 1.214 + weight=lowerLimit; 1.215 + for(length=lowerLength; length>=2; --length) { 1.216 + trail=getWeightTrail(weight, length); 1.217 + if(trail<maxByte) { 1.218 + lower[length].start=incWeightTrail(weight, length); 1.219 + lower[length].end=setWeightTrail(weight, length, maxByte); 1.220 + lower[length].length=length; 1.221 + lower[length].count=maxByte-trail; 1.222 + } 1.223 + weight=truncateWeight(weight, length-1); 1.224 + } 1.225 + middle.start=incWeightTrail(weight, 1); 1.226 + 1.227 + weight=upperLimit; 1.228 + for(length=upperLength; length>=2; --length) { 1.229 + trail=getWeightTrail(weight, length); 1.230 + if(trail>UCOL_BYTE_FIRST_TAILORED) { 1.231 + upper[length].start=setWeightTrail(weight, length, UCOL_BYTE_FIRST_TAILORED); 1.232 + upper[length].end=decWeightTrail(weight, length); 1.233 + upper[length].length=length; 1.234 + upper[length].count=trail-UCOL_BYTE_FIRST_TAILORED; 1.235 + } 1.236 + weight=truncateWeight(weight, length-1); 1.237 + } 1.238 + middle.end=decWeightTrail(weight, 1); 1.239 + 1.240 + /* set the middle range */ 1.241 + middle.length=1; 1.242 + if(middle.end>=middle.start) { 1.243 + middle.count=(int32_t)((middle.end-middle.start)>>24)+1; 1.244 + } else { 1.245 + /* eliminate overlaps */ 1.246 + uint32_t start, end; 1.247 + 1.248 + /* remove the middle range */ 1.249 + middle.count=0; 1.250 + 1.251 + /* reduce or remove the lower ranges that go beyond upperLimit */ 1.252 + for(length=4; length>=2; --length) { 1.253 + if(lower[length].count>0 && upper[length].count>0) { 1.254 + start=upper[length].start; 1.255 + end=lower[length].end; 1.256 + 1.257 + if(end>=start || incWeight(end, length, maxByte)==start) { 1.258 + /* lower and upper ranges collide or are directly adjacent: merge these two and remove all shorter ranges */ 1.259 + start=lower[length].start; 1.260 + end=lower[length].end=upper[length].end; 1.261 + /* 1.262 + * merging directly adjacent ranges needs to subtract the 0/1 gaps in between; 1.263 + * it may result in a range with count>countBytes 1.264 + */ 1.265 + lower[length].count= 1.266 + (int32_t)(getWeightTrail(end, length)-getWeightTrail(start, length)+1+ 1.267 + countBytes*(getWeightByte(end, length-1)-getWeightByte(start, length-1))); 1.268 + upper[length].count=0; 1.269 + while(--length>=2) { 1.270 + lower[length].count=upper[length].count=0; 1.271 + } 1.272 + break; 1.273 + } 1.274 + } 1.275 + } 1.276 + } 1.277 + 1.278 +#ifdef UCOL_DEBUG 1.279 + /* print ranges */ 1.280 + for(length=4; length>=2; --length) { 1.281 + if(lower[length].count>0) { 1.282 + printf("lower[%ld] .start=0x%08lx .end=0x%08lx .count=%ld\n", length, lower[length].start, lower[length].end, lower[length].count); 1.283 + } 1.284 + } 1.285 + if(middle.count>0) { 1.286 + printf("middle .start=0x%08lx .end=0x%08lx .count=%ld\n", middle.start, middle.end, middle.count); 1.287 + } 1.288 + for(length=2; length<=4; ++length) { 1.289 + if(upper[length].count>0) { 1.290 + printf("upper[%ld] .start=0x%08lx .end=0x%08lx .count=%ld\n", length, upper[length].start, upper[length].end, upper[length].count); 1.291 + } 1.292 + } 1.293 +#endif 1.294 + 1.295 + /* copy the ranges, shortest first, into the result array */ 1.296 + rangeCount=0; 1.297 + if(middle.count>0) { 1.298 + uprv_memcpy(ranges, &middle, sizeof(WeightRange)); 1.299 + rangeCount=1; 1.300 + } 1.301 + for(length=2; length<=4; ++length) { 1.302 + /* copy upper first so that later the middle range is more likely the first one to use */ 1.303 + if(upper[length].count>0) { 1.304 + uprv_memcpy(ranges+rangeCount, upper+length, sizeof(WeightRange)); 1.305 + ++rangeCount; 1.306 + } 1.307 + if(lower[length].count>0) { 1.308 + uprv_memcpy(ranges+rangeCount, lower+length, sizeof(WeightRange)); 1.309 + ++rangeCount; 1.310 + } 1.311 + } 1.312 + return rangeCount; 1.313 +} 1.314 + 1.315 +/* 1.316 + * call getWeightRanges and then determine heuristically 1.317 + * which ranges to use for a given number of weights between (excluding) 1.318 + * two limits 1.319 + */ 1.320 +U_CFUNC int32_t 1.321 +ucol_allocWeights(uint32_t lowerLimit, uint32_t upperLimit, 1.322 + uint32_t n, 1.323 + uint32_t maxByte, 1.324 + WeightRange ranges[7]) { 1.325 + /* number of usable byte values 3..maxByte */ 1.326 + uint32_t countBytes=maxByte-UCOL_BYTE_FIRST_TAILORED+1; 1.327 + 1.328 + uint32_t lengthCounts[6]; /* [0] unused, [5] to make index checks unnecessary */ 1.329 + uint32_t maxCount; 1.330 + int32_t i, rangeCount, minLength/*, maxLength*/; 1.331 + 1.332 + /* countBytes to the power of index */ 1.333 + uint32_t powers[5]; 1.334 + /* gcc requires explicit initialization */ 1.335 + powers[0] = 1; 1.336 + powers[1] = countBytes; 1.337 + powers[2] = countBytes*countBytes; 1.338 + powers[3] = countBytes*countBytes*countBytes; 1.339 + powers[4] = countBytes*countBytes*countBytes*countBytes; 1.340 + 1.341 +#ifdef UCOL_DEBUG 1.342 + puts(""); 1.343 +#endif 1.344 + 1.345 + rangeCount=getWeightRanges(lowerLimit, upperLimit, maxByte, countBytes, ranges); 1.346 + if(rangeCount<=0) { 1.347 +#ifdef UCOL_DEBUG 1.348 + printf("error: unable to get Weight ranges\n"); 1.349 +#endif 1.350 + return 0; 1.351 + } 1.352 + 1.353 + /* what is the maximum number of weights with these ranges? */ 1.354 + maxCount=0; 1.355 + for(i=0; i<rangeCount; ++i) { 1.356 + maxCount+=(uint32_t)ranges[i].count*powers[4-ranges[i].length]; 1.357 + } 1.358 + if(maxCount>=n) { 1.359 +#ifdef UCOL_DEBUG 1.360 + printf("the maximum number of %lu weights is sufficient for n=%lu\n", maxCount, n); 1.361 +#endif 1.362 + } else { 1.363 +#ifdef UCOL_DEBUG 1.364 + printf("error: the maximum number of %lu weights is insufficient for n=%lu\n", maxCount, n); 1.365 +#endif 1.366 + return 0; 1.367 + } 1.368 + 1.369 + /* set the length2 and count2 fields */ 1.370 + for(i=0; i<rangeCount; ++i) { 1.371 + ranges[i].length2=ranges[i].length; 1.372 + ranges[i].count2=(uint32_t)ranges[i].count; 1.373 + } 1.374 + 1.375 + /* try until we find suitably large ranges */ 1.376 + for(;;) { 1.377 + /* get the smallest number of bytes in a range */ 1.378 + minLength=ranges[0].length2; 1.379 + 1.380 + /* sum up the number of elements that fit into ranges of each byte length */ 1.381 + uprv_memset(lengthCounts, 0, sizeof(lengthCounts)); 1.382 + for(i=0; i<rangeCount; ++i) { 1.383 + lengthCounts[ranges[i].length2]+=ranges[i].count2; 1.384 + } 1.385 + 1.386 + /* now try to allocate n elements in the available short ranges */ 1.387 + if(n<=(lengthCounts[minLength]+lengthCounts[minLength+1])) { 1.388 + /* trivial cases, use the first few ranges */ 1.389 + maxCount=0; 1.390 + rangeCount=0; 1.391 + do { 1.392 + maxCount+=ranges[rangeCount].count2; 1.393 + ++rangeCount; 1.394 + } while(n>maxCount); 1.395 +#ifdef UCOL_DEBUG 1.396 + printf("take first %ld ranges\n", rangeCount); 1.397 +#endif 1.398 + break; 1.399 + } else if(n<=ranges[0].count2*countBytes) { 1.400 + /* easy case, just make this one range large enough by lengthening it once more, possibly split it */ 1.401 + uint32_t count1, count2, power_1, power; 1.402 + 1.403 + /*maxLength=minLength+1;*/ 1.404 + 1.405 + /* calculate how to split the range between maxLength-1 (count1) and maxLength (count2) */ 1.406 + power_1=powers[minLength-ranges[0].length]; 1.407 + power=power_1*countBytes; 1.408 + count2=(n+power-1)/power; 1.409 + count1=ranges[0].count-count2; 1.410 + 1.411 + /* split the range */ 1.412 +#ifdef UCOL_DEBUG 1.413 + printf("split the first range %ld:%ld\n", count1, count2); 1.414 +#endif 1.415 + if(count1<1) { 1.416 + rangeCount=1; 1.417 + 1.418 + /* lengthen the entire range to maxLength */ 1.419 + lengthenRange(ranges, maxByte, countBytes); 1.420 + } else { 1.421 + /* really split the range */ 1.422 + uint32_t byte; 1.423 + 1.424 + /* create a new range with the end and initial and current length of the old one */ 1.425 + rangeCount=2; 1.426 + ranges[1].end=ranges[0].end; 1.427 + ranges[1].length=ranges[0].length; 1.428 + ranges[1].length2=minLength; 1.429 + 1.430 + /* set the end of the first range according to count1 */ 1.431 + i=ranges[0].length; 1.432 + byte=getWeightByte(ranges[0].start, i)+count1-1; 1.433 + 1.434 + /* 1.435 + * ranges[0].count and count1 may be >countBytes 1.436 + * from merging adjacent ranges; 1.437 + * byte>maxByte is possible 1.438 + */ 1.439 + if(byte<=maxByte) { 1.440 + ranges[0].end=setWeightByte(ranges[0].start, i, byte); 1.441 + } else /* byte>maxByte */ { 1.442 + ranges[0].end=setWeightByte(incWeight(ranges[0].start, i-1, maxByte), i, byte-countBytes); 1.443 + } 1.444 + 1.445 + /* set the bytes in the end weight at length+1..length2 to maxByte */ 1.446 + byte=(maxByte<<24)|(maxByte<<16)|(maxByte<<8)|maxByte; /* this used to be 0xffffffff */ 1.447 + ranges[0].end=truncateWeight(ranges[0].end, i)| 1.448 + ((byte>>(8*i))&(byte<<(8*(4-minLength)))); 1.449 + 1.450 + /* set the start of the second range to immediately follow the end of the first one */ 1.451 + ranges[1].start=incWeight(ranges[0].end, minLength, maxByte); 1.452 + 1.453 + /* set the count values (informational) */ 1.454 + ranges[0].count=count1; 1.455 + ranges[1].count=count2; 1.456 + 1.457 + ranges[0].count2=count1*power_1; 1.458 + ranges[1].count2=count2*power_1; /* will be *countBytes when lengthened */ 1.459 + 1.460 + /* lengthen the second range to maxLength */ 1.461 + lengthenRange(ranges+1, maxByte, countBytes); 1.462 + } 1.463 + break; 1.464 + } 1.465 + 1.466 + /* no good match, lengthen all minLength ranges and iterate */ 1.467 +#ifdef UCOL_DEBUG 1.468 + printf("lengthen the short ranges from %ld bytes to %ld and iterate\n", minLength, minLength+1); 1.469 +#endif 1.470 + for(i=0; ranges[i].length2==minLength; ++i) { 1.471 + lengthenRange(ranges+i, maxByte, countBytes); 1.472 + } 1.473 + } 1.474 + 1.475 + if(rangeCount>1) { 1.476 + /* sort the ranges by weight values */ 1.477 + UErrorCode errorCode=U_ZERO_ERROR; 1.478 + uprv_sortArray(ranges, rangeCount, sizeof(WeightRange), compareRanges, NULL, FALSE, &errorCode); 1.479 + /* ignore error code: we know that the internal sort function will not fail here */ 1.480 + } 1.481 + 1.482 +#ifdef UCOL_DEBUG 1.483 + puts("final ranges:"); 1.484 + for(i=0; i<rangeCount; ++i) { 1.485 + printf("ranges[%ld] .start=0x%08lx .end=0x%08lx .length=%ld .length2=%ld .count=%ld .count2=%lu\n", 1.486 + i, ranges[i].start, ranges[i].end, ranges[i].length, ranges[i].length2, ranges[i].count, ranges[i].count2); 1.487 + } 1.488 +#endif 1.489 + 1.490 + /* set maxByte in ranges[0] for ucol_nextWeight() */ 1.491 + ranges[0].count=maxByte; 1.492 + 1.493 + return rangeCount; 1.494 +} 1.495 + 1.496 +/* 1.497 + * given a set of ranges calculated by ucol_allocWeights(), 1.498 + * iterate through the weights 1.499 + */ 1.500 +U_CFUNC uint32_t 1.501 +ucol_nextWeight(WeightRange ranges[], int32_t *pRangeCount) { 1.502 + if(*pRangeCount<=0) { 1.503 + return 0xffffffff; 1.504 + } else { 1.505 + uint32_t weight, maxByte; 1.506 + 1.507 + /* get maxByte from the .count field */ 1.508 + maxByte=ranges[0].count; 1.509 + 1.510 + /* get the next weight */ 1.511 + weight=ranges[0].start; 1.512 + if(weight==ranges[0].end) { 1.513 + /* this range is finished, remove it and move the following ones up */ 1.514 + if(--*pRangeCount>0) { 1.515 + uprv_memmove(ranges, ranges+1, *pRangeCount*sizeof(WeightRange)); 1.516 + ranges[0].count=maxByte; /* keep maxByte in ranges[0] */ 1.517 + } 1.518 + } else { 1.519 + /* increment the weight for the next value */ 1.520 + ranges[0].start=incWeight(weight, ranges[0].length2, maxByte); 1.521 + } 1.522 + 1.523 + return weight; 1.524 + } 1.525 +} 1.526 + 1.527 +#if 0 // #ifdef UCOL_DEBUG 1.528 + 1.529 +static void 1.530 +testAlloc(uint32_t lowerLimit, uint32_t upperLimit, uint32_t n, UBool enumerate) { 1.531 + WeightRange ranges[8]; 1.532 + int32_t rangeCount; 1.533 + 1.534 + rangeCount=ucol_allocWeights(lowerLimit, upperLimit, n, ranges); 1.535 + if(enumerate) { 1.536 + uint32_t weight; 1.537 + 1.538 + while(n>0) { 1.539 + weight=ucol_nextWeight(ranges, &rangeCount); 1.540 + if(weight==0xffffffff) { 1.541 + printf("error: 0xffffffff with %lu more weights to go\n", n); 1.542 + break; 1.543 + } 1.544 + printf(" 0x%08lx\n", weight); 1.545 + --n; 1.546 + } 1.547 + } 1.548 +} 1.549 + 1.550 +extern int 1.551 +main(int argc, const char *argv[]) { 1.552 +#if 0 1.553 +#endif 1.554 + testAlloc(0x364214fc, 0x44b87d23, 5, FALSE); 1.555 + testAlloc(0x36421500, 0x44b87d23, 5, FALSE); 1.556 + testAlloc(0x36421500, 0x44b87d23, 20, FALSE); 1.557 + testAlloc(0x36421500, 0x44b87d23, 13700, FALSE); 1.558 + testAlloc(0x36421500, 0x38b87d23, 1, FALSE); 1.559 + testAlloc(0x36421500, 0x38b87d23, 20, FALSE); 1.560 + testAlloc(0x36421500, 0x38b87d23, 200, TRUE); 1.561 + testAlloc(0x36421500, 0x38b87d23, 13700, FALSE); 1.562 + testAlloc(0x36421500, 0x37b87d23, 13700, FALSE); 1.563 + testAlloc(0x36ef1500, 0x37b87d23, 13700, FALSE); 1.564 + testAlloc(0x36421500, 0x36b87d23, 13700, FALSE); 1.565 + testAlloc(0x36b87122, 0x36b87d23, 13700, FALSE); 1.566 + testAlloc(0x49000000, 0x4a600000, 13700, FALSE); 1.567 + testAlloc(0x9fffffff, 0xd0000000, 13700, FALSE); 1.568 + testAlloc(0x9fffffff, 0xd0000000, 67400, FALSE); 1.569 + testAlloc(0x9fffffff, 0xa0030000, 67400, FALSE); 1.570 + testAlloc(0x9fffffff, 0xa0030000, 40000, FALSE); 1.571 + testAlloc(0xa0000000, 0xa0030000, 40000, FALSE); 1.572 + testAlloc(0xa0031100, 0xa0030000, 40000, FALSE); 1.573 +#if 0 1.574 +#endif 1.575 + return 0; 1.576 +} 1.577 + 1.578 +#endif 1.579 + 1.580 +#endif /* #if !UCONFIG_NO_COLLATION */