rev |
line source |
nuclear@0
|
1 /************************************************************************************
|
nuclear@0
|
2
|
nuclear@0
|
3 PublicHeader: OVR_Kernel.h
|
nuclear@0
|
4 Filename : OVR_Std.h
|
nuclear@0
|
5 Content : Standard C function interface
|
nuclear@0
|
6 Created : September 19, 2012
|
nuclear@0
|
7 Notes :
|
nuclear@0
|
8
|
nuclear@0
|
9 Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved.
|
nuclear@0
|
10
|
nuclear@0
|
11 Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License");
|
nuclear@0
|
12 you may not use the Oculus VR Rift SDK except in compliance with the License,
|
nuclear@0
|
13 which is provided at the time of installation or download, or which
|
nuclear@0
|
14 otherwise accompanies this software in either electronic or hard copy form.
|
nuclear@0
|
15
|
nuclear@0
|
16 You may obtain a copy of the License at
|
nuclear@0
|
17
|
nuclear@0
|
18 http://www.oculusvr.com/licenses/LICENSE-3.2
|
nuclear@0
|
19
|
nuclear@0
|
20 Unless required by applicable law or agreed to in writing, the Oculus VR SDK
|
nuclear@0
|
21 distributed under the License is distributed on an "AS IS" BASIS,
|
nuclear@0
|
22 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
nuclear@0
|
23 See the License for the specific language governing permissions and
|
nuclear@0
|
24 limitations under the License.
|
nuclear@0
|
25
|
nuclear@0
|
26 ************************************************************************************/
|
nuclear@0
|
27
|
nuclear@0
|
28 #ifndef OVR_Std_h
|
nuclear@0
|
29 #define OVR_Std_h
|
nuclear@0
|
30
|
nuclear@0
|
31 #include "OVR_Types.h"
|
nuclear@0
|
32 #include <stdarg.h> // for va_list args
|
nuclear@0
|
33 #include <string.h>
|
nuclear@0
|
34 #include <stdio.h>
|
nuclear@0
|
35 #include <stdlib.h>
|
nuclear@0
|
36 #include <ctype.h>
|
nuclear@0
|
37
|
nuclear@0
|
38 #if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400)
|
nuclear@0
|
39 #define OVR_MSVC_SAFESTRING
|
nuclear@0
|
40 #include <errno.h>
|
nuclear@0
|
41 #endif
|
nuclear@0
|
42
|
nuclear@0
|
43 // Wide-char funcs
|
nuclear@0
|
44 #include <wchar.h>
|
nuclear@0
|
45 #include <wctype.h>
|
nuclear@0
|
46
|
nuclear@0
|
47 namespace OVR {
|
nuclear@0
|
48
|
nuclear@0
|
49 // Has the same behavior as itoa aside from also having a dest size argument.
|
nuclear@0
|
50 // Return value: Pointer to the resulting null-terminated string, same as parameter str.
|
nuclear@0
|
51 #if defined(OVR_OS_MS)
|
nuclear@0
|
52 inline char* OVR_CDECL OVR_itoa(int val, char *dest, size_t destsize, int radix)
|
nuclear@0
|
53 {
|
nuclear@0
|
54 #if defined(OVR_MSVC_SAFESTRING)
|
nuclear@0
|
55 _itoa_s(val, dest, destsize, radix);
|
nuclear@0
|
56 return dest;
|
nuclear@0
|
57 #else
|
nuclear@0
|
58 OVR_UNUSED(destsize);
|
nuclear@0
|
59 return itoa(val, dest, radix);
|
nuclear@0
|
60 #endif
|
nuclear@0
|
61 }
|
nuclear@0
|
62 #else // OVR_OS_MS
|
nuclear@0
|
63 inline char* OVR_itoa(int val, char* dest, size_t len, int radix)
|
nuclear@0
|
64 {
|
nuclear@0
|
65 if (val == 0)
|
nuclear@0
|
66 {
|
nuclear@0
|
67 if (len > 1)
|
nuclear@0
|
68 {
|
nuclear@0
|
69 dest[0] = '0';
|
nuclear@0
|
70 dest[1] = '\0';
|
nuclear@0
|
71 }
|
nuclear@0
|
72 else if(len > 0)
|
nuclear@0
|
73 dest[0] = '\0';
|
nuclear@0
|
74 return dest;
|
nuclear@0
|
75 }
|
nuclear@0
|
76
|
nuclear@0
|
77 // FIXME: Fix the following code to avoid memory write overruns when len is in sufficient.
|
nuclear@0
|
78 int cur = val;
|
nuclear@0
|
79 size_t i = 0;
|
nuclear@0
|
80 size_t sign = 0;
|
nuclear@0
|
81
|
nuclear@0
|
82 if (val < 0)
|
nuclear@0
|
83 {
|
nuclear@0
|
84 val = -val;
|
nuclear@0
|
85 sign = 1;
|
nuclear@0
|
86 }
|
nuclear@0
|
87
|
nuclear@0
|
88 while ((val != 0) && (i < (len - 1 - sign)))
|
nuclear@0
|
89 {
|
nuclear@0
|
90 cur = val % radix;
|
nuclear@0
|
91 val /= radix;
|
nuclear@0
|
92
|
nuclear@0
|
93 if (radix == 16)
|
nuclear@0
|
94 {
|
nuclear@0
|
95 switch(cur)
|
nuclear@0
|
96 {
|
nuclear@0
|
97 case 10:
|
nuclear@0
|
98 dest[i] = 'a';
|
nuclear@0
|
99 break;
|
nuclear@0
|
100 case 11:
|
nuclear@0
|
101 dest[i] = 'b';
|
nuclear@0
|
102 break;
|
nuclear@0
|
103 case 12:
|
nuclear@0
|
104 dest[i] = 'c';
|
nuclear@0
|
105 break;
|
nuclear@0
|
106 case 13:
|
nuclear@0
|
107 dest[i] = 'd';
|
nuclear@0
|
108 break;
|
nuclear@0
|
109 case 14:
|
nuclear@0
|
110 dest[i] = 'e';
|
nuclear@0
|
111 break;
|
nuclear@0
|
112 case 15:
|
nuclear@0
|
113 dest[i] = 'f';
|
nuclear@0
|
114 break;
|
nuclear@0
|
115 default:
|
nuclear@0
|
116 dest[i] = (char)('0' + cur);
|
nuclear@0
|
117 break;
|
nuclear@0
|
118 }
|
nuclear@0
|
119 }
|
nuclear@0
|
120 else
|
nuclear@0
|
121 {
|
nuclear@0
|
122 dest[i] = (char)('0' + cur);
|
nuclear@0
|
123 }
|
nuclear@0
|
124 ++i;
|
nuclear@0
|
125 }
|
nuclear@0
|
126
|
nuclear@0
|
127 if (sign)
|
nuclear@0
|
128 {
|
nuclear@0
|
129 dest[i++] = '-';
|
nuclear@0
|
130 }
|
nuclear@0
|
131
|
nuclear@0
|
132 for (size_t j = 0; j < i / 2; ++j)
|
nuclear@0
|
133 {
|
nuclear@0
|
134 char tmp = dest[j];
|
nuclear@0
|
135 dest[j] = dest[i - 1 - j];
|
nuclear@0
|
136 dest[i - 1 - j] = tmp;
|
nuclear@0
|
137 }
|
nuclear@0
|
138 dest[i] = '\0';
|
nuclear@0
|
139
|
nuclear@0
|
140 return dest;
|
nuclear@0
|
141 }
|
nuclear@0
|
142
|
nuclear@0
|
143 #endif
|
nuclear@0
|
144
|
nuclear@0
|
145
|
nuclear@0
|
146 // String functions
|
nuclear@0
|
147
|
nuclear@0
|
148 inline size_t OVR_CDECL OVR_strlen(const char* str)
|
nuclear@0
|
149 {
|
nuclear@0
|
150 return strlen(str);
|
nuclear@0
|
151 }
|
nuclear@0
|
152
|
nuclear@0
|
153 inline char* OVR_CDECL OVR_strcpy(char* dest, size_t destsize, const char* src)
|
nuclear@0
|
154 {
|
nuclear@0
|
155 #if defined(OVR_MSVC_SAFESTRING)
|
nuclear@0
|
156 strcpy_s(dest, destsize, src);
|
nuclear@0
|
157 return dest;
|
nuclear@0
|
158 #else
|
nuclear@0
|
159 // FIXME: This should be a safer implementation
|
nuclear@0
|
160 OVR_UNUSED(destsize);
|
nuclear@0
|
161 return strcpy(dest, src);
|
nuclear@0
|
162 #endif
|
nuclear@0
|
163 }
|
nuclear@0
|
164
|
nuclear@0
|
165
|
nuclear@0
|
166 // Acts the same as the strlcpy function.
|
nuclear@0
|
167 // Copies src to dest, 0-terminating even if it involves truncating the write.
|
nuclear@0
|
168 // Returns the required strlen of dest (which is one less than the required size of dest).
|
nuclear@0
|
169 // strlcpy is a safer alternative to strcpy and strncpy and provides size information.
|
nuclear@0
|
170 // However, it still may result in an incomplete copy.
|
nuclear@0
|
171 //
|
nuclear@0
|
172 // Example usage:
|
nuclear@0
|
173 // char buffer[256];
|
nuclear@0
|
174 // if(OVR_strlcpy(buffer, "hello world", sizeof(buffer)) < sizeof(buffer))
|
nuclear@0
|
175 // { there was enough space }
|
nuclear@0
|
176 // else
|
nuclear@0
|
177 // { need a larger buffer }
|
nuclear@0
|
178 //
|
nuclear@0
|
179 size_t OVR_CDECL OVR_strlcpy(char* dest, const char* src, size_t destsize);
|
nuclear@0
|
180
|
nuclear@0
|
181 // Acts the same as the strlcat function.
|
nuclear@0
|
182 // Appends src to dest, 0-terminating even if it involves an incomplete write.
|
nuclear@0
|
183 // Doesn't 0-terminate in the case that destsize is 0.
|
nuclear@0
|
184 // Returns the required strlen of dest (which is one less than the required size of dest).
|
nuclear@0
|
185 // The terminating 0 char of dest is overwritten by the first
|
nuclear@0
|
186 // character of src, and a new 0 char is appended to dest. The required capacity
|
nuclear@0
|
187 // of the destination is (strlen(src) + strlen(dest) + 1).
|
nuclear@0
|
188 // strlcat is a safer alternative to strcat and provides size information.
|
nuclear@0
|
189 // However, it still may result in an incomplete copy.
|
nuclear@0
|
190 //
|
nuclear@0
|
191 // Example usage:
|
nuclear@0
|
192 // char buffer[256] = "hello ";
|
nuclear@0
|
193 // if(OVR_strlcat(buffer, "world", sizeof(buffer)) < sizeof(buffer))
|
nuclear@0
|
194 // { there was enough space }
|
nuclear@0
|
195 // else
|
nuclear@0
|
196 // { need a larger buffer }
|
nuclear@0
|
197 //
|
nuclear@0
|
198 size_t OVR_CDECL OVR_strlcat(char* dest, const char* src, size_t destsize);
|
nuclear@0
|
199
|
nuclear@0
|
200
|
nuclear@0
|
201 inline char* OVR_CDECL OVR_strncpy(char* dest, size_t destsize, const char* src, size_t count)
|
nuclear@0
|
202 {
|
nuclear@0
|
203 #if defined(OVR_MSVC_SAFESTRING)
|
nuclear@0
|
204 strncpy_s(dest, destsize, src, count);
|
nuclear@0
|
205 return dest;
|
nuclear@0
|
206 #else
|
nuclear@0
|
207 // FIXME: This should be a safer implementation
|
nuclear@0
|
208 OVR_UNUSED(destsize);
|
nuclear@0
|
209 return strncpy(dest, src, count);
|
nuclear@0
|
210 #endif
|
nuclear@0
|
211 }
|
nuclear@0
|
212
|
nuclear@0
|
213 inline char * OVR_CDECL OVR_strcat(char* dest, size_t destsize, const char* src)
|
nuclear@0
|
214 {
|
nuclear@0
|
215 #if defined(OVR_MSVC_SAFESTRING)
|
nuclear@0
|
216 strcat_s(dest, destsize, src);
|
nuclear@0
|
217 return dest;
|
nuclear@0
|
218 #else
|
nuclear@0
|
219 // FIXME: This should be a safer implementation
|
nuclear@0
|
220 OVR_UNUSED(destsize);
|
nuclear@0
|
221 return strcat(dest, src);
|
nuclear@0
|
222 #endif
|
nuclear@0
|
223 }
|
nuclear@0
|
224
|
nuclear@0
|
225 inline int OVR_CDECL OVR_strcmp(const char* dest, const char* src)
|
nuclear@0
|
226 {
|
nuclear@0
|
227 return strcmp(dest, src);
|
nuclear@0
|
228 }
|
nuclear@0
|
229
|
nuclear@0
|
230 inline const char* OVR_CDECL OVR_strchr(const char* str, char c)
|
nuclear@0
|
231 {
|
nuclear@0
|
232 return strchr(str, c);
|
nuclear@0
|
233 }
|
nuclear@0
|
234
|
nuclear@0
|
235 inline char* OVR_CDECL OVR_strchr(char* str, char c)
|
nuclear@0
|
236 {
|
nuclear@0
|
237 return strchr(str, c);
|
nuclear@0
|
238 }
|
nuclear@0
|
239
|
nuclear@0
|
240 inline const char* OVR_strrchr(const char* str, char c)
|
nuclear@0
|
241 {
|
nuclear@0
|
242 size_t len = OVR_strlen(str);
|
nuclear@0
|
243 for (size_t i=len; i>0; i--)
|
nuclear@0
|
244 if (str[i]==c)
|
nuclear@0
|
245 return str+i;
|
nuclear@0
|
246 return 0;
|
nuclear@0
|
247 }
|
nuclear@0
|
248
|
nuclear@0
|
249 inline const uint8_t* OVR_CDECL OVR_memrchr(const uint8_t* str, size_t size, uint8_t c)
|
nuclear@0
|
250 {
|
nuclear@0
|
251 for (intptr_t i = (intptr_t)size - 1; i >= 0; i--)
|
nuclear@0
|
252 {
|
nuclear@0
|
253 if (str[i] == c)
|
nuclear@0
|
254 return str + i;
|
nuclear@0
|
255 }
|
nuclear@0
|
256 return 0;
|
nuclear@0
|
257 }
|
nuclear@0
|
258
|
nuclear@0
|
259 inline char* OVR_CDECL OVR_strrchr(char* str, char c)
|
nuclear@0
|
260 {
|
nuclear@0
|
261 size_t len = OVR_strlen(str);
|
nuclear@0
|
262 for (size_t i=len; i>0; i--)
|
nuclear@0
|
263 if (str[i]==c)
|
nuclear@0
|
264 return str+i;
|
nuclear@0
|
265 return 0;
|
nuclear@0
|
266 }
|
nuclear@0
|
267
|
nuclear@0
|
268
|
nuclear@0
|
269 double OVR_CDECL OVR_strtod(const char* string, char** tailptr);
|
nuclear@0
|
270
|
nuclear@0
|
271 inline long OVR_CDECL OVR_strtol(const char* string, char** tailptr, int radix)
|
nuclear@0
|
272 {
|
nuclear@0
|
273 return strtol(string, tailptr, radix);
|
nuclear@0
|
274 }
|
nuclear@0
|
275
|
nuclear@0
|
276 inline long OVR_CDECL OVR_strtoul(const char* string, char** tailptr, int radix)
|
nuclear@0
|
277 {
|
nuclear@0
|
278 return strtoul(string, tailptr, radix);
|
nuclear@0
|
279 }
|
nuclear@0
|
280
|
nuclear@0
|
281 inline int OVR_CDECL OVR_strncmp(const char* ws1, const char* ws2, size_t size)
|
nuclear@0
|
282 {
|
nuclear@0
|
283 return strncmp(ws1, ws2, size);
|
nuclear@0
|
284 }
|
nuclear@0
|
285
|
nuclear@0
|
286 inline uint64_t OVR_CDECL OVR_strtouq(const char *nptr, char **endptr, int base)
|
nuclear@0
|
287 {
|
nuclear@0
|
288 #if defined(OVR_CC_MSVC)
|
nuclear@0
|
289 return _strtoui64(nptr, endptr, base);
|
nuclear@0
|
290 #else
|
nuclear@0
|
291 return strtoull(nptr, endptr, base);
|
nuclear@0
|
292 #endif
|
nuclear@0
|
293 }
|
nuclear@0
|
294
|
nuclear@0
|
295 inline int64_t OVR_CDECL OVR_strtoq(const char *nptr, char **endptr, int base)
|
nuclear@0
|
296 {
|
nuclear@0
|
297 #if defined(OVR_CC_MSVC)
|
nuclear@0
|
298 return _strtoi64(nptr, endptr, base);
|
nuclear@0
|
299 #else
|
nuclear@0
|
300 return strtoll(nptr, endptr, base);
|
nuclear@0
|
301 #endif
|
nuclear@0
|
302 }
|
nuclear@0
|
303
|
nuclear@0
|
304
|
nuclear@0
|
305 inline int64_t OVR_CDECL OVR_atoq(const char* string)
|
nuclear@0
|
306 {
|
nuclear@0
|
307 #if defined(OVR_CC_MSVC)
|
nuclear@0
|
308 return _atoi64(string);
|
nuclear@0
|
309 #else
|
nuclear@0
|
310 return atoll(string);
|
nuclear@0
|
311 #endif
|
nuclear@0
|
312 }
|
nuclear@0
|
313
|
nuclear@0
|
314 inline uint64_t OVR_CDECL OVR_atouq(const char* string)
|
nuclear@0
|
315 {
|
nuclear@0
|
316 return OVR_strtouq(string, NULL, 10);
|
nuclear@0
|
317 }
|
nuclear@0
|
318
|
nuclear@0
|
319
|
nuclear@0
|
320 // Implemented in OVR_Std.cpp in platform-specific manner.
|
nuclear@0
|
321 int OVR_CDECL OVR_stricmp(const char* dest, const char* src);
|
nuclear@0
|
322 int OVR_CDECL OVR_strnicmp(const char* dest, const char* src, size_t count);
|
nuclear@0
|
323
|
nuclear@0
|
324
|
nuclear@0
|
325 // This is like sprintf but with a destination buffer size argument. However, the behavior is different
|
nuclear@0
|
326 // from vsnprintf in that the return value semantics are like sprintf (which returns -1 on capacity overflow) and
|
nuclear@0
|
327 // not like snprintf (which returns intended strlen on capacity overflow).
|
nuclear@0
|
328 inline size_t OVR_CDECL OVR_sprintf(char *dest, size_t destsize, const char* format, ...)
|
nuclear@0
|
329 {
|
nuclear@0
|
330 va_list argList;
|
nuclear@0
|
331 va_start(argList,format);
|
nuclear@0
|
332 size_t ret;
|
nuclear@0
|
333 #if defined(OVR_CC_MSVC)
|
nuclear@0
|
334 #if defined(OVR_MSVC_SAFESTRING)
|
nuclear@0
|
335 ret = _vsnprintf_s(dest, destsize, _TRUNCATE, format, argList);
|
nuclear@0
|
336 OVR_ASSERT(ret != -1);
|
nuclear@0
|
337 #else
|
nuclear@0
|
338 OVR_UNUSED(destsize);
|
nuclear@0
|
339 ret = _vsnprintf(dest, destsize - 1, format, argList); // -1 for space for the null character
|
nuclear@0
|
340 OVR_ASSERT(ret != -1);
|
nuclear@0
|
341 dest[destsize-1] = 0;
|
nuclear@0
|
342 #endif
|
nuclear@0
|
343 #else
|
nuclear@0
|
344 OVR_UNUSED(destsize);
|
nuclear@0
|
345 ret = vsprintf(dest, format, argList);
|
nuclear@0
|
346 OVR_ASSERT(ret < destsize);
|
nuclear@0
|
347 #endif
|
nuclear@0
|
348 va_end(argList);
|
nuclear@0
|
349 return ret;
|
nuclear@0
|
350 }
|
nuclear@0
|
351
|
nuclear@0
|
352
|
nuclear@0
|
353 // This is like vsprintf but with a destination buffer size argument. However, the behavior is different
|
nuclear@0
|
354 // from vsnprintf in that the return value semantics are like vsprintf (which returns -1 on capacity overflow) and
|
nuclear@0
|
355 // not like vsnprintf (which returns intended strlen on capacity overflow).
|
nuclear@0
|
356 // Return value:
|
nuclear@0
|
357 // On success, the total number of characters written is returned.
|
nuclear@0
|
358 // On failure, a negative number is returned.
|
nuclear@0
|
359 inline size_t OVR_CDECL OVR_vsprintf(char *dest, size_t destsize, const char * format, va_list argList)
|
nuclear@0
|
360 {
|
nuclear@0
|
361 size_t ret;
|
nuclear@0
|
362 #if defined(OVR_CC_MSVC)
|
nuclear@0
|
363 #if defined(OVR_MSVC_SAFESTRING)
|
nuclear@0
|
364 dest[0] = '\0';
|
nuclear@0
|
365 int rv = vsnprintf_s(dest, destsize, _TRUNCATE, format, argList);
|
nuclear@0
|
366 if (rv == -1)
|
nuclear@0
|
367 {
|
nuclear@0
|
368 dest[destsize - 1] = '\0';
|
nuclear@0
|
369 ret = destsize - 1;
|
nuclear@0
|
370 }
|
nuclear@0
|
371 else
|
nuclear@0
|
372 ret = (size_t)rv;
|
nuclear@0
|
373 #else
|
nuclear@0
|
374 OVR_UNUSED(destsize);
|
nuclear@0
|
375 int rv = _vsnprintf(dest, destsize - 1, format, argList);
|
nuclear@0
|
376 OVR_ASSERT(rv != -1);
|
nuclear@0
|
377 ret = (size_t)rv;
|
nuclear@0
|
378 dest[destsize-1] = 0;
|
nuclear@0
|
379 #endif
|
nuclear@0
|
380 #else
|
nuclear@0
|
381 // FIXME: This should be a safer implementation
|
nuclear@0
|
382 OVR_UNUSED(destsize);
|
nuclear@0
|
383 ret = (size_t)vsprintf(dest, format, argList);
|
nuclear@0
|
384 OVR_ASSERT(ret < destsize);
|
nuclear@0
|
385 #endif
|
nuclear@0
|
386 return ret;
|
nuclear@0
|
387 }
|
nuclear@0
|
388
|
nuclear@0
|
389 // Same behavior as ISO C99 vsnprintf.
|
nuclear@0
|
390 // Returns the strlen of the resulting formatted string, or a negative value if the format is invalid.
|
nuclear@0
|
391 // destsize specifies the capacity of the input buffer.
|
nuclear@0
|
392 //
|
nuclear@0
|
393 // Example usage:
|
nuclear@0
|
394 // void Log(char *dest, size_t destsize, const char * format, ...)
|
nuclear@0
|
395 // {
|
nuclear@0
|
396 // char buffer[1024];
|
nuclear@0
|
397 // va_list argList;
|
nuclear@0
|
398 // va_start(argList,format);
|
nuclear@0
|
399 // int result = OVR_vsnprintf(dest, destsize, format, argList);
|
nuclear@0
|
400 // assert(result < destsize); // Else we'd have to retry with a dynamically allocated buffer (of size=result+1) and new argList copy.
|
nuclear@0
|
401 // va_end(argList);
|
nuclear@0
|
402 // }
|
nuclear@0
|
403
|
nuclear@0
|
404 inline int OVR_CDECL OVR_vsnprintf(char *dest, size_t destsize, const char * format, va_list argList)
|
nuclear@0
|
405 {
|
nuclear@0
|
406 int ret;
|
nuclear@0
|
407 #if defined(OVR_CC_MSVC)
|
nuclear@0
|
408 OVR_DISABLE_MSVC_WARNING(4996) // 'vsnprintf': This function or variable may be unsafe.
|
nuclear@0
|
409 ret = vsnprintf(dest, destsize, format, argList); // Microsoft vsnprintf is non-conforming; it returns -1 if destsize is insufficient.
|
nuclear@0
|
410 if (ret < 0) // If there was a format error or if destsize was insufficient...
|
nuclear@0
|
411 {
|
nuclear@0
|
412 ret = _vscprintf(format, argList); // Get the expected dest strlen. If the return value is still -1 then there was a format error.
|
nuclear@0
|
413
|
nuclear@0
|
414 if (destsize) // If we can 0-terminate the output...
|
nuclear@0
|
415 {
|
nuclear@0
|
416 if (ret < 0)
|
nuclear@0
|
417 dest[0] = 0;
|
nuclear@0
|
418 else
|
nuclear@0
|
419 dest[destsize-1] = 0;
|
nuclear@0
|
420 }
|
nuclear@0
|
421 }
|
nuclear@0
|
422 // Else the string was written OK and ret is its strlen.
|
nuclear@0
|
423 OVR_RESTORE_MSVC_WARNING()
|
nuclear@0
|
424 #else
|
nuclear@0
|
425 ret = vsnprintf(dest, destsize, format, argList);
|
nuclear@0
|
426 #endif
|
nuclear@0
|
427 return ret;
|
nuclear@0
|
428 }
|
nuclear@0
|
429
|
nuclear@0
|
430
|
nuclear@0
|
431 // Same behavior as ISO C99 snprintf.
|
nuclear@0
|
432 // Returns the strlen of the resulting formatted string, or a negative value if the format is invalid.
|
nuclear@0
|
433 // destsize specifies the capacity of the input buffer.
|
nuclear@0
|
434 //
|
nuclear@0
|
435 // Example usage:
|
nuclear@0
|
436 // char buffer[16];
|
nuclear@0
|
437 // int result = OVR_snprintf(buffer, sizeof(buffer), "%d", 37);
|
nuclear@0
|
438 // if (result >= sizeof(buffer)) // If there was insufficient capacity...
|
nuclear@0
|
439 // {
|
nuclear@0
|
440 // char* p = new char[result + 1]; // Or char* p = (char*)OVR_ALLOC(result + 1);
|
nuclear@0
|
441 // OVR_snprintf(p, (size_t)result, "%d", 37);
|
nuclear@0
|
442 // delete[] p;
|
nuclear@0
|
443 // }
|
nuclear@0
|
444 //
|
nuclear@0
|
445 inline int OVR_CDECL OVR_snprintf(char *dest, size_t destsize, const char * format, ...)
|
nuclear@0
|
446 {
|
nuclear@0
|
447 va_list argList;
|
nuclear@0
|
448 va_start(argList,format);
|
nuclear@0
|
449 int ret = OVR_vsnprintf(dest, destsize, format, argList);
|
nuclear@0
|
450 va_end(argList);
|
nuclear@0
|
451 return ret;
|
nuclear@0
|
452 }
|
nuclear@0
|
453
|
nuclear@0
|
454
|
nuclear@0
|
455 // Returns the strlen of the resulting formatted string, or a negative value if the format is invalid.
|
nuclear@0
|
456 // Note: If you are planning on printing a string then it's more efficient to just use OVR_vsnprintf and
|
nuclear@0
|
457 // look at the return value and handle the uncommon case that there wasn't enough space.
|
nuclear@0
|
458 inline int OVR_CDECL OVR_vscprintf(const char * format, va_list argList)
|
nuclear@0
|
459 {
|
nuclear@0
|
460 int ret;
|
nuclear@0
|
461 #if defined(OVR_CC_MSVC)
|
nuclear@0
|
462 ret = _vscprintf(format, argList);
|
nuclear@0
|
463 #else
|
nuclear@0
|
464 ret = vsnprintf(NULL, 0, format, argList);
|
nuclear@0
|
465 #endif
|
nuclear@0
|
466 return ret;
|
nuclear@0
|
467 }
|
nuclear@0
|
468
|
nuclear@0
|
469
|
nuclear@0
|
470 wchar_t* OVR_CDECL OVR_wcscpy(wchar_t* dest, size_t destsize, const wchar_t* src);
|
nuclear@0
|
471 wchar_t* OVR_CDECL OVR_wcsncpy(wchar_t* dest, size_t destsize, const wchar_t* src, size_t count);
|
nuclear@0
|
472 wchar_t* OVR_CDECL OVR_wcscat(wchar_t* dest, size_t destsize, const wchar_t* src);
|
nuclear@0
|
473 size_t OVR_CDECL OVR_wcslen(const wchar_t* str);
|
nuclear@0
|
474 int OVR_CDECL OVR_wcscmp(const wchar_t* a, const wchar_t* b);
|
nuclear@0
|
475 int OVR_CDECL OVR_wcsicmp(const wchar_t* a, const wchar_t* b);
|
nuclear@0
|
476
|
nuclear@0
|
477 inline int OVR_CDECL OVR_wcsicoll(const wchar_t* a, const wchar_t* b)
|
nuclear@0
|
478 {
|
nuclear@0
|
479 #if defined(OVR_OS_MS)
|
nuclear@0
|
480 #if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400)
|
nuclear@0
|
481 return ::_wcsicoll(a, b);
|
nuclear@0
|
482 #else
|
nuclear@0
|
483 return ::wcsicoll(a, b);
|
nuclear@0
|
484 #endif
|
nuclear@0
|
485 #else
|
nuclear@0
|
486 // not supported, use regular wcsicmp
|
nuclear@0
|
487 return OVR_wcsicmp(a, b);
|
nuclear@0
|
488 #endif
|
nuclear@0
|
489 }
|
nuclear@0
|
490
|
nuclear@0
|
491 inline int OVR_CDECL OVR_wcscoll(const wchar_t* a, const wchar_t* b)
|
nuclear@0
|
492 {
|
nuclear@0
|
493 #if defined(OVR_OS_MS) || defined(OVR_OS_LINUX)
|
nuclear@0
|
494 return wcscoll(a, b);
|
nuclear@0
|
495 #else
|
nuclear@0
|
496 // not supported, use regular wcscmp
|
nuclear@0
|
497 return OVR_wcscmp(a, b);
|
nuclear@0
|
498 #endif
|
nuclear@0
|
499 }
|
nuclear@0
|
500
|
nuclear@0
|
501 #ifndef OVR_NO_WCTYPE
|
nuclear@0
|
502
|
nuclear@0
|
503 inline int OVR_CDECL UnicodeCharIs(const uint16_t* table, wchar_t charCode)
|
nuclear@0
|
504 {
|
nuclear@0
|
505 unsigned offset = table[charCode >> 8];
|
nuclear@0
|
506 if (offset == 0) return 0;
|
nuclear@0
|
507 if (offset == 1) return 1;
|
nuclear@0
|
508 return (table[offset + ((charCode >> 4) & 15)] & (1 << (charCode & 15))) != 0;
|
nuclear@0
|
509 }
|
nuclear@0
|
510
|
nuclear@0
|
511 extern const uint16_t UnicodeAlnumBits[];
|
nuclear@0
|
512 extern const uint16_t UnicodeAlphaBits[];
|
nuclear@0
|
513 extern const uint16_t UnicodeDigitBits[];
|
nuclear@0
|
514 extern const uint16_t UnicodeSpaceBits[];
|
nuclear@0
|
515 extern const uint16_t UnicodeXDigitBits[];
|
nuclear@0
|
516
|
nuclear@0
|
517 // Uncomment if necessary
|
nuclear@0
|
518 //extern const uint16_t UnicodeCntrlBits[];
|
nuclear@0
|
519 //extern const uint16_t UnicodeGraphBits[];
|
nuclear@0
|
520 //extern const uint16_t UnicodeLowerBits[];
|
nuclear@0
|
521 //extern const uint16_t UnicodePrintBits[];
|
nuclear@0
|
522 //extern const uint16_t UnicodePunctBits[];
|
nuclear@0
|
523 //extern const uint16_t UnicodeUpperBits[];
|
nuclear@0
|
524
|
nuclear@0
|
525 inline int OVR_CDECL OVR_iswalnum (wchar_t charCode) { return UnicodeCharIs(UnicodeAlnumBits, charCode); }
|
nuclear@0
|
526 inline int OVR_CDECL OVR_iswalpha (wchar_t charCode) { return UnicodeCharIs(UnicodeAlphaBits, charCode); }
|
nuclear@0
|
527 inline int OVR_CDECL OVR_iswdigit (wchar_t charCode) { return UnicodeCharIs(UnicodeDigitBits, charCode); }
|
nuclear@0
|
528 inline int OVR_CDECL OVR_iswspace (wchar_t charCode) { return UnicodeCharIs(UnicodeSpaceBits, charCode); }
|
nuclear@0
|
529 inline int OVR_CDECL OVR_iswxdigit(wchar_t charCode) { return UnicodeCharIs(UnicodeXDigitBits, charCode); }
|
nuclear@0
|
530
|
nuclear@0
|
531 // Uncomment if necessary
|
nuclear@0
|
532 //inline int OVR_CDECL OVR_iswcntrl (wchar_t charCode) { return UnicodeCharIs(UnicodeCntrlBits, charCode); }
|
nuclear@0
|
533 //inline int OVR_CDECL OVR_iswgraph (wchar_t charCode) { return UnicodeCharIs(UnicodeGraphBits, charCode); }
|
nuclear@0
|
534 //inline int OVR_CDECL OVR_iswlower (wchar_t charCode) { return UnicodeCharIs(UnicodeLowerBits, charCode); }
|
nuclear@0
|
535 //inline int OVR_CDECL OVR_iswprint (wchar_t charCode) { return UnicodeCharIs(UnicodePrintBits, charCode); }
|
nuclear@0
|
536 //inline int OVR_CDECL OVR_iswpunct (wchar_t charCode) { return UnicodeCharIs(UnicodePunctBits, charCode); }
|
nuclear@0
|
537 //inline int OVR_CDECL OVR_iswupper (wchar_t charCode) { return UnicodeCharIs(UnicodeUpperBits, charCode); }
|
nuclear@0
|
538
|
nuclear@0
|
539 int OVR_CDECL OVR_towupper(wchar_t charCode);
|
nuclear@0
|
540 int OVR_CDECL OVR_towlower(wchar_t charCode);
|
nuclear@0
|
541
|
nuclear@0
|
542 #else // OVR_NO_WCTYPE
|
nuclear@0
|
543
|
nuclear@0
|
544 inline int OVR_CDECL OVR_iswspace(wchar_t c)
|
nuclear@0
|
545 {
|
nuclear@0
|
546 return iswspace(c);
|
nuclear@0
|
547 }
|
nuclear@0
|
548
|
nuclear@0
|
549 inline int OVR_CDECL OVR_iswdigit(wchar_t c)
|
nuclear@0
|
550 {
|
nuclear@0
|
551 return iswdigit(c);
|
nuclear@0
|
552 }
|
nuclear@0
|
553
|
nuclear@0
|
554 inline int OVR_CDECL OVR_iswxdigit(wchar_t c)
|
nuclear@0
|
555 {
|
nuclear@0
|
556 return iswxdigit(c);
|
nuclear@0
|
557 }
|
nuclear@0
|
558
|
nuclear@0
|
559 inline int OVR_CDECL OVR_iswalpha(wchar_t c)
|
nuclear@0
|
560 {
|
nuclear@0
|
561 return iswalpha(c);
|
nuclear@0
|
562 }
|
nuclear@0
|
563
|
nuclear@0
|
564 inline int OVR_CDECL OVR_iswalnum(wchar_t c)
|
nuclear@0
|
565 {
|
nuclear@0
|
566 return iswalnum(c);
|
nuclear@0
|
567 }
|
nuclear@0
|
568
|
nuclear@0
|
569 inline wchar_t OVR_CDECL OVR_towlower(wchar_t c)
|
nuclear@0
|
570 {
|
nuclear@0
|
571 return (wchar_t)towlower(c);
|
nuclear@0
|
572 }
|
nuclear@0
|
573
|
nuclear@0
|
574 inline wchar_t OVR_towupper(wchar_t c)
|
nuclear@0
|
575 {
|
nuclear@0
|
576 return (wchar_t)towupper(c);
|
nuclear@0
|
577 }
|
nuclear@0
|
578
|
nuclear@0
|
579 #endif // OVR_NO_WCTYPE
|
nuclear@0
|
580
|
nuclear@0
|
581 // ASCII versions of tolower and toupper. Don't use "char"
|
nuclear@0
|
582 inline int OVR_CDECL OVR_tolower(int c)
|
nuclear@0
|
583 {
|
nuclear@0
|
584 return (c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c;
|
nuclear@0
|
585 }
|
nuclear@0
|
586
|
nuclear@0
|
587 inline int OVR_CDECL OVR_toupper(int c)
|
nuclear@0
|
588 {
|
nuclear@0
|
589 return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c;
|
nuclear@0
|
590 }
|
nuclear@0
|
591
|
nuclear@0
|
592
|
nuclear@0
|
593
|
nuclear@0
|
594 inline double OVR_CDECL OVR_wcstod(const wchar_t* string, wchar_t** tailptr)
|
nuclear@0
|
595 {
|
nuclear@0
|
596 #if defined(OVR_OS_OTHER)
|
nuclear@0
|
597 OVR_UNUSED(tailptr);
|
nuclear@0
|
598 char buffer[64];
|
nuclear@0
|
599 char* tp = NULL;
|
nuclear@0
|
600 size_t max = OVR_wcslen(string);
|
nuclear@0
|
601 if (max > 63) max = 63;
|
nuclear@0
|
602 unsigned char c = 0;
|
nuclear@0
|
603 for (size_t i=0; i < max; i++)
|
nuclear@0
|
604 {
|
nuclear@0
|
605 c = (unsigned char)string[i];
|
nuclear@0
|
606 buffer[i] = ((c) < 128 ? (char)c : '!');
|
nuclear@0
|
607 }
|
nuclear@0
|
608 buffer[max] = 0;
|
nuclear@0
|
609 return OVR_strtod(buffer, &tp);
|
nuclear@0
|
610 #else
|
nuclear@0
|
611 return wcstod(string, tailptr);
|
nuclear@0
|
612 #endif
|
nuclear@0
|
613 }
|
nuclear@0
|
614
|
nuclear@0
|
615 inline long OVR_CDECL OVR_wcstol(const wchar_t* string, wchar_t** tailptr, int radix)
|
nuclear@0
|
616 {
|
nuclear@0
|
617 #if defined(OVR_OS_OTHER)
|
nuclear@0
|
618 OVR_UNUSED(tailptr);
|
nuclear@0
|
619 char buffer[64];
|
nuclear@0
|
620 char* tp = NULL;
|
nuclear@0
|
621 size_t max = OVR_wcslen(string);
|
nuclear@0
|
622 if (max > 63) max = 63;
|
nuclear@0
|
623 unsigned char c = 0;
|
nuclear@0
|
624 for (size_t i=0; i < max; i++)
|
nuclear@0
|
625 {
|
nuclear@0
|
626 c = (unsigned char)string[i];
|
nuclear@0
|
627 buffer[i] = ((c) < 128 ? (char)c : '!');
|
nuclear@0
|
628 }
|
nuclear@0
|
629 buffer[max] = 0;
|
nuclear@0
|
630 return strtol(buffer, &tp, radix);
|
nuclear@0
|
631 #else
|
nuclear@0
|
632 return wcstol(string, tailptr, radix);
|
nuclear@0
|
633 #endif
|
nuclear@0
|
634 }
|
nuclear@0
|
635
|
nuclear@0
|
636 } // OVR
|
nuclear@0
|
637
|
nuclear@0
|
638 #endif // OVR_Std_h
|