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