|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 #include "nsCRTGlue.h" |
|
6 #include "nsXPCOM.h" |
|
7 #include "nsDebug.h" |
|
8 #include "prtime.h" |
|
9 |
|
10 #include <stdlib.h> |
|
11 #include <string.h> |
|
12 #include <stdio.h> |
|
13 #include <stdarg.h> |
|
14 |
|
15 #ifdef XP_WIN |
|
16 #include <io.h> |
|
17 #include <windows.h> |
|
18 #endif |
|
19 |
|
20 #ifdef ANDROID |
|
21 #include <android/log.h> |
|
22 #endif |
|
23 |
|
24 const char* |
|
25 NS_strspnp(const char *delims, const char *str) |
|
26 { |
|
27 const char *d; |
|
28 do { |
|
29 for (d = delims; *d != '\0'; ++d) { |
|
30 if (*str == *d) { |
|
31 ++str; |
|
32 break; |
|
33 } |
|
34 } |
|
35 } while (*d); |
|
36 |
|
37 return str; |
|
38 } |
|
39 |
|
40 char* |
|
41 NS_strtok(const char *delims, char **str) |
|
42 { |
|
43 if (!*str) |
|
44 return nullptr; |
|
45 |
|
46 char *ret = (char*) NS_strspnp(delims, *str); |
|
47 |
|
48 if (!*ret) { |
|
49 *str = ret; |
|
50 return nullptr; |
|
51 } |
|
52 |
|
53 char *i = ret; |
|
54 do { |
|
55 for (const char *d = delims; *d != '\0'; ++d) { |
|
56 if (*i == *d) { |
|
57 *i = '\0'; |
|
58 *str = ++i; |
|
59 return ret; |
|
60 } |
|
61 } |
|
62 ++i; |
|
63 } while (*i); |
|
64 |
|
65 *str = nullptr; |
|
66 return ret; |
|
67 } |
|
68 |
|
69 uint32_t |
|
70 NS_strlen(const char16_t *aString) |
|
71 { |
|
72 const char16_t *end; |
|
73 |
|
74 for (end = aString; *end; ++end) { |
|
75 // empty loop |
|
76 } |
|
77 |
|
78 return end - aString; |
|
79 } |
|
80 |
|
81 int |
|
82 NS_strcmp(const char16_t *a, const char16_t *b) |
|
83 { |
|
84 while (*b) { |
|
85 int r = *a - *b; |
|
86 if (r) |
|
87 return r; |
|
88 |
|
89 ++a; |
|
90 ++b; |
|
91 } |
|
92 |
|
93 return *a != '\0'; |
|
94 } |
|
95 |
|
96 char16_t* |
|
97 NS_strdup(const char16_t *aString) |
|
98 { |
|
99 uint32_t len = NS_strlen(aString); |
|
100 return NS_strndup(aString, len); |
|
101 } |
|
102 |
|
103 char16_t* |
|
104 NS_strndup(const char16_t *aString, uint32_t aLen) |
|
105 { |
|
106 char16_t *newBuf = (char16_t*) NS_Alloc((aLen + 1) * sizeof(char16_t)); |
|
107 if (newBuf) { |
|
108 memcpy(newBuf, aString, aLen * sizeof(char16_t)); |
|
109 newBuf[aLen] = '\0'; |
|
110 } |
|
111 return newBuf; |
|
112 } |
|
113 |
|
114 char* |
|
115 NS_strdup(const char *aString) |
|
116 { |
|
117 uint32_t len = strlen(aString); |
|
118 char *str = (char*) NS_Alloc(len + 1); |
|
119 if (str) { |
|
120 memcpy(str, aString, len); |
|
121 str[len] = '\0'; |
|
122 } |
|
123 return str; |
|
124 } |
|
125 |
|
126 // This table maps uppercase characters to lower case characters; |
|
127 // characters that are neither upper nor lower case are unaffected. |
|
128 const unsigned char nsLowerUpperUtils::kUpper2Lower[256] = { |
|
129 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, |
|
130 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, |
|
131 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, |
|
132 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, |
|
133 64, |
|
134 |
|
135 // upper band mapped to lower [A-Z] => [a-z] |
|
136 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111, |
|
137 112,113,114,115,116,117,118,119,120,121,122, |
|
138 |
|
139 91, 92, 93, 94, 95, |
|
140 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111, |
|
141 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, |
|
142 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, |
|
143 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, |
|
144 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, |
|
145 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, |
|
146 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, |
|
147 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, |
|
148 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, |
|
149 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 |
|
150 }; |
|
151 |
|
152 const unsigned char nsLowerUpperUtils::kLower2Upper[256] = { |
|
153 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, |
|
154 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, |
|
155 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, |
|
156 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, |
|
157 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, |
|
158 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, |
|
159 96, |
|
160 |
|
161 // lower band mapped to upper [a-z] => [A-Z] |
|
162 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, |
|
163 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, |
|
164 |
|
165 123,124,125,126,127, |
|
166 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, |
|
167 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, |
|
168 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, |
|
169 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, |
|
170 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, |
|
171 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, |
|
172 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, |
|
173 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 |
|
174 }; |
|
175 |
|
176 bool NS_IsUpper(char aChar) |
|
177 { |
|
178 return aChar != (char)nsLowerUpperUtils::kUpper2Lower[(unsigned char)aChar]; |
|
179 } |
|
180 |
|
181 bool NS_IsLower(char aChar) |
|
182 { |
|
183 return aChar != (char)nsLowerUpperUtils::kLower2Upper[(unsigned char)aChar]; |
|
184 } |
|
185 |
|
186 bool NS_IsAscii(char16_t aChar) |
|
187 { |
|
188 return (0x0080 > aChar); |
|
189 } |
|
190 |
|
191 bool NS_IsAscii(const char16_t *aString) |
|
192 { |
|
193 while(*aString) { |
|
194 if( 0x0080 <= *aString) |
|
195 return false; |
|
196 aString++; |
|
197 } |
|
198 return true; |
|
199 } |
|
200 |
|
201 bool NS_IsAscii(const char *aString) |
|
202 { |
|
203 while(*aString) { |
|
204 if( 0x80 & *aString) |
|
205 return false; |
|
206 aString++; |
|
207 } |
|
208 return true; |
|
209 } |
|
210 |
|
211 bool NS_IsAscii(const char* aString, uint32_t aLength) |
|
212 { |
|
213 const char* end = aString + aLength; |
|
214 while (aString < end) { |
|
215 if (0x80 & *aString) |
|
216 return false; |
|
217 ++aString; |
|
218 } |
|
219 return true; |
|
220 } |
|
221 |
|
222 bool NS_IsAsciiAlpha(char16_t aChar) |
|
223 { |
|
224 return ((aChar >= 'A') && (aChar <= 'Z')) || |
|
225 ((aChar >= 'a') && (aChar <= 'z')); |
|
226 } |
|
227 |
|
228 bool NS_IsAsciiWhitespace(char16_t aChar) |
|
229 { |
|
230 return aChar == ' ' || |
|
231 aChar == '\r' || |
|
232 aChar == '\n' || |
|
233 aChar == '\t'; |
|
234 } |
|
235 |
|
236 bool NS_IsAsciiDigit(char16_t aChar) |
|
237 { |
|
238 return aChar >= '0' && aChar <= '9'; |
|
239 } |
|
240 |
|
241 |
|
242 #ifndef XPCOM_GLUE_AVOID_NSPR |
|
243 #define TABLE_SIZE 36 |
|
244 static const char table[] = { |
|
245 'a','b','c','d','e','f','g','h','i','j', |
|
246 'k','l','m','n','o','p','q','r','s','t', |
|
247 'u','v','w','x','y','z','0','1','2','3', |
|
248 '4','5','6','7','8','9' |
|
249 }; |
|
250 |
|
251 void NS_MakeRandomString(char *aBuf, int32_t aBufLen) |
|
252 { |
|
253 // turn PR_Now() into milliseconds since epoch |
|
254 // and salt rand with that. |
|
255 static unsigned int seed = 0; |
|
256 if (seed == 0) { |
|
257 double fpTime = double(PR_Now()); |
|
258 seed = (unsigned int)(fpTime * 1e-6 + 0.5); // use 1e-6, granularity of PR_Now() on the mac is seconds |
|
259 srand(seed); |
|
260 } |
|
261 |
|
262 int32_t i; |
|
263 for (i=0;i<aBufLen;i++) { |
|
264 *aBuf++ = table[rand()%TABLE_SIZE]; |
|
265 } |
|
266 *aBuf = 0; |
|
267 } |
|
268 |
|
269 #endif |
|
270 #if defined(XP_WIN) |
|
271 |
|
272 #define va_copy(dest, src) (dest = src) |
|
273 |
|
274 void |
|
275 vprintf_stderr(const char *fmt, va_list args) |
|
276 { |
|
277 if (IsDebuggerPresent()) { |
|
278 char buf[2048]; |
|
279 va_list argsCpy; |
|
280 va_copy(argsCpy, args); |
|
281 vsnprintf(buf, sizeof(buf), fmt, argsCpy); |
|
282 buf[sizeof(buf) - 1] = '\0'; |
|
283 va_end(argsCpy); |
|
284 OutputDebugStringA(buf); |
|
285 } |
|
286 |
|
287 FILE *fp = _fdopen(_dup(2), "a"); |
|
288 if (!fp) |
|
289 return; |
|
290 |
|
291 vfprintf(fp, fmt, args); |
|
292 |
|
293 fclose(fp); |
|
294 } |
|
295 |
|
296 #undef va_copy |
|
297 |
|
298 #elif defined(ANDROID) |
|
299 void |
|
300 vprintf_stderr(const char *fmt, va_list args) |
|
301 { |
|
302 __android_log_vprint(ANDROID_LOG_INFO, "Gecko", fmt, args); |
|
303 } |
|
304 #else |
|
305 void |
|
306 vprintf_stderr(const char *fmt, va_list args) |
|
307 { |
|
308 vfprintf(stderr, fmt, args); |
|
309 } |
|
310 #endif |
|
311 |
|
312 void |
|
313 printf_stderr(const char *fmt, ...) |
|
314 { |
|
315 va_list args; |
|
316 va_start(args, fmt); |
|
317 vprintf_stderr(fmt, args); |
|
318 va_end(args); |
|
319 } |
|
320 |
|
321 void |
|
322 fprintf_stderr(FILE* aFile, const char *fmt, ...) |
|
323 { |
|
324 va_list args; |
|
325 va_start(args, fmt); |
|
326 if (aFile == stderr) { |
|
327 vprintf_stderr(fmt, args); |
|
328 } else { |
|
329 vfprintf(aFile, fmt, args); |
|
330 } |
|
331 va_end(args); |
|
332 } |
|
333 |
|
334 |