1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
17 #include "mozilla/Sprintf.h"
22 # include "mozilla/LateWriteChecks.h"
23 # include "mozilla/UniquePtr.h"
27 # include <android/log.h>
30 using namespace mozilla
;
32 const char* NS_strspnp(const char* aDelims
, const char* aStr
) {
35 for (d
= aDelims
; *d
!= '\0'; ++d
) {
46 char* NS_strtok(const char* aDelims
, char** aStr
) {
51 char* ret
= (char*)NS_strspnp(aDelims
, *aStr
);
60 for (const char* d
= aDelims
; *d
!= '\0'; ++d
) {
74 uint32_t NS_strlen(const char16_t
* aString
) {
78 for (end
= aString
; *end
; ++end
) {
85 int NS_strcmp(const char16_t
* aStrA
, const char16_t
* aStrB
) {
87 int r
= *aStrA
- *aStrB
;
96 return *aStrA
!= '\0';
99 int NS_strncmp(const char16_t
* aStrA
, const char16_t
* aStrB
, size_t aLen
) {
100 while (aLen
&& *aStrB
) {
101 int r
= *aStrA
- *aStrB
;
111 return aLen
? *aStrA
!= '\0' : 0;
114 char16_t
* NS_xstrdup(const char16_t
* aString
) {
115 uint32_t len
= NS_strlen(aString
);
116 return NS_xstrndup(aString
, len
);
119 template <typename CharT
>
120 CharT
* NS_xstrndup(const CharT
* aString
, uint32_t aLen
) {
121 auto newBuf
= (CharT
*)moz_xmalloc((aLen
+ 1) * sizeof(CharT
));
122 memcpy(newBuf
, aString
, aLen
* sizeof(CharT
));
127 template char16_t
* NS_xstrndup
<char16_t
>(const char16_t
* aString
,
129 template char* NS_xstrndup
<char>(const char* aString
, uint32_t aLen
);
131 char* NS_xstrdup(const char* aString
) {
132 uint32_t len
= strlen(aString
);
133 char* str
= (char*)moz_xmalloc(len
+ 1);
134 memcpy(str
, aString
, len
);
141 // This table maps uppercase characters to lower case characters;
142 // characters that are neither upper nor lower case are unaffected.
143 const unsigned char nsLowerUpperUtils::kUpper2Lower
[256] = {
144 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
145 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
146 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
147 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
150 // upper band mapped to lower [A-Z] => [a-z]
151 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
152 112,113,114,115,116,117,118,119,120,121,122,
155 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
156 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
157 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
158 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
159 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
160 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
161 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
162 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
163 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
164 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
167 const unsigned char nsLowerUpperUtils::kLower2Upper
[256] = {
168 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
169 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
170 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
171 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
172 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
173 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
176 // lower band mapped to upper [a-z] => [A-Z]
177 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
178 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
181 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
182 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
183 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
184 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
185 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
186 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
187 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
188 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
193 bool NS_IsUpper(char aChar
) {
194 return aChar
!= (char)nsLowerUpperUtils::kUpper2Lower
[(unsigned char)aChar
];
197 bool NS_IsLower(char aChar
) {
198 return aChar
!= (char)nsLowerUpperUtils::kLower2Upper
[(unsigned char)aChar
];
201 #ifndef XPCOM_GLUE_AVOID_NSPR
203 void NS_MakeRandomString(char* aBuf
, int32_t aBufLen
) {
204 # define TABLE_SIZE 36
205 static const char table
[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
206 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
207 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0',
208 '1', '2', '3', '4', '5', '6', '7', '8', '9'};
210 // turn PR_Now() into milliseconds since epoch
211 // and salt rand with that.
212 static unsigned int seed
= 0;
214 double fpTime
= double(PR_Now());
216 (unsigned int)(fpTime
* 1e-6 + 0.5); // use 1e-6, granularity of
217 // PR_Now() on the mac is seconds
222 for (i
= 0; i
< aBufLen
; ++i
) {
223 *aBuf
++ = table
[rand() % TABLE_SIZE
];
231 # define VARARGS_ASSIGN(foo, bar) VA_COPY(foo, bar)
232 #elif defined(HAVE_VA_LIST_AS_ARRAY)
233 # define VARARGS_ASSIGN(foo, bar) foo[0] = bar[0]
235 # define VARARGS_ASSIGN(foo, bar) (foo) = (bar)
239 void vprintf_stderr(const char* aFmt
, va_list aArgs
) {
240 if (IsDebuggerPresent()) {
241 int lengthNeeded
= _vscprintf(aFmt
, aArgs
);
244 auto buf
= MakeUnique
<char[]>(lengthNeeded
);
247 VARARGS_ASSIGN(argsCpy
, aArgs
);
248 vsnprintf(buf
.get(), lengthNeeded
, aFmt
, argsCpy
);
249 buf
[lengthNeeded
- 1] = '\0';
251 OutputDebugStringA(buf
.get());
256 FILE* fp
= _fdopen(_dup(2), "a");
261 vfprintf(fp
, aFmt
, aArgs
);
263 AutoSuspendLateWriteChecks suspend
;
267 #elif defined(ANDROID)
268 void vprintf_stderr(const char* aFmt
, va_list aArgs
) {
269 __android_log_vprint(ANDROID_LOG_INFO
, "Gecko", aFmt
, aArgs
);
272 void vprintf_stderr(const char* aFmt
, va_list aArgs
) {
273 vfprintf(stderr
, aFmt
, aArgs
);
277 void printf_stderr(const char* aFmt
, ...) {
279 va_start(args
, aFmt
);
280 vprintf_stderr(aFmt
, args
);
284 void fprintf_stderr(FILE* aFile
, const char* aFmt
, ...) {
286 va_start(args
, aFmt
);
287 if (aFile
== stderr
) {
288 vprintf_stderr(aFmt
, args
);
290 vfprintf(aFile
, aFmt
, args
);
295 void print_stderr(std::stringstream
& aStr
) {
297 // On Android logcat output is truncated to 1024 chars per line, and
298 // we usually use std::stringstream to build up giant multi-line gobs
299 // of output. So to avoid the truncation we find the newlines and
300 // print the lines individually.
302 while (std::getline(aStr
, line
)) {
303 printf_stderr("%s\n", line
.c_str());
306 printf_stderr("%s", aStr
.str().c_str());
310 void fprint_stderr(FILE* aFile
, std::stringstream
& aStr
) {
311 if (aFile
== stderr
) {
314 fprintf_stderr(aFile
, "%s", aStr
.str().c_str());