]>
git.saurik.com Git - apple/icu.git/blob - icuSources/common/cstring.c
2 ******************************************************************************
4 * Copyright (C) 1997-2003, International Business Machines
5 * Corporation and others. All Rights Reserved.
7 ******************************************************************************
13 * Modification History:
15 * Date Name Description
16 * 6/18/98 hshih Created
17 * 09/08/98 stephen Added include for ctype, for Mac Port
18 * 11/15/99 helena Integrated S/390 IEEE changes.
19 ******************************************************************************
26 #include "unicode/utypes.h"
32 * We hardcode case conversion for invariant characters to match our expectation
33 * and the compiler execution charset.
34 * This prevents problems on systems
35 * - with non-default casing behavior, like Turkish system locales where
36 * tolower('I') maps to dotless i and toupper('i') maps to dotted I
37 * - where there are no lowercase Latin characters at all, or using different
38 * codes (some old EBCDIC codepages)
40 * This works because the compiler usually runs on a platform where the execution
41 * charset includes all of the invariant characters at their expected
42 * code positions, so that the char * string literals in ICU code match
43 * the char literals here.
45 * Note that the set of lowercase Latin letters is discontiguous in EBCDIC
46 * and the set of uppercase Latin letters is discontiguous as well.
50 uprv_toupper(char c
) {
51 #if U_CHARSET_FAMILY==U_EBCDIC_FAMILY
52 if(('a'<=c
&& c
<='i') || ('j'<=c
&& c
<='r') || ('s'<=c
&& c
<='z')) {
53 c
=(char)(c
+('A'-'a'));
56 if('a'<=c
&& c
<='z') {
57 c
=(char)(c
+('A'-'a'));
66 * Commented out because cstring.h defines uprv_tolower() to be
67 * the same as either uprv_asciitolower() or uprv_ebcdictolower()
68 * to reduce the amount of code to cover with tests.
70 * Note that this uprv_tolower() definition is likely to work for most
71 * charset families, not just ASCII and EBCDIC, because its #else branch
72 * is written generically.
75 uprv_tolower(char c
) {
76 #if U_CHARSET_FAMILY==U_EBCDIC_FAMILY
77 if(('A'<=c
&& c
<='I') || ('J'<=c
&& c
<='R') || ('S'<=c
&& c
<='Z')) {
78 c
=(char)(c
+('a'-'A'));
81 if('A'<=c
&& c
<='Z') {
82 c
=(char)(c
+('a'-'A'));
90 uprv_asciitolower(char c
) {
91 if(0x41<=c
&& c
<=0x5a) {
98 uprv_ebcdictolower(char c
) {
99 if( (0xc1<=(uint8_t)c
&& (uint8_t)c
<=0xc9) ||
100 (0xd1<=(uint8_t)c
&& (uint8_t)c
<=0xd9) ||
101 (0xe2<=(uint8_t)c
&& (uint8_t)c
<=0xe9)
109 U_CAPI
char* U_EXPORT2
110 T_CString_toLowerCase(char* str
)
116 *str
= (char)uprv_tolower(*str
);
123 U_CAPI
char* U_EXPORT2
124 T_CString_toUpperCase(char* str
)
130 *str
= (char)uprv_toupper(*str
);
138 * Takes a int32_t and fills in a char* string with that number "radix"-based.
139 * Does not handle negative values (makes an empty string for them).
140 * Writes at most 12 chars ("-2147483647" plus NUL).
141 * Returns the length of the string (not including the NUL).
143 U_CAPI
int32_t U_EXPORT2
144 T_CString_integerToString(char* buffer
, int32_t v
, int32_t radix
)
147 int32_t tbx
= sizeof(tbuf
);
152 U_ASSERT(radix
>=2 && radix
<=16);
154 if(v
<0 && radix
== 10) {
155 /* Only in base 10 do we conside numbers to be signed. */
156 uval
= (uint32_t)(-v
);
157 buffer
[length
++] = '-';
160 tbx
= sizeof(tbuf
)-1;
161 tbuf
[tbx
] = 0; /* We are generating the digits backwards. Null term the end. */
163 digit
= (uint8_t)(uval
% radix
);
164 tbuf
[--tbx
] = (char)(T_CString_itosOffset(digit
));
168 /* copy converted number into user buffer */
169 uprv_strcpy(buffer
+length
, tbuf
+tbx
);
170 length
+= sizeof(tbuf
) - tbx
-1;
177 * Takes a int64_t and fills in a char* string with that number "radix"-based.
178 * Writes at most 21: chars ("-9223372036854775807" plus NUL).
179 * Returns the length of the string, not including the terminating NULL.
181 U_CAPI
int32_t U_EXPORT2
182 T_CString_int64ToString(char* buffer
, int64_t v
, uint32_t radix
)
185 int32_t tbx
= sizeof(tbuf
);
190 U_ASSERT(radix
>=2 && radix
<=16);
192 if(v
<0 && radix
== 10) {
193 /* Only in base 10 do we conside numbers to be signed. */
194 uval
= (uint64_t)(-v
);
195 buffer
[length
++] = '-';
198 tbx
= sizeof(tbuf
)-1;
199 tbuf
[tbx
] = 0; /* We are generating the digits backwards. Null term the end. */
201 digit
= (uint8_t)(uval
% radix
);
202 tbuf
[--tbx
] = (char)(T_CString_itosOffset(digit
));
206 /* copy converted number into user buffer */
207 uprv_strcpy(buffer
+length
, tbuf
+tbx
);
208 length
+= sizeof(tbuf
) - tbx
-1;
213 U_CAPI
int32_t U_EXPORT2
214 T_CString_stringToInteger(const char *integerString
, int32_t radix
)
217 return uprv_strtoul(integerString
, &end
, radix
);
222 T_CString_stricmp(const char *str1
, const char *str2
) {
229 } else if(str2
==NULL
) {
232 /* compare non-NULL strings lexically with lowercase */
234 unsigned char c1
, c2
;
237 c1
=(unsigned char)*str1
;
238 c2
=(unsigned char)*str2
;
248 /* compare non-zero characters with lowercase */
249 rc
=(int)(unsigned char)uprv_tolower(c1
)-(int)(unsigned char)uprv_tolower(c2
);
261 T_CString_strnicmp(const char *str1
, const char *str2
, uint32_t n
) {
268 } else if(str2
==NULL
) {
271 /* compare non-NULL strings lexically with lowercase */
273 unsigned char c1
, c2
;
276 c1
=(unsigned char)*str1
;
277 c2
=(unsigned char)*str2
;
287 /* compare non-zero characters with lowercase */
288 rc
=(int)(unsigned char)uprv_tolower(c1
)-(int)(unsigned char)uprv_tolower(c2
);
301 U_CAPI
char* U_EXPORT2
302 uprv_strdup(const char *src
) {
303 size_t len
= uprv_strlen(src
) + 1;
304 char *dup
= (char *) uprv_malloc(len
);
307 uprv_memcpy(dup
, src
, len
);
313 U_CAPI
char* U_EXPORT2
314 uprv_strndup(const char *src
, int32_t n
) {
318 dup
= uprv_strdup(src
);
320 dup
= (char*)uprv_malloc(n
+1);
322 uprv_memcpy(dup
, src
, n
);