mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-13 08:53:20 +00:00
ICU-174 make code more robust
X-SVN-Rev: 337
This commit is contained in:
parent
61c30e4e4e
commit
5927a9f1e8
11 changed files with 267 additions and 129 deletions
|
@ -33,8 +33,12 @@
|
|||
U_CAPI FileStream*
|
||||
T_FileStream_open(const char* filename, const char* mode)
|
||||
{
|
||||
FILE *file = fopen(filename, mode);
|
||||
return (FileStream*)file;
|
||||
if(filename != NULL && *filename != 0 && mode != NULL && *mode != 0) {
|
||||
FILE *file = fopen(filename, mode);
|
||||
return (FileStream*)file;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -109,7 +109,11 @@ Normalizer::~Normalizer()
|
|||
Normalizer*
|
||||
Normalizer::clone() const
|
||||
{
|
||||
return new Normalizer(*this);
|
||||
if(this!=0) {
|
||||
return new Normalizer(*this);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include "uhash.h"
|
||||
#include "ustring.h"
|
||||
#include "cstring.h"
|
||||
#include "cmemory.h"
|
||||
|
||||
/* Private function prototypes */
|
||||
|
@ -505,59 +506,69 @@ uhash_find(const UHashtable *hash,
|
|||
U_CAPI int32_t
|
||||
uhash_hashUString(const void *parm)
|
||||
{
|
||||
const UChar *key = (const UChar*) parm;
|
||||
int32_t len = u_strlen(key);
|
||||
int32_t hash = UHASH_INVALID;
|
||||
const UChar *limit = key + len;
|
||||
int32_t inc = (len >= 128 ? len/64 : 1);
|
||||
if(parm != NULL) {
|
||||
const UChar *key = (const UChar*) parm;
|
||||
int32_t len = u_strlen(key);
|
||||
int32_t hash = UHASH_INVALID;
|
||||
const UChar *limit = key + len;
|
||||
int32_t inc = (len >= 128 ? len/64 : 1);
|
||||
|
||||
/*
|
||||
We compute the hash by iterating sparsely over 64 (at most) characters
|
||||
spaced evenly through the string. For each character, we multiply the
|
||||
previous hash value by a prime number and add the new character in,
|
||||
in the manner of a additive linear congruential random number generator,
|
||||
thus producing a pseudorandom deterministic value which should be well
|
||||
distributed over the output range. [LIU]
|
||||
*/
|
||||
/*
|
||||
We compute the hash by iterating sparsely over 64 (at most) characters
|
||||
spaced evenly through the string. For each character, we multiply the
|
||||
previous hash value by a prime number and add the new character in,
|
||||
in the manner of a additive linear congruential random number generator,
|
||||
thus producing a pseudorandom deterministic value which should be well
|
||||
distributed over the output range. [LIU]
|
||||
*/
|
||||
|
||||
while(key < limit) {
|
||||
hash = (hash * 37) + *key;
|
||||
key += inc;
|
||||
while(key < limit) {
|
||||
hash = (hash * 37) + *key;
|
||||
key += inc;
|
||||
}
|
||||
|
||||
if(hash == UHASH_INVALID) {
|
||||
hash = UHASH_EMPTY;
|
||||
}
|
||||
|
||||
return hash & 0x7FFFFFFF;
|
||||
} else {
|
||||
return UHASH_INVALID;
|
||||
}
|
||||
|
||||
if(hash == UHASH_INVALID)
|
||||
hash = UHASH_EMPTY;
|
||||
|
||||
return hash & 0x7FFFFFFF;
|
||||
}
|
||||
|
||||
U_CAPI int32_t
|
||||
uhash_hashString(const void *parm)
|
||||
{
|
||||
const char *key = (const char*) parm;
|
||||
int32_t len = strlen(key);
|
||||
int32_t hash = UHASH_INVALID;
|
||||
const char *limit = key + len;
|
||||
int32_t inc = (len >= 128 ? len/64 : 1);
|
||||
if(parm != NULL) {
|
||||
const char *key = (const char*) parm;
|
||||
int32_t len = icu_strlen(key);
|
||||
int32_t hash = UHASH_INVALID;
|
||||
const char *limit = key + len;
|
||||
int32_t inc = (len >= 128 ? len/64 : 1);
|
||||
|
||||
/*
|
||||
We compute the hash by iterating sparsely over 64 (at most) characters
|
||||
spaced evenly through the string. For each character, we multiply the
|
||||
previous hash value by a prime number and add the new character in,
|
||||
in the manner of a additive linear congruential random number generator,
|
||||
thus producing a pseudorandom deterministic value which should be well
|
||||
distributed over the output range. [LIU]
|
||||
*/
|
||||
/*
|
||||
We compute the hash by iterating sparsely over 64 (at most) characters
|
||||
spaced evenly through the string. For each character, we multiply the
|
||||
previous hash value by a prime number and add the new character in,
|
||||
in the manner of a additive linear congruential random number generator,
|
||||
thus producing a pseudorandom deterministic value which should be well
|
||||
distributed over the output range. [LIU]
|
||||
*/
|
||||
|
||||
while(key < limit) {
|
||||
hash = (hash * 37) + *key;
|
||||
key += inc;
|
||||
while(key < limit) {
|
||||
hash = (hash * 37) + *key;
|
||||
key += inc;
|
||||
}
|
||||
|
||||
if(hash == UHASH_INVALID) {
|
||||
hash = UHASH_EMPTY;
|
||||
}
|
||||
|
||||
return hash & 0x7FFFFFFF;
|
||||
} else {
|
||||
return UHASH_INVALID;
|
||||
}
|
||||
|
||||
if(hash == UHASH_INVALID)
|
||||
hash = UHASH_EMPTY;
|
||||
|
||||
return hash & 0x7FFFFFFF;
|
||||
}
|
||||
|
||||
U_CAPI int32_t
|
||||
|
|
|
@ -492,6 +492,10 @@ UnicodeString::doLastIndexOf(UChar c,
|
|||
UTextOffset start,
|
||||
int32_t length) const
|
||||
{
|
||||
if(isBogus()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// pin indices
|
||||
pinIndices(start, length);
|
||||
if(length == 0) {
|
||||
|
|
|
@ -1615,8 +1615,16 @@ UnicodeString::UnicodeString(const UnicodeString& that)
|
|||
//========================================
|
||||
inline bool_t
|
||||
UnicodeString::operator== (const UnicodeString& text) const
|
||||
{ return (fLength == text.fLength
|
||||
&& doCompare(0, fLength, text, 0, text.fLength) == 0); }
|
||||
{
|
||||
if(isBogus()) {
|
||||
return text.isBogus();
|
||||
} else {
|
||||
return
|
||||
!text.isBogus() &&
|
||||
fLength == text.fLength &&
|
||||
doCompare(0, fLength, text, 0, text.fLength) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool_t
|
||||
UnicodeString::operator!= (const UnicodeString& text) const
|
||||
|
|
|
@ -36,11 +36,16 @@ UChar*
|
|||
u_strcat(UChar *dst,
|
||||
const UChar *src)
|
||||
{
|
||||
UChar *anchor = dst; /* save a pointer to start of dst */
|
||||
|
||||
while(*dst++); /* To end of first string */
|
||||
dst--; /* Return to the null */
|
||||
while(*dst++ = *src++); /* copy string 2 over */
|
||||
UChar *anchor = dst; /* save a pointer to start of dst */
|
||||
|
||||
while(*dst != 0) { /* To end of first string */
|
||||
++dst;
|
||||
}
|
||||
while((*dst = *src) != 0) { /* copy string 2 over */
|
||||
++dst;
|
||||
++src;
|
||||
}
|
||||
|
||||
return anchor;
|
||||
}
|
||||
|
||||
|
@ -49,26 +54,37 @@ u_strncat(UChar *dst,
|
|||
const UChar *src,
|
||||
int32_t n )
|
||||
{
|
||||
UChar *anchor = dst; /* save a pointer to start of dst */
|
||||
if(n > 0) {
|
||||
UChar *anchor = dst; /* save a pointer to start of dst */
|
||||
|
||||
while(*dst != 0) { /* To end of first string */
|
||||
++dst;
|
||||
}
|
||||
while((*dst = *src) != 0) { /* copy string 2 over */
|
||||
++dst;
|
||||
if(--n == 0) {
|
||||
*dst = 0;
|
||||
break;
|
||||
}
|
||||
++src;
|
||||
}
|
||||
|
||||
if (!n) return dst;
|
||||
while(*dst++); /* To end of first string */
|
||||
dst--; /* Return to the null */
|
||||
while((*dst++ = *src++) && --n); /* copy string 2 over */
|
||||
*dst = 0x0000;
|
||||
|
||||
return anchor;
|
||||
return anchor;
|
||||
} else {
|
||||
return dst;
|
||||
}
|
||||
}
|
||||
|
||||
UChar*
|
||||
u_strchr(const UChar *s,
|
||||
UChar c)
|
||||
{
|
||||
while((*s != c) && *s)
|
||||
s++;
|
||||
|
||||
if(*s == c)
|
||||
return (UChar*) s;
|
||||
while(*s != 0) {
|
||||
if(*s == c) {
|
||||
return (UChar *)s;
|
||||
}
|
||||
++s;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -76,12 +92,15 @@ int32_t
|
|||
u_strcmp(const UChar *s1,
|
||||
const UChar *s2)
|
||||
{
|
||||
while((*s1 == *s2) && *s1) {
|
||||
s1++;
|
||||
s2++;
|
||||
int32_t rc;
|
||||
for(;;) {
|
||||
rc = (int32_t)*s1 - (int32_t)*s2;
|
||||
if(rc != 0 || *s1 == 0) {
|
||||
return rc;
|
||||
}
|
||||
++s1;
|
||||
++s2;
|
||||
}
|
||||
|
||||
return (int32_t)*s1 - (int32_t)*s2;
|
||||
}
|
||||
|
||||
int32_t
|
||||
|
@ -89,21 +108,32 @@ u_strncmp(const UChar *s1,
|
|||
const UChar *s2,
|
||||
int32_t n)
|
||||
{
|
||||
if (!n) return 0;
|
||||
while((*s1 == *s2) && *s1 && --n) {
|
||||
s1++;
|
||||
s2++;
|
||||
if(n > 0) {
|
||||
int32_t rc;
|
||||
for(;;) {
|
||||
rc = (int32_t)*s1 - (int32_t)*s2;
|
||||
if(rc != 0 || *s1 == 0 || --n == 0) {
|
||||
return rc;
|
||||
}
|
||||
++s1;
|
||||
++s2;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
return (int32_t)*s1 - (int32_t)*s2;
|
||||
}
|
||||
|
||||
UChar*
|
||||
u_strcpy(UChar *dst,
|
||||
const UChar *src)
|
||||
{
|
||||
UChar *anchor = dst; /* save the start of result string */
|
||||
|
||||
while(*dst++ = *src++);
|
||||
UChar *anchor = dst; /* save a pointer to start of dst */
|
||||
|
||||
while((*dst = *src) != 0) { /* copy string 2 over */
|
||||
++dst;
|
||||
++src;
|
||||
}
|
||||
|
||||
return anchor;
|
||||
}
|
||||
|
||||
|
@ -112,22 +142,36 @@ u_strncpy(UChar *dst,
|
|||
const UChar *src,
|
||||
int32_t n)
|
||||
{
|
||||
UChar *anchor = dst; /* save the start of result string */
|
||||
|
||||
if (!n) return dst;
|
||||
while((*dst++ = *src++) && --n);
|
||||
*dst = 0x0000;
|
||||
UChar *anchor = dst; /* save a pointer to start of dst */
|
||||
|
||||
if(n > 0) {
|
||||
while((*dst = *src) != 0) { /* copy string 2 over */
|
||||
++dst;
|
||||
if(--n == 0) {
|
||||
*dst = 0;
|
||||
break;
|
||||
}
|
||||
++src;
|
||||
}
|
||||
} else {
|
||||
*dst = 0;
|
||||
}
|
||||
|
||||
return anchor;
|
||||
}
|
||||
|
||||
int32_t
|
||||
u_strlen(const UChar *s)
|
||||
{
|
||||
int32_t i = 0;
|
||||
|
||||
while(*s++)
|
||||
i++;
|
||||
return i;
|
||||
if(U_SIZEOF_WCHAR_T == sizeof(UChar)) {
|
||||
return icu_wcslen(s);
|
||||
} else {
|
||||
const UChar *t = s;
|
||||
while(*t != 0) {
|
||||
++t;
|
||||
}
|
||||
return t - s;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -136,12 +180,14 @@ UChar* u_uastrcpy(UChar *ucs1,
|
|||
{
|
||||
UErrorCode err = U_ZERO_ERROR;
|
||||
ucnv_toUChars(defaultConverter,
|
||||
ucs1,
|
||||
MAX_STRLEN,
|
||||
s2,
|
||||
icu_strlen(s2),
|
||||
&err);
|
||||
|
||||
ucs1,
|
||||
MAX_STRLEN,
|
||||
s2,
|
||||
icu_strlen(s2),
|
||||
&err);
|
||||
if(U_FAILURE(err)) {
|
||||
*ucs1 = 0;
|
||||
}
|
||||
return ucs1;
|
||||
}
|
||||
|
||||
|
@ -150,33 +196,29 @@ UChar* u_uastrncpy(UChar *ucs1,
|
|||
int32_t n)
|
||||
{
|
||||
UErrorCode err = U_ZERO_ERROR;
|
||||
int32_t end = ucnv_toUChars(defaultConverter,
|
||||
ucnv_toUChars(defaultConverter,
|
||||
ucs1,
|
||||
n,
|
||||
s2,
|
||||
icu_strlen(s2),
|
||||
&err);
|
||||
|
||||
ucs1[icu_min(end,n)] = 0x0000;
|
||||
|
||||
if(U_FAILURE(err)) {
|
||||
*ucs1 = 0;
|
||||
}
|
||||
return ucs1;
|
||||
}
|
||||
|
||||
char* u_austrcpy(char *s1,
|
||||
const UChar *ucs2 )
|
||||
{
|
||||
char * anchor = s1; /* save the start of result string */
|
||||
UErrorCode err = U_ZERO_ERROR;
|
||||
int32_t len = ucnv_fromUChars(defaultConverter,
|
||||
s1,
|
||||
MAX_STRLEN,
|
||||
ucs2,
|
||||
&err);
|
||||
|
||||
s1[len] = '\0';
|
||||
|
||||
s1[len] = 0;
|
||||
return s1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -385,6 +385,10 @@ void SimpleDateFormat::parseAmbiguousDatesAsAfter(UDate startDate, UErrorCode& s
|
|||
UnicodeString&
|
||||
SimpleDateFormat::format(UDate date, UnicodeString& toAppendTo, FieldPosition& pos) const
|
||||
{
|
||||
if (fCalendar == 0) {
|
||||
return toAppendTo;
|
||||
}
|
||||
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
pos.setBeginIndex(0);
|
||||
pos.setEndIndex(0);
|
||||
|
|
|
@ -26,20 +26,32 @@
|
|||
#include <string.h>
|
||||
#include "uchar.h"
|
||||
#include "ustring.h"
|
||||
#include "ucnv.h"
|
||||
|
||||
static char* _testDirectory=NULL;
|
||||
int main ( int argc, char **argv )
|
||||
{
|
||||
|
||||
|
||||
TestNode *root = NULL;
|
||||
addAllTests(&root);
|
||||
processArgs(root, argc, argv);
|
||||
|
||||
TestNode *root;
|
||||
|
||||
return 0;
|
||||
/* initial check for the default converter */
|
||||
UErrorCode errorCode = U_ZERO_ERROR;
|
||||
UConverter *cnv = ucnv_open(NULL, &errorCode);
|
||||
if(cnv != NULL) {
|
||||
// ok
|
||||
ucnv_close(cnv);
|
||||
} else {
|
||||
fprintf(stderr,
|
||||
"*** Failure! The default converter cannot be opened.\n"
|
||||
"*** Check the ICU_DATA environment variable and \n"
|
||||
"*** check that the data files are present.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
root = NULL;
|
||||
addAllTests(&root);
|
||||
processArgs(root, argc, argv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -654,7 +654,7 @@ bool_t IntlTest::runTestLoop( char* testname, char* par )
|
|||
/**
|
||||
* Adds given string to the log if we are in verbose mode.
|
||||
*/
|
||||
void IntlTest::log( UnicodeString message )
|
||||
void IntlTest::log( const UnicodeString &message )
|
||||
{
|
||||
if( verbose ) {
|
||||
LL_message( message, FALSE );
|
||||
|
@ -665,7 +665,7 @@ void IntlTest::log( UnicodeString message )
|
|||
* Adds given string to the log if we are in verbose mode. Adds a new line to
|
||||
* the given message.
|
||||
*/
|
||||
void IntlTest::logln( UnicodeString message )
|
||||
void IntlTest::logln( const UnicodeString &message )
|
||||
{
|
||||
if( verbose ) {
|
||||
LL_message( message, TRUE );
|
||||
|
@ -690,13 +690,13 @@ void IntlTest::err() {
|
|||
IncErrorCount();
|
||||
}
|
||||
|
||||
void IntlTest::err( UnicodeString message )
|
||||
void IntlTest::err( const UnicodeString &message )
|
||||
{
|
||||
IncErrorCount();
|
||||
if (!no_err_msg) LL_message( message, FALSE );
|
||||
}
|
||||
|
||||
void IntlTest::errln( UnicodeString message )
|
||||
void IntlTest::errln( const UnicodeString &message )
|
||||
{
|
||||
IncErrorCount();
|
||||
if (!no_err_msg) LL_message( message, TRUE );
|
||||
|
@ -862,6 +862,19 @@ main(int argc, char* argv[])
|
|||
cout << " Leaks (l) : " << (leaks? "On" : "Off") << endl;
|
||||
cout << "-----------------------------------------------" << endl << endl;
|
||||
|
||||
// initial check for the default converter
|
||||
UErrorCode errorCode = U_ZERO_ERROR;
|
||||
UConverter *cnv = ucnv_open(0, &errorCode);
|
||||
if(cnv != 0) {
|
||||
// ok
|
||||
ucnv_close(cnv);
|
||||
} else {
|
||||
cout << "*** Failure! The default converter cannot be opened." << endl <<
|
||||
"*** Check the ICU_DATA environment variable and " << endl <<
|
||||
"*** check that the data files are present." << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (all) {
|
||||
major.runTest();
|
||||
if (leaks) {
|
||||
|
|
|
@ -68,17 +68,29 @@ public:
|
|||
virtual void setCaller( IntlTest* callingTest ); // for internal use only
|
||||
virtual void setPath( char* path ); // for internal use only
|
||||
|
||||
virtual void log( UnicodeString message );
|
||||
virtual void log( const UnicodeString &message );
|
||||
|
||||
// convenience function; assume that the message contains only invariant charcters
|
||||
virtual void log( const char *message );
|
||||
|
||||
virtual void logln( UnicodeString message );
|
||||
virtual void logln( const UnicodeString &message );
|
||||
|
||||
// convenience function; assume that the message contains only invariant charcters
|
||||
virtual void logln( const char *message );
|
||||
|
||||
virtual void logln( void );
|
||||
|
||||
virtual void err(void);
|
||||
|
||||
virtual void err( UnicodeString message );
|
||||
virtual void err( const UnicodeString &message );
|
||||
|
||||
virtual void errln( UnicodeString message );
|
||||
// convenience function; assume that the message contains only invariant charcters
|
||||
virtual void err( const char *message );
|
||||
|
||||
virtual void errln( const UnicodeString &message );
|
||||
|
||||
// convenience function; assume that the message contains only invariant charcters
|
||||
virtual void errln( const char *message );
|
||||
|
||||
virtual void usage( void ) ;
|
||||
|
||||
|
@ -136,6 +148,21 @@ public:
|
|||
|
||||
};
|
||||
|
||||
inline void IntlTest::log( const char *message ) {
|
||||
log(UnicodeString(message, ""));
|
||||
}
|
||||
|
||||
inline void IntlTest::logln( const char *message ) {
|
||||
logln(UnicodeString(message, ""));
|
||||
}
|
||||
|
||||
inline void IntlTest::err( const char *message ) {
|
||||
err(UnicodeString(message, ""));
|
||||
}
|
||||
|
||||
inline void IntlTest::errln( const char *message ) {
|
||||
errln(UnicodeString(message, ""));
|
||||
}
|
||||
|
||||
void it_log( UnicodeString message );
|
||||
void it_logln( UnicodeString message );
|
||||
|
|
|
@ -89,11 +89,16 @@ CollationMonkeyTest::checkValue(int32_t value)
|
|||
|
||||
void CollationMonkeyTest::TestCollationKey( char* par )
|
||||
{
|
||||
if(source.length() == 0) {
|
||||
errln(UNICODE_STRING("CollationMonkeyTest::TestCollationKey(): source is empty - ICU_DATA not set or data missing?", 92));
|
||||
return;
|
||||
}
|
||||
|
||||
srand( (unsigned)time( NULL ) );
|
||||
int32_t s = checkValue(rand() % source.size());
|
||||
int32_t t = checkValue(rand() % source.size());
|
||||
int32_t slen = checkValue((rand() - source.size()) % source.size());
|
||||
int32_t tlen = checkValue((rand() - source.size()) % source.size());
|
||||
int32_t s = checkValue(rand() % source.length());
|
||||
int32_t t = checkValue(rand() % source.length());
|
||||
int32_t slen = checkValue((rand() - source.length()) % source.length());
|
||||
int32_t tlen = checkValue((rand() - source.length()) % source.length());
|
||||
UnicodeString subs, subt;
|
||||
|
||||
source.extract(MIN(s, slen), MAX(s, slen), subs);
|
||||
|
@ -156,15 +161,19 @@ void CollationMonkeyTest::TestCollationKey( char* par )
|
|||
void
|
||||
CollationMonkeyTest::TestCompare(char* par)
|
||||
{
|
||||
if(source.length() == 0) {
|
||||
errln(UNICODE_STRING("CollationMonkeyTest::TestCompare(): source is empty - ICU_DATA not set or data missing?", 87));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Seed the random-number generator with current time so that
|
||||
* the numbers will be different every time we run.
|
||||
*/
|
||||
srand( (unsigned)time( NULL ) );
|
||||
int32_t s = checkValue(rand() % source.size());
|
||||
int32_t t = checkValue(rand() % source.size());
|
||||
int32_t slen = checkValue((rand() - source.size()) % source.size());
|
||||
int32_t tlen = checkValue((rand() - source.size()) % source.size());
|
||||
int32_t s = checkValue(rand() % source.length());
|
||||
int32_t t = checkValue(rand() % source.length());
|
||||
int32_t slen = checkValue((rand() - source.length()) % source.length());
|
||||
int32_t tlen = checkValue((rand() - source.length()) % source.length());
|
||||
UnicodeString subs, subt;
|
||||
|
||||
source.extract(MIN(s, slen), MAX(s, slen), subs);
|
||||
|
|
Loading…
Add table
Reference in a new issue