sl@0: sl@0: sl@0: /************************************************************************ sl@0: * sl@0: * valcmp.cpp - definitions of the rw_valcmp() family of helper functions sl@0: * sl@0: * $Id: valcmp.cpp 332687 2005-11-12 00:47:57Z sebor $ sl@0: * sl@0: ************************************************************************ sl@0: * sl@0: * Copyright (c) 1994-2005 Quovadx, Inc., acting through its Rogue Wave sl@0: * Software division. Licensed under the Apache License, Version 2.0 (the sl@0: * "License"); you may not use this file except in compliance with the sl@0: * License. You may obtain a copy of the License at sl@0: * http://www.apache.org/licenses/LICENSE-2.0. Unless required by sl@0: * applicable law or agreed to in writing, software distributed under sl@0: * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR sl@0: * CONDITIONS OF ANY KIND, either express or implied. See the License sl@0: * for the specific language governing permissions and limitations under sl@0: * the License. sl@0: * sl@0: **************************************************************************/ sl@0: sl@0: // expand _TEST_EXPORT macros sl@0: #define _RWSTD_TEST_SRC sl@0: sl@0: #include sl@0: #include sl@0: sl@0: #include // for fprintf, stderr sl@0: #include // for abort sl@0: #include // for memcmp sl@0: sl@0: /**************************************************************************/ sl@0: sl@0: typedef unsigned char UChar; sl@0: sl@0: sl@0: static const UChar sl@0: _rw_upper [] = { sl@0: sl@0: #if 'A' == 0x41 sl@0: sl@0: // basic ASCII: sl@0: // .0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .a .b .c .d .e .f sl@0: // --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- sl@0: // NUL SOH STX ETX EOT ENQ ACK BEL BS TAB LF VT FF CR SO SI sl@0: /* 0. */ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" sl@0: // DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US sl@0: /* 1. */ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" sl@0: // SPC ! " # $ % ' ' ( ) * + , - . / sl@0: /* 2. */ "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f" sl@0: // 0 1 2 3 4 5 6 7 8 9 : ; < = > ? sl@0: /* 3. */ "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f" sl@0: // A B C D E F G H I J K L M N O sl@0: /* 4. */ "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f" sl@0: // P Q R S T U V W X Y Z [ \ ] ^ _ sl@0: /* 5. */ "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f" sl@0: // ` a b c d e f g h i j k l m n o sl@0: /* 6. */ "\x60\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f" sl@0: // p q r s t u v w x y z { | } ~ DEL sl@0: /* 7. */ "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x7b\x7c\x7d\x7e\x7f" sl@0: sl@0: // extended ASCII: sl@0: /* 8. */ "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f" sl@0: /* 9. */ "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f" sl@0: /* a. */ "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf" sl@0: /* b. */ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf" sl@0: /* c. */ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf" sl@0: /* d. */ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf" sl@0: /* e. */ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef" sl@0: /* f. */ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff" sl@0: sl@0: #elif 'A' == 0xc1 sl@0: sl@0: // EBCDIC: sl@0: // .0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .a .b .c .d .e .f sl@0: // --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- sl@0: // NUL SOH STX ETX PF HT LC DEL SMM VT FF CR SO SI sl@0: /* 0. */ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" sl@0: // DLE DC1 DC2 TM RES NL BS IL CAN EM CC CU1 IFS IGS IRS IUS sl@0: /* 1. */ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" sl@0: // DS SOS FS BYP LF ETB ESC SM CU2 ENQ ACK BEL sl@0: /* 2. */ "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f" sl@0: // SYN PN RS UC EOT CU3 DC4 NAK SUB sl@0: /* 3. */ "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f" sl@0: // SP ct. . < ( + | sl@0: /* 4. */ "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f" sl@0: // & ! $ * ) ; ~ sl@0: /* 5. */ "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f" sl@0: // - / , % _ > ? sl@0: /* 6. */ "\x60\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f" sl@0: // : # @ ' = " sl@0: /* 7. */ "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f" sl@0: // a b c d e f g h i sl@0: /* 8. */ "\x80\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\x8a\x8b\x8c\x8d\x8e\x8f" sl@0: // j k l m n o p q r sl@0: /* 9. */ "\x90\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\x9a\x9b\x9c\x9d\x9e\x9f" sl@0: // s t u v w x y z sl@0: /* a. */ "\xa0\xa1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xaa\xab\xac\xad\xae\xaf" sl@0: // ` sl@0: /* b. */ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf" sl@0: // A B C D E F G H I sl@0: /* c. */ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf" sl@0: // J K L M N O P Q R sl@0: /* d. */ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf" sl@0: // S T U V W X Y Z sl@0: /* e. */ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef" sl@0: // 0 1 2 3 4 5 6 7 8 9 sl@0: /* f. */ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff" sl@0: sl@0: #else // 'A' != 0x41 && 'A' != 0xc1 sl@0: # error unknown character set (neither ASCII nor EBCDIC) sl@0: #endif // ASCII or EBCDIC sl@0: sl@0: }; sl@0: sl@0: sl@0: // returns 1 iff all size bytes of the object pointed to by buf are 0 sl@0: static int sl@0: _rw_iszero (const void *buf, _RWSTD_SIZE_T size) sl@0: { sl@0: for (_RWSTD_SIZE_T i = 0; i != size; ++i) sl@0: if (_RWSTD_STATIC_CAST (const UChar*, buf)[i]) sl@0: return 0; sl@0: sl@0: return 1; sl@0: } sl@0: sl@0: sl@0: // compares two objects of equal size sl@0: static int sl@0: _rw_cmpx (const void *buf1, sl@0: const void *buf2, sl@0: _RWSTD_SIZE_T nelems, sl@0: _RWSTD_SIZE_T size, sl@0: int flags = 0) sl@0: { sl@0: const UChar *p1 = _RWSTD_STATIC_CAST (const UChar*, buf1); sl@0: const UChar *p2 = _RWSTD_STATIC_CAST (const UChar*, buf2); sl@0: sl@0: int ret = 0; sl@0: sl@0: for ( ; nelems; p1 += size, p2 += size, --nelems) { sl@0: sl@0: ret = memcmp (p1, p2, size); sl@0: sl@0: if (flags & CMP_NULTERM) { sl@0: sl@0: const int zero1 = _rw_iszero (p1, size); sl@0: const int zero2 = _rw_iszero (p2, size); sl@0: sl@0: if (zero1 || zero2) { sl@0: ret = zero1 - zero2; sl@0: break; sl@0: } sl@0: } sl@0: sl@0: if (ret && (flags & CMP_NOCASE)) { sl@0: // FIXME: implement sl@0: fprintf (stderr, sl@0: "%s:%d: case insensitive comparison not implemented\n", sl@0: __FILE__, __LINE__); sl@0: abort (); sl@0: } sl@0: } sl@0: sl@0: if (flags & CMP_RETOFF) { sl@0: // FIXME: implement sl@0: fprintf (stderr, sl@0: "%s:%d: returning offset not implemented\n", sl@0: __FILE__, __LINE__); sl@0: abort (); sl@0: } sl@0: sl@0: return ret < 0 ? -1 : ret ? +1 : 0; sl@0: } sl@0: sl@0: sl@0: // compares two byte arrays sl@0: static int sl@0: _rw_cmp1 (const void *buf1, sl@0: const void *buf2, sl@0: _RWSTD_SIZE_T nelems, sl@0: int flags = 0) sl@0: { sl@0: #ifdef _RWSTD_UINT8_T sl@0: sl@0: typedef _RWSTD_UINT8_T UI8T; sl@0: sl@0: if (0 == flags) { sl@0: const int ret = memcmp (buf1, buf2, nelems); sl@0: return ret < 0 ? -1 : ret ? +1 : 0; sl@0: } sl@0: sl@0: if (CMP_NULTERM == flags) { sl@0: const int ret = sl@0: strncmp (_RWSTD_STATIC_CAST (const char*, buf1), sl@0: _RWSTD_STATIC_CAST (const char*, buf2), sl@0: nelems); sl@0: return ret < 0 ? -1 : ret ? +1 : 0; sl@0: } sl@0: sl@0: int ret = 0; sl@0: int inx = 0; sl@0: sl@0: const UI8T *pi1 = _RWSTD_STATIC_CAST (const UI8T*, buf1); sl@0: const UI8T *pi2 = _RWSTD_STATIC_CAST (const UI8T*, buf2); sl@0: sl@0: for (; nelems; ++pi1, ++pi2, --nelems, ++inx) { sl@0: sl@0: const UI8T ui1 = *pi1; sl@0: const UI8T ui2 = *pi2; sl@0: sl@0: if (flags & CMP_NULTERM) { sl@0: sl@0: if (0 == ui1) { sl@0: ret = ui2 ? -1 : 0; sl@0: break; sl@0: } sl@0: sl@0: if (0 == ui2) { sl@0: ret = +1; sl@0: break; sl@0: } sl@0: } sl@0: sl@0: if (ui1 != ui2) { sl@0: if (flags & CMP_NOCASE) { sl@0: if (_rw_upper [ui1] != _rw_upper [ui2]) { sl@0: ret = _rw_upper [ui1] < _rw_upper [ui2] ? -1 : +1; sl@0: break; sl@0: } sl@0: } sl@0: else { sl@0: ret = ui1 < ui2 ? -1 : +1; sl@0: break; sl@0: } sl@0: } sl@0: } sl@0: sl@0: if (CMP_RETOFF & flags) { sl@0: ret = _RWSTD_STATIC_CAST (_RWSTD_SIZE_T, inx) < nelems ? inx : -1; sl@0: } sl@0: sl@0: return ret; sl@0: sl@0: #else // if !defined (_RWSTD_UINT8_T) sl@0: # error _RWSTD_UINT8_T not #defined (configuration problem?) sl@0: #endif // _RWSTD_UINT8_T sl@0: sl@0: } sl@0: sl@0: sl@0: // compares two arrays of objects each 16 bits in size sl@0: static int sl@0: _rw_cmp2 (const void *buf1, sl@0: const void *buf2, sl@0: _RWSTD_SIZE_T nelems, sl@0: int flags = 0) sl@0: { sl@0: #ifdef _RWSTD_UINT16_T sl@0: sl@0: typedef _RWSTD_UINT16_T UI16T; sl@0: sl@0: int ret = 0; sl@0: int inx = 0; sl@0: sl@0: const UI16T *pi1 = _RWSTD_STATIC_CAST (const UI16T*, buf1); sl@0: const UI16T *pi2 = _RWSTD_STATIC_CAST (const UI16T*, buf2); sl@0: sl@0: for (; nelems; ++pi1, ++pi2, --nelems) { sl@0: sl@0: const UI16T ui1 = *pi1; sl@0: const UI16T ui2 = *pi2; sl@0: sl@0: if (flags & CMP_NULTERM) { sl@0: sl@0: if (0 == ui1) { sl@0: ret = ui2 ? -1 : 0; sl@0: break; sl@0: } sl@0: sl@0: if (0 == ui2) { sl@0: ret = +1; sl@0: break; sl@0: } sl@0: } sl@0: sl@0: if (ui1 != ui2) { sl@0: if (flags & CMP_NOCASE) { sl@0: if (_RWSTD_UCHAR_MAX < ui1 || _RWSTD_UCHAR_MAX < ui2) { sl@0: ret = ui1 < ui2 ? -1 : +1; sl@0: break; sl@0: } sl@0: else if (_rw_upper [ui1] != _rw_upper [ui2]) { sl@0: ret = _rw_upper [ui1] < _rw_upper [ui2] ? -1 : +1; sl@0: break; sl@0: } sl@0: } sl@0: else { sl@0: ret = ui1 < ui2 ? -1 : +1; sl@0: break; sl@0: } sl@0: } sl@0: } sl@0: sl@0: if (CMP_RETOFF & flags) { sl@0: ret = _RWSTD_STATIC_CAST (_RWSTD_SIZE_T, inx) < nelems ? inx : -1; sl@0: } sl@0: sl@0: return ret; sl@0: sl@0: #else // if !defined (_RWSTD_UINT16_T) sl@0: sl@0: return _rw_cmpx (buf1, buf2, nelems, 2, flags); sl@0: sl@0: #endif // _RWSTD_UINT16_T sl@0: } sl@0: sl@0: sl@0: // compares two arrays of objects each 32 bits in size sl@0: static int sl@0: _rw_cmp4 (const void *buf1, sl@0: const void *buf2, sl@0: _RWSTD_SIZE_T nelems, sl@0: int flags = 0) sl@0: { sl@0: #ifdef _RWSTD_UINT32_T sl@0: sl@0: typedef _RWSTD_UINT32_T UI32T; sl@0: sl@0: int ret = 0; sl@0: int inx = 0; sl@0: sl@0: const UI32T *pi1 = _RWSTD_STATIC_CAST (const UI32T*, buf1); sl@0: const UI32T *pi2 = _RWSTD_STATIC_CAST (const UI32T*, buf2); sl@0: sl@0: for (; nelems; ++pi1, ++pi2, --nelems) { sl@0: sl@0: const UI32T ui1 = *pi1; sl@0: const UI32T ui2 = *pi2; sl@0: sl@0: if (flags & CMP_NULTERM) { sl@0: sl@0: if (0 == ui1) { sl@0: ret = ui2 ? -1 : 0; sl@0: break; sl@0: } sl@0: sl@0: if (0 == ui2) { sl@0: ret = +1; sl@0: break; sl@0: } sl@0: } sl@0: sl@0: if (ui1 != ui2) { sl@0: if (flags & CMP_NOCASE) { sl@0: if (_RWSTD_UCHAR_MAX < ui1 || _RWSTD_UCHAR_MAX < ui2) { sl@0: ret = ui1 < ui2 ? -1 : +1; sl@0: break; sl@0: } sl@0: else if (_rw_upper [ui1] != _rw_upper [ui2]) { sl@0: ret = _rw_upper [ui1] < _rw_upper [ui2] ? -1 : +1; sl@0: break; sl@0: } sl@0: } sl@0: else { sl@0: ret = ui1 < ui2 ? -1 : +1; sl@0: break; sl@0: } sl@0: } sl@0: } sl@0: sl@0: if (CMP_RETOFF & flags) { sl@0: ret = _RWSTD_STATIC_CAST (_RWSTD_SIZE_T, inx) < nelems ? inx : -1; sl@0: } sl@0: sl@0: return ret; sl@0: sl@0: #else // if !defined (_RWSTD_UINT32_T) sl@0: sl@0: return _rw_cmpx (buf1, buf2, nelems, 4, flags); sl@0: sl@0: #endif // _RWSTD_UINT32_T sl@0: } sl@0: sl@0: sl@0: // compares two arrays of objects each 64 bits in size sl@0: static int sl@0: _rw_cmp8 (const void *buf1, sl@0: const void *buf2, sl@0: _RWSTD_SIZE_T nelems, sl@0: int flags = 0) sl@0: { sl@0: #ifdef _RWSTD_UINT64_T sl@0: sl@0: typedef _RWSTD_UINT64_T UI64T; sl@0: sl@0: int ret = 0; sl@0: int inx = 0; sl@0: sl@0: const UI64T *pi1 = _RWSTD_STATIC_CAST (const UI64T*, buf1); sl@0: const UI64T *pi2 = _RWSTD_STATIC_CAST (const UI64T*, buf2); sl@0: sl@0: for (; nelems; ++pi1, ++pi2, --nelems) { sl@0: sl@0: const UI64T ui1 = *pi1; sl@0: const UI64T ui2 = *pi2; sl@0: sl@0: if (flags & CMP_NULTERM) { sl@0: sl@0: if (0 == ui1) { sl@0: ret = ui2 ? -1 : 0; sl@0: break; sl@0: } sl@0: sl@0: if (0 == ui2) { sl@0: ret = +1; sl@0: break; sl@0: } sl@0: } sl@0: sl@0: if (ui1 != ui2) { sl@0: if (flags & CMP_NOCASE) { sl@0: if (_RWSTD_UCHAR_MAX < ui1 || _RWSTD_UCHAR_MAX < ui2) { sl@0: ret = ui1 < ui2 ? -1 : +1; sl@0: break; sl@0: } sl@0: else if (_rw_upper [ui1] != _rw_upper [ui2]) { sl@0: ret = _rw_upper [ui1] < _rw_upper [ui2] ? -1 : +1; sl@0: break; sl@0: } sl@0: } sl@0: else { sl@0: ret = ui1 < ui2 ? -1 : +1; sl@0: break; sl@0: } sl@0: } sl@0: } sl@0: sl@0: if (CMP_RETOFF & flags) { sl@0: ret = _RWSTD_STATIC_CAST (_RWSTD_SIZE_T, inx) < nelems ? inx : -1; sl@0: } sl@0: sl@0: return ret; sl@0: sl@0: #else // if !defined (_RWSTD_UINT64_T) sl@0: sl@0: return _rw_cmpx (buf1, buf2, nelems, 8, flags); sl@0: sl@0: #endif // _RWSTD_UINT64_T sl@0: } sl@0: sl@0: sl@0: // compares two arrays of objects of unequal size sl@0: static int sl@0: _rw_cmpxx (const void* buf1, sl@0: const void* buf2, sl@0: _RWSTD_SIZE_T nelems, sl@0: _RWSTD_SIZE_T size1, sl@0: _RWSTD_SIZE_T size2, sl@0: int flags) sl@0: { sl@0: int ret = 0; sl@0: int inx = 0; sl@0: sl@0: for (; nelems; --nelems, ++inx) { sl@0: sl@0: #ifdef _RWSTD_UINT64_T sl@0: sl@0: _RWSTD_UINT64_T ui1; sl@0: _RWSTD_UINT64_T ui2; sl@0: sl@0: #else // if !defined (_RWSTD_UINT64_T) sl@0: sl@0: _RWSTD_SIZE_T ui1; sl@0: _RWSTD_SIZE_T ui2; sl@0: sl@0: #endif // _RWSTD_UINT64_T sl@0: sl@0: switch (size1) { sl@0: sl@0: #ifdef _RWSTD_UINT8_T sl@0: sl@0: case 1: { sl@0: const _RWSTD_UINT8_T* ptr = sl@0: _RWSTD_STATIC_CAST (const _RWSTD_UINT8_T*, buf1); sl@0: ui1 = *ptr++; sl@0: buf1 = ptr; sl@0: break; sl@0: } sl@0: sl@0: #endif // _RWSTD_UINT8_T sl@0: sl@0: #ifdef _RWSTD_UINT16_T sl@0: sl@0: case 2: { sl@0: const _RWSTD_UINT16_T* ptr = sl@0: _RWSTD_STATIC_CAST (const _RWSTD_UINT16_T*, buf1); sl@0: ui1 = *ptr++; sl@0: buf1 = ptr; sl@0: break; sl@0: } sl@0: sl@0: #endif // _RWSTD_UINT16_T sl@0: sl@0: #ifdef _RWSTD_UINT32_T sl@0: sl@0: case 4: { sl@0: const _RWSTD_UINT32_T* ptr = sl@0: _RWSTD_STATIC_CAST (const _RWSTD_UINT32_T*, buf1); sl@0: ui1 = *ptr++; sl@0: buf1 = ptr; sl@0: break; sl@0: } sl@0: sl@0: #endif // _RWSTD_UINT32_T sl@0: sl@0: #ifdef _RWSTD_UINT64_T sl@0: sl@0: case 8: { sl@0: const _RWSTD_UINT64_T* ptr = sl@0: _RWSTD_STATIC_CAST (const _RWSTD_UINT64_T*, buf1); sl@0: ui1 = *ptr++; sl@0: buf1 = ptr; sl@0: break; sl@0: } sl@0: sl@0: #endif // _RWSTD_UINT64_T sl@0: sl@0: default: sl@0: fprintf (stderr, sl@0: "%s:%d: comparison of objects %u and %u bytes in size " sl@0: "not implemented\n", __FILE__, __LINE__, sl@0: unsigned (size1), unsigned (size2)); sl@0: abort (); sl@0: } sl@0: sl@0: switch (size2) { sl@0: sl@0: #ifdef _RWSTD_UINT8_T sl@0: sl@0: case 1: { sl@0: const _RWSTD_UINT8_T* ptr = sl@0: _RWSTD_STATIC_CAST (const _RWSTD_UINT8_T*, buf2); sl@0: ui2 = *ptr++; sl@0: buf2 = ptr; sl@0: break; sl@0: } sl@0: sl@0: #endif // _RWSTD_UINT8_T sl@0: sl@0: #ifdef _RWSTD_UINT16_T sl@0: sl@0: case 2: { sl@0: const _RWSTD_UINT16_T* ptr = sl@0: _RWSTD_STATIC_CAST (const _RWSTD_UINT16_T*, buf2); sl@0: ui2 = *ptr++; sl@0: buf2 = ptr; sl@0: break; sl@0: } sl@0: sl@0: #endif // _RWSTD_UINT16_T sl@0: sl@0: #ifdef _RWSTD_UINT32_T sl@0: sl@0: case 4: { sl@0: const _RWSTD_UINT32_T* ptr = sl@0: _RWSTD_STATIC_CAST (const _RWSTD_UINT32_T*, buf2); sl@0: ui2 = *ptr++; sl@0: buf2 = ptr; sl@0: break; sl@0: } sl@0: sl@0: #endif // _RWSTD_UINT32_T sl@0: sl@0: #ifdef _RWSTD_UINT64_T sl@0: sl@0: case 8: { sl@0: const _RWSTD_UINT64_T* ptr = sl@0: _RWSTD_STATIC_CAST (const _RWSTD_UINT64_T*, buf2); sl@0: ui2 = *ptr++; sl@0: buf2 = ptr; sl@0: break; sl@0: } sl@0: sl@0: #endif // _RWSTD_UINT64_T sl@0: sl@0: default: sl@0: fprintf (stderr, sl@0: "%s:%d: comparison of objects %u and %u bytes in size " sl@0: "not implemented\n", __FILE__, __LINE__, sl@0: unsigned (size1), unsigned (size2)); sl@0: abort (); sl@0: } sl@0: sl@0: if (flags & CMP_NULTERM) { sl@0: sl@0: if (0 == ui1) { sl@0: ret = ui2 ? -1 : 0; sl@0: break; sl@0: } sl@0: sl@0: if (0 == ui2) { sl@0: ret = +1; sl@0: break; sl@0: } sl@0: } sl@0: sl@0: if (ui1 != ui2) { sl@0: if (flags & CMP_NOCASE) { sl@0: if (_RWSTD_UCHAR_MAX < ui1 || _RWSTD_UCHAR_MAX < ui2) { sl@0: ret = ui1 < ui2 ? -1 : +1; sl@0: break; sl@0: } sl@0: else if (_rw_upper [ui1] != _rw_upper [ui2]) { sl@0: ret = _rw_upper [ui1] < _rw_upper [ui2] ? -1 : +1; sl@0: break; sl@0: } sl@0: } sl@0: else { sl@0: ret = ui1 < ui2 ? -1 : +1; sl@0: break; sl@0: } sl@0: } sl@0: } sl@0: sl@0: if (CMP_RETOFF & flags) { sl@0: ret = _RWSTD_STATIC_CAST (_RWSTD_SIZE_T, inx) < nelems ? inx : -1; sl@0: } sl@0: sl@0: return ret; sl@0: } sl@0: sl@0: sl@0: _TEST_EXPORT int sl@0: rw_valcmp (const void* buf1, sl@0: const void* buf2, sl@0: _RWSTD_SIZE_T nelems, sl@0: _RWSTD_SIZE_T size1, sl@0: _RWSTD_SIZE_T size2, sl@0: int flags /* = 0 */) sl@0: { sl@0: if (size1 == size2) { sl@0: sl@0: switch (size1) { sl@0: case 1: return _rw_cmp1 (buf1, buf2, nelems, flags); sl@0: case 2: return _rw_cmp2 (buf1, buf2, nelems, flags); sl@0: case 4: return _rw_cmp4 (buf1, buf2, nelems, flags); sl@0: case 8: return _rw_cmp8 (buf1, buf2, nelems, flags); sl@0: } sl@0: sl@0: return _rw_cmpx (buf1, buf2, nelems, size1, flags); sl@0: } sl@0: sl@0: return _rw_cmpxx (buf1, buf2, nelems, size1, size2, flags); sl@0: } sl@0: sl@0: sl@0: _TEST_EXPORT int sl@0: rw_strncmp (const char* str1, sl@0: const char* str2, sl@0: _RWSTD_SIZE_T nelems /* = _RWSTD_SIZE_MAX */, sl@0: int flags /* = CMP_NULTERM */) sl@0: { sl@0: return rw_valcmp (str1, str2, nelems, 1, 1, flags); sl@0: } sl@0: sl@0: sl@0: #ifndef _RWSTD_NO_WCHAR_T sl@0: sl@0: _TEST_EXPORT int sl@0: rw_strncmp (const char* str1, sl@0: const wchar_t* str2, sl@0: _RWSTD_SIZE_T nelems /* = _RWSTD_SIZE_MAX */, sl@0: int flags /* = CMP_NULTERM */) sl@0: { sl@0: return rw_valcmp (str1, str2, nelems, 1, sizeof (wchar_t), flags); sl@0: } sl@0: sl@0: sl@0: _TEST_EXPORT int sl@0: rw_strncmp (const wchar_t* str1, sl@0: const char* str2, sl@0: _RWSTD_SIZE_T nelems /* = _RWSTD_SIZE_MAX */, sl@0: int flags /* = CMP_NULTERM */) sl@0: { sl@0: return rw_valcmp (str1, str2, nelems, sizeof (wchar_t), 1, flags); sl@0: } sl@0: sl@0: sl@0: _TEST_EXPORT int sl@0: rw_strncmp (const wchar_t* str1, sl@0: const wchar_t* str2, sl@0: _RWSTD_SIZE_T nelems /* = _RWSTD_SIZE_MAX */, sl@0: int flags /* = CMP_NULTERM */) sl@0: { sl@0: return rw_valcmp (str1, str2, nelems, sl@0: sizeof (wchar_t), sizeof (wchar_t), flags); sl@0: } sl@0: sl@0: #endif // _RWSTD_NO_WCHAR_T sl@0: sl@0: sl@0: // floating point comparison helpers based on sl@0: // http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm sl@0: sl@0: _TEST_EXPORT int sl@0: rw_fltcmp (float x, float y) sl@0: { sl@0: #if _RWSTD_SHRT_SIZE == _RWSTD_INT_SIZE sl@0: typedef short IntT; sl@0: #ifdef __ARMCC__ sl@0: #pragma diag_suppress 68 sl@0: #endif sl@0: const IntT imin = _RWSTD_SHRT_MIN; sl@0: sl@0: #elif _RWSTD_FLT_SIZE == _RWSTD_INT_SIZE sl@0: typedef int IntT; sl@0: const IntT imin = _RWSTD_INT_MIN; sl@0: #elif _RWSTD_FLT_SIZE == _RWSTD_LONG_SIZE sl@0: typedef long IntT; sl@0: const IntT imin = _RWSTD_LONG_MIN; sl@0: #elif _RWSTD_FLT_SIZE == _RWSTD_LLONG_SIZE sl@0: typedef _RWSTD_LONG_LONG IntT; sl@0: const IntT imin = _RWSTD_LLONG_MIN; sl@0: #else sl@0: // ??? sl@0: # error no integral type of the same size as float exists sl@0: #endif sl@0: sl@0: if (x == y) sl@0: return 0; sl@0: sl@0: // make both arguments lexicographically ordered as twos-complement ints sl@0: IntT x_int = *(IntT*)&x; sl@0: if (x_int < 0) sl@0: x_int = imin - x_int; sl@0: sl@0: IntT y_int = *(IntT*)&y; sl@0: if (y_int < 0) sl@0: y_int = imin - y_int; sl@0: sl@0: const IntT int_diff = x_int - y_int; sl@0: sl@0: return int_diff; sl@0: } sl@0: sl@0: sl@0: #define Abs(x) ((x) < 0 ? -(x) : (x)) sl@0: sl@0: sl@0: _TEST_EXPORT int sl@0: rw_dblcmp (double x, double y) sl@0: { sl@0: #if _RWSTD_DBL_SIZE == _RWSTD_INT_SIZE sl@0: typedef int IntT; sl@0: const IntT imin = _RWSTD_INT_MIN; sl@0: #elif _RWSTD_DBL_SIZE == _RWSTD_LONG_SIZE sl@0: typedef long IntT; sl@0: const IntT imin = _RWSTD_LONG_MIN; sl@0: #elif _RWSTD_DBL_SIZE == _RWSTD_LLONG_SIZE sl@0: typedef _RWSTD_LONG_LONG IntT; sl@0: const IntT imin = _RWSTD_LLONG_MIN; sl@0: #endif sl@0: sl@0: #if _RWSTD_LLONG_SIZE < _RWSTD_DBL_SIZE sl@0: sl@0: if (x == y) sl@0: return 0; sl@0: sl@0: // FIXME: use integer math as in the functions above sl@0: sl@0: const double diff = x - y; sl@0: sl@0: // check absolute error sl@0: if (Abs (diff) < _RWSTD_DBL_EPSILON) sl@0: return 0; sl@0: sl@0: // check relative error sl@0: const double relerr = sl@0: Abs (x) < Abs (y) ? Abs (diff / y) : Abs (diff / x); sl@0: sl@0: if (relerr <= 0.0000001) sl@0: return 0; sl@0: sl@0: return x < y ? -1 : +1; sl@0: sl@0: #else // if !(_RWSTD_LLONG_SIZE < _RWSTD_DBL_SIZE) sl@0: sl@0: if (x == y) sl@0: return 0; sl@0: sl@0: IntT x_int = *(IntT*)&x; sl@0: if (x_int < 0) sl@0: x_int = imin - x_int; sl@0: sl@0: IntT y_int = *(IntT*)&y; sl@0: if (y_int < 0) sl@0: y_int = imin - y_int; sl@0: sl@0: const IntT int_diff = x_int - y_int; sl@0: sl@0: return int_diff; sl@0: sl@0: #endif // _RWSTD_LLONG_SIZE < _RWSTD_DBL_SIZE sl@0: sl@0: } sl@0: sl@0: sl@0: #ifndef _RWSTD_NO_LONG_DOUBLE sl@0: _TEST_EXPORT int sl@0: rw_ldblcmp (long double x, long double y) sl@0: { sl@0: if (sizeof (long double) == sizeof (double)) sl@0: return rw_dblcmp (double (x), double (y)); sl@0: sl@0: #ifdef __ARMCC__ sl@0: #pragma diag_suppress 111 sl@0: #endif sl@0: if (x == y) sl@0: return 0; sl@0: sl@0: sl@0: sl@0: // FIXME: use integer math as in the functions above sl@0: sl@0: const long double diff = x - y; sl@0: sl@0: // check absolute error sl@0: if (Abs (diff) < _RWSTD_LDBL_EPSILON) sl@0: return 0; sl@0: sl@0: // check relative error sl@0: const long double relerr = sl@0: Abs (x) < Abs (y) ? Abs (diff / y) : Abs (diff / x); sl@0: sl@0: if (relerr <= 0.0000001L) sl@0: return 0; sl@0: sl@0: return x < y ? -1 : +1; sl@0: } sl@0: sl@0: #endif // _RWSTD_NO_LONG_DOUBLE sl@0: sl@0: #ifdef __SYMBIAN32__ sl@0: _TEST_EXPORT int sl@0: rw_strcmp (std::basic_string& x ,/*std::basic_string */ long double y) sl@0: { sl@0: const char * c= x.c_str(); sl@0: sl@0: /*if(x.compare(y)==0) sl@0: return 0; sl@0: else sl@0: return x.compare(y)<0?-1:+1; */ sl@0: float z=atof(c); sl@0: sl@0: if ((long double)z == y) sl@0: return 0; sl@0: sl@0: // FIXME: use integer math as in the functions above sl@0: sl@0: const long double diff =((long double)z) - y; sl@0: sl@0: // check absolute error sl@0: if (Abs (diff) < _RWSTD_LDBL_EPSILON) sl@0: return 0; sl@0: sl@0: // check relative error sl@0: const long double relerr = sl@0: Abs ((long double)z) < Abs (y) ? Abs (diff / y) : Abs (diff /(long double)z); sl@0: sl@0: if (relerr <= 0.0000001L) sl@0: return 0; sl@0: sl@0: return z < y ? -1 : +1; sl@0: sl@0: } sl@0: sl@0: _TEST_EXPORT int sl@0: rw_strcmp (std::basic_string& x ,long double y) sl@0: { sl@0: /* if(x.compare(y)==0) sl@0: return 0; sl@0: else sl@0: return x.compare(y)<0?-1:+1; */ sl@0: sl@0: int len=x.length(); sl@0: const wchar_t *w=x.c_str(); sl@0: char c[128]; sl@0: WCtoC(w,len,c); sl@0: sl@0: float z=atof(c); sl@0: sl@0: if ((long double)z == y) sl@0: return 0; sl@0: sl@0: // FIXME: use integer math as in the functions above sl@0: sl@0: const long double diff =((long double)z) - y; sl@0: sl@0: // check absolute error sl@0: if (Abs (diff) < _RWSTD_LDBL_EPSILON) sl@0: return 0; sl@0: sl@0: // check relative error sl@0: const long double relerr = sl@0: Abs ((long double)z) < Abs (y) ? Abs (diff / y) : Abs (diff /(long double)z); sl@0: sl@0: if (relerr <= 0.0000001L) sl@0: return 0; sl@0: sl@0: return z < y ? -1 : +1; sl@0: sl@0: } sl@0: _TEST_EXPORT sl@0: void WCtoC(const wchar_t *wstr, int len, char* str) sl@0: { sl@0: sl@0: int i = 0; sl@0: for (;i