ICU-174 make code more robust

X-SVN-Rev: 337
This commit is contained in:
Markus Scherer 1999-12-08 00:15:46 +00:00
parent 61c30e4e4e
commit 5927a9f1e8
11 changed files with 267 additions and 129 deletions

View file

@ -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;
}
}

View file

@ -109,7 +109,11 @@ Normalizer::~Normalizer()
Normalizer*
Normalizer::clone() const
{
return new Normalizer(*this);
if(this!=0) {
return new Normalizer(*this);
} else {
return 0;
}
}
/**

View file

@ -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

View file

@ -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) {

View file

@ -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

View file

@ -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;
}

View file

@ -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);

View file

@ -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

View file

@ -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) {

View file

@ -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 );

View file

@ -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);