This repository has been archived by the owner on Feb 11, 2021. It is now read-only.
/
SDL_string.c
1442 lines (1330 loc) · 35.8 KB
1
2
/*
SDL - Simple DirectMedia Layer
3
Copyright (C) 1997-2011 Sam Lantinga
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
22
#include "SDL_config.h"
23
24
25
/* This file contains portable string manipulation functions for SDL */
26
#include "SDL_stdinc.h"
27
28
29
30
#define SDL_isupperhex(X) (((X) >= 'A') && ((X) <= 'F'))
#define SDL_islowerhex(X) (((X) >= 'a') && ((X) <= 'f'))
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#define UTF8_IsLeadByte(c) ((c) >= 0xC0 && (c) <= 0xF4)
#define UTF8_IsTrailingByte(c) ((c) >= 0x80 && (c) <= 0xBF)
int UTF8_TrailingBytes(unsigned char c)
{
if (c >= 0xC0 && c<= 0xDF)
return 1;
else if (c >= 0xE0 && c <= 0xEF)
return 2;
else if (c >= 0xF0 && c <= 0xF4)
return 3;
else
return 0;
}
47
#if !defined(HAVE_SSCANF) || !defined(HAVE_STRTOL)
48
49
static size_t
SDL_ScanLong(const char *text, int radix, long *valuep)
50
51
52
53
54
{
const char *textstart = text;
long value = 0;
SDL_bool negative = SDL_FALSE;
55
if (*text == '-') {
56
57
58
negative = SDL_TRUE;
++text;
}
59
if (radix == 16 && SDL_strncmp(text, "0x", 2) == 0) {
60
61
text += 2;
}
62
for (;;) {
63
int v;
64
if (SDL_isdigit((unsigned char) *text)) {
65
v = *text - '0';
66
} else if (radix == 16 && SDL_isupperhex(*text)) {
67
v = 10 + (*text - 'A');
68
} else if (radix == 16 && SDL_islowerhex(*text)) {
69
70
71
72
73
74
75
76
v = 10 + (*text - 'a');
} else {
break;
}
value *= radix;
value += v;
++text;
}
77
78
if (valuep) {
if (negative && value) {
79
80
81
82
83
84
85
86
87
*valuep = -value;
} else {
*valuep = value;
}
}
return (text - textstart);
}
#endif
88
#if !defined(HAVE_SSCANF) || !defined(HAVE_STRTOUL) || !defined(HAVE_STRTOD)
89
90
static size_t
SDL_ScanUnsignedLong(const char *text, int radix, unsigned long *valuep)
91
92
93
94
{
const char *textstart = text;
unsigned long value = 0;
95
if (radix == 16 && SDL_strncmp(text, "0x", 2) == 0) {
96
97
text += 2;
}
98
for (;;) {
99
int v;
100
if (SDL_isdigit((unsigned char) *text)) {
101
v = *text - '0';
102
} else if (radix == 16 && SDL_isupperhex(*text)) {
103
v = 10 + (*text - 'A');
104
} else if (radix == 16 && SDL_islowerhex(*text)) {
105
106
107
108
109
110
111
112
v = 10 + (*text - 'a');
} else {
break;
}
value *= radix;
value += v;
++text;
}
113
if (valuep) {
114
115
116
117
118
119
*valuep = value;
}
return (text - textstart);
}
#endif
120
#ifndef HAVE_SSCANF
121
122
static size_t
SDL_ScanUintPtrT(const char *text, int radix, uintptr_t * valuep)
123
124
125
126
{
const char *textstart = text;
uintptr_t value = 0;
127
if (radix == 16 && SDL_strncmp(text, "0x", 2) == 0) {
128
129
text += 2;
}
130
for (;;) {
131
int v;
132
if (SDL_isdigit((unsigned char) *text)) {
133
v = *text - '0';
134
} else if (radix == 16 && SDL_isupperhex(*text)) {
135
v = 10 + (*text - 'A');
136
} else if (radix == 16 && SDL_islowerhex(*text)) {
137
138
139
140
141
142
143
144
v = 10 + (*text - 'a');
} else {
break;
}
value *= radix;
value += v;
++text;
}
145
if (valuep) {
146
147
148
149
150
151
*valuep = value;
}
return (text - textstart);
}
#endif
152
153
#ifdef SDL_HAS_64BIT_TYPE
#if !defined(HAVE_SSCANF) || !defined(HAVE_STRTOLL)
154
155
static size_t
SDL_ScanLongLong(const char *text, int radix, Sint64 * valuep)
156
157
158
159
160
{
const char *textstart = text;
Sint64 value = 0;
SDL_bool negative = SDL_FALSE;
161
if (*text == '-') {
162
163
164
negative = SDL_TRUE;
++text;
}
165
if (radix == 16 && SDL_strncmp(text, "0x", 2) == 0) {
166
167
text += 2;
}
168
for (;;) {
169
int v;
170
if (SDL_isdigit((unsigned char) *text)) {
171
v = *text - '0';
172
} else if (radix == 16 && SDL_isupperhex(*text)) {
173
v = 10 + (*text - 'A');
174
} else if (radix == 16 && SDL_islowerhex(*text)) {
175
176
177
178
179
180
181
182
v = 10 + (*text - 'a');
} else {
break;
}
value *= radix;
value += v;
++text;
}
183
184
if (valuep) {
if (negative && value) {
185
186
187
188
189
190
191
192
193
*valuep = -value;
} else {
*valuep = value;
}
}
return (text - textstart);
}
#endif
194
#if !defined(HAVE_SSCANF) || !defined(HAVE_STRTOULL)
195
196
static size_t
SDL_ScanUnsignedLongLong(const char *text, int radix, Uint64 * valuep)
197
198
199
200
{
const char *textstart = text;
Uint64 value = 0;
201
if (radix == 16 && SDL_strncmp(text, "0x", 2) == 0) {
202
203
text += 2;
}
204
for (;;) {
205
int v;
206
if (SDL_isdigit((unsigned char) *text)) {
207
v = *text - '0';
208
} else if (radix == 16 && SDL_isupperhex(*text)) {
209
v = 10 + (*text - 'A');
210
} else if (radix == 16 && SDL_islowerhex(*text)) {
211
212
213
214
215
216
217
218
v = 10 + (*text - 'a');
} else {
break;
}
value *= radix;
value += v;
++text;
}
219
if (valuep) {
220
221
222
223
224
225
226
*valuep = value;
}
return (text - textstart);
}
#endif
#endif /* SDL_HAS_64BIT_TYPE */
227
#if !defined(HAVE_SSCANF) || !defined(HAVE_STRTOD)
228
229
static size_t
SDL_ScanFloat(const char *text, double *valuep)
230
231
232
233
234
235
{
const char *textstart = text;
unsigned long lvalue = 0;
double value = 0.0;
SDL_bool negative = SDL_FALSE;
236
if (*text == '-') {
237
238
239
240
241
negative = SDL_TRUE;
++text;
}
text += SDL_ScanUnsignedLong(text, 10, &lvalue);
value += lvalue;
242
if (*text == '.') {
243
244
int mult = 10;
++text;
245
while (SDL_isdigit((unsigned char) *text)) {
246
lvalue = *text - '0';
247
value += (double) lvalue / mult;
248
249
250
251
mult *= 10;
++text;
}
}
252
253
if (valuep) {
if (negative && value) {
254
255
256
257
258
259
260
261
262
263
*valuep = -value;
} else {
*valuep = value;
}
}
return (text - textstart);
}
#endif
#ifndef SDL_memset
264
265
void *
SDL_memset(void *dst, int c, size_t len)
266
267
{
size_t left = (len % 4);
268
269
270
271
272
273
274
275
276
Uint32 *dstp4;
Uint8 *dstp1;
Uint32 value4 = (c | (c << 8) | (c << 16) | (c << 24));
Uint8 value1 = (Uint8) c;
dstp4 = (Uint32 *) dst;
len /= 4;
while (len--) {
*dstp4++ = value4;
277
}
278
279
280
281
282
283
284
285
286
dstp1 = (Uint8 *) dstp4;
switch (left) {
case 3:
*dstp1++ = value1;
case 2:
*dstp1++ = value1;
case 1:
*dstp1++ = value1;
287
}
288
289
290
291
292
293
return dst;
}
#endif
#ifndef SDL_memcpy
294
295
void *
SDL_memcpy(void *dst, const void *src, size_t len)
296
{
297
298
299
300
301
302
303
size_t left = (len % 4);
Uint32 *srcp4, *dstp4;
Uint8 *srcp1, *dstp1;
srcp4 = (Uint32 *) src;
dstp4 = (Uint32 *) dst;
len /= 4;
304
while (len--) {
305
306
307
308
309
310
311
312
313
314
315
316
*dstp4++ = *srcp4++;
}
srcp1 = (Uint8 *) srcp4;
dstp1 = (Uint8 *) dstp4;
switch (left) {
case 3:
*dstp1++ = *srcp1++;
case 2:
*dstp1++ = *srcp1++;
case 1:
*dstp1++ = *srcp1++;
317
}
318
319
320
321
322
return dst;
}
#endif
323
#ifndef SDL_memmove
324
void *
325
SDL_memmove(void *dst, const void *src, size_t len)
326
{
327
328
char *srcp = (char *) src;
char *dstp = (char *) dst;
329
330
331
332
333
334
335
336
337
338
339
if (src < dst) {
srcp += len - 1;
dstp += len - 1;
while (len--) {
*dstp-- = *srcp--;
}
} else {
while (len--) {
*dstp++ = *srcp++;
}
340
341
342
343
344
345
}
return dst;
}
#endif
#ifndef SDL_memcmp
346
347
int
SDL_memcmp(const void *s1, const void *s2, size_t len)
348
{
349
350
351
352
char *s1p = (char *) s1;
char *s2p = (char *) s2;
while (len--) {
if (*s1p != *s2p) {
353
return (*s1p - *s2p);
354
355
356
}
++s1p;
++s2p;
357
358
359
360
361
362
}
return 0;
}
#endif
#ifndef HAVE_STRLEN
363
364
size_t
SDL_strlen(const char *string)
365
366
{
size_t len = 0;
367
while (*string++) {
368
369
370
371
372
373
++len;
}
return len;
}
#endif
374
375
#ifndef HAVE_WCSLEN
size_t
376
SDL_wcslen(const wchar_t * string)
377
378
379
380
381
382
383
384
385
{
size_t len = 0;
while (*string++) {
++len;
}
return len;
}
#endif
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
#ifndef HAVE_WCSLCPY
size_t
SDL_wcslcpy(wchar_t *dst, const wchar_t *src, size_t maxlen)
{
size_t srclen = SDL_wcslen(src);
if (maxlen > 0) {
size_t len = SDL_min(srclen, maxlen - 1);
SDL_memcpy(dst, src, len * sizeof(wchar_t));
dst[len] = '\0';
}
return srclen;
}
#endif
#ifndef HAVE_WCSLCAT
size_t
SDL_wcslcat(wchar_t *dst, const wchar_t *src, size_t maxlen)
{
size_t dstlen = SDL_wcslen(dst);
size_t srclen = SDL_wcslen(src);
if (dstlen < maxlen) {
SDL_wcslcpy(dst + dstlen, src, maxlen - dstlen);
}
return dstlen + srclen;
}
#endif
413
#ifndef HAVE_STRLCPY
414
415
size_t
SDL_strlcpy(char *dst, const char *src, size_t maxlen)
416
{
417
size_t srclen = SDL_strlen(src);
418
419
if (maxlen > 0) {
size_t len = SDL_min(srclen, maxlen - 1);
420
421
SDL_memcpy(dst, src, len);
dst[len] = '\0';
422
}
423
return srclen;
424
425
426
}
#endif
427
428
429
430
size_t SDL_utf8strlcpy(char *dst, const char *src, size_t dst_bytes)
{
size_t src_bytes = SDL_strlen(src);
size_t bytes = SDL_min(src_bytes, dst_bytes - 1);
431
size_t i = 0;
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
char trailing_bytes = 0;
if (bytes)
{
unsigned char c = (unsigned char)src[bytes - 1];
if (UTF8_IsLeadByte(c))
--bytes;
else if (UTF8_IsTrailingByte(c))
{
for (i = bytes - 1; i != 0; --i)
{
c = (unsigned char)src[i];
trailing_bytes = UTF8_TrailingBytes(c);
if (trailing_bytes)
{
if (bytes - i != trailing_bytes + 1)
bytes = i;
break;
}
}
}
SDL_memcpy(dst, src, bytes);
}
dst[bytes] = '\0';
return bytes;
}
459
#ifndef HAVE_STRLCAT
460
461
size_t
SDL_strlcat(char *dst, const char *src, size_t maxlen)
462
{
463
464
size_t dstlen = SDL_strlen(dst);
size_t srclen = SDL_strlen(src);
465
466
if (dstlen < maxlen) {
SDL_strlcpy(dst + dstlen, src, maxlen - dstlen);
467
}
468
return dstlen + srclen;
469
470
471
}
#endif
472
#ifndef HAVE_STRDUP
473
474
char *
SDL_strdup(const char *string)
475
{
476
size_t len = SDL_strlen(string) + 1;
477
char *newstr = SDL_malloc(len);
478
if (newstr) {
479
SDL_strlcpy(newstr, string, len);
480
481
482
483
484
}
return newstr;
}
#endif
485
#ifndef HAVE__STRREV
486
487
char *
SDL_strrev(char *string)
488
489
490
{
size_t len = SDL_strlen(string);
char *a = &string[0];
491
char *b = &string[len - 1];
492
len /= 2;
493
while (len--) {
494
495
496
497
498
499
500
501
502
char c = *a;
*a++ = *b;
*b-- = c;
}
return string;
}
#endif
#ifndef HAVE__STRUPR
503
504
char *
SDL_strupr(char *string)
505
506
{
char *bufp = string;
507
while (*bufp) {
508
*bufp = SDL_toupper((unsigned char) *bufp);
509
++bufp;
510
511
512
513
514
515
}
return string;
}
#endif
#ifndef HAVE__STRLWR
516
517
char *
SDL_strlwr(char *string)
518
519
{
char *bufp = string;
520
while (*bufp) {
521
*bufp = SDL_tolower((unsigned char) *bufp);
522
++bufp;
523
524
525
526
527
528
}
return string;
}
#endif
#ifndef HAVE_STRCHR
529
530
char *
SDL_strchr(const char *string, int c)
531
{
532
533
534
while (*string) {
if (*string == c) {
return (char *) string;
535
}
536
++string;
537
538
539
540
541
542
}
return NULL;
}
#endif
#ifndef HAVE_STRRCHR
543
544
char *
SDL_strrchr(const char *string, int c)
545
{
546
const char *bufp = string + SDL_strlen(string) - 1;
547
548
549
while (bufp >= string) {
if (*bufp == c) {
return (char *) bufp;
550
}
551
--bufp;
552
553
554
555
556
557
}
return NULL;
}
#endif
#ifndef HAVE_STRSTR
558
559
char *
SDL_strstr(const char *haystack, const char *needle)
560
{
561
size_t length = SDL_strlen(needle);
562
563
564
while (*haystack) {
if (SDL_strncmp(haystack, needle, length) == 0) {
return (char *) haystack;
565
}
566
++haystack;
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
}
return NULL;
}
#endif
#if !defined(HAVE__LTOA) || !defined(HAVE__I64TOA) || \
!defined(HAVE__ULTOA) || !defined(HAVE__UI64TOA)
static const char ntoa_table[] = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
'U', 'V', 'W', 'X', 'Y', 'Z'
};
#endif /* ntoa() conversion table */
#ifndef HAVE__LTOA
583
584
char *
SDL_ltoa(long value, char *string, int radix)
585
586
587
{
char *bufp = string;
588
if (value < 0) {
589
590
591
*bufp++ = '-';
value = -value;
}
592
593
if (value) {
while (value > 0) {
594
595
596
597
598
599
600
601
602
*bufp++ = ntoa_table[value % radix];
value /= radix;
}
} else {
*bufp++ = '0';
}
*bufp = '\0';
/* The numbers went into the string backwards. :) */
603
604
if (*string == '-') {
SDL_strrev(string + 1);
605
} else {
606
SDL_strrev(string);
607
608
609
610
611
612
613
}
return string;
}
#endif
#ifndef HAVE__ULTOA
614
615
char *
SDL_ultoa(unsigned long value, char *string, int radix)
616
617
618
{
char *bufp = string;
619
620
if (value) {
while (value > 0) {
621
622
623
624
625
626
627
628
629
*bufp++ = ntoa_table[value % radix];
value /= radix;
}
} else {
*bufp++ = '0';
}
*bufp = '\0';
/* The numbers went into the string backwards. :) */
630
SDL_strrev(string);
631
632
633
634
635
636
return string;
}
#endif
#ifndef HAVE_STRTOL
637
638
long
SDL_strtol(const char *string, char **endp, int base)
639
640
641
642
{
size_t len;
long value;
643
644
if (!base) {
if ((SDL_strlen(string) > 2) && (SDL_strncmp(string, "0x", 2) == 0)) {
645
646
647
648
649
650
651
base = 16;
} else {
base = 10;
}
}
len = SDL_ScanLong(string, base, &value);
652
653
if (endp) {
*endp = (char *) string + len;
654
655
656
657
658
}
return value;
}
#endif
659
#ifndef HAVE_STRTOUL
660
661
unsigned long
SDL_strtoul(const char *string, char **endp, int base)
662
663
664
665
{
size_t len;
unsigned long value;
666
667
if (!base) {
if ((SDL_strlen(string) > 2) && (SDL_strncmp(string, "0x", 2) == 0)) {
668
669
670
671
672
673
674
base = 16;
} else {
base = 10;
}
}
len = SDL_ScanUnsignedLong(string, base, &value);
675
676
if (endp) {
*endp = (char *) string + len;
677
678
679
680
681
}
return value;
}
#endif
682
683
684
#ifdef SDL_HAS_64BIT_TYPE
#ifndef HAVE__I64TOA
685
686
char *
SDL_lltoa(Sint64 value, char *string, int radix)
687
688
689
{
char *bufp = string;
690
if (value < 0) {
691
692
693
*bufp++ = '-';
value = -value;
}
694
695
if (value) {
while (value > 0) {
696
697
698
699
700
701
702
703
704
*bufp++ = ntoa_table[value % radix];
value /= radix;
}
} else {
*bufp++ = '0';
}
*bufp = '\0';
/* The numbers went into the string backwards. :) */
705
706
if (*string == '-') {
SDL_strrev(string + 1);
707
} else {
708
SDL_strrev(string);
709
710
711
712
713
714
715
}
return string;
}
#endif
#ifndef HAVE__UI64TOA
716
717
char *
SDL_ulltoa(Uint64 value, char *string, int radix)
718
719
720
{
char *bufp = string;
721
722
if (value) {
while (value > 0) {
723
724
725
726
727
728
729
730
731
*bufp++ = ntoa_table[value % radix];
value /= radix;
}
} else {
*bufp++ = '0';
}
*bufp = '\0';
/* The numbers went into the string backwards. :) */
732
SDL_strrev(string);
733
734
735
736
737
738
return string;
}
#endif
#ifndef HAVE_STRTOLL
739
740
Sint64
SDL_strtoll(const char *string, char **endp, int base)
741
742
743
744
{
size_t len;
Sint64 value;
745
746
if (!base) {
if ((SDL_strlen(string) > 2) && (SDL_strncmp(string, "0x", 2) == 0)) {
747
748
749
750
751
752
753
base = 16;
} else {
base = 10;
}
}
len = SDL_ScanLongLong(string, base, &value);
754
755
if (endp) {
*endp = (char *) string + len;
756
757
758
759
760
}
return value;
}
#endif
761
#ifndef HAVE_STRTOULL
762
763
Uint64
SDL_strtoull(const char *string, char **endp, int base)
764
765
766
767
{
size_t len;
Uint64 value;
768
769
if (!base) {
if ((SDL_strlen(string) > 2) && (SDL_strncmp(string, "0x", 2) == 0)) {
770
771
772
773
774
775
776
base = 16;
} else {
base = 10;
}
}
len = SDL_ScanUnsignedLongLong(string, base, &value);
777
778
if (endp) {
*endp = (char *) string + len;
779
780
781
782
783
}
return value;
}
#endif
784
785
#endif /* SDL_HAS_64BIT_TYPE */
786
#ifndef HAVE_STRTOD
787
788
double
SDL_strtod(const char *string, char **endp)
789
790
791
792
793
{
size_t len;
double value;
len = SDL_ScanFloat(string, &value);
794
795
if (endp) {
*endp = (char *) string + len;
796
797
798
799
800
}
return value;
}
#endif
801
#ifndef HAVE_STRCMP
802
803
int
SDL_strcmp(const char *str1, const char *str2)
804
805
{
while (*str1 && *str2) {
806
if (*str1 != *str2)
807
808
809
810
break;
++str1;
++str2;
}
811
return (int) ((unsigned char) *str1 - (unsigned char) *str2);
812
813
814
815
}
#endif
#ifndef HAVE_STRNCMP
816
817
int
SDL_strncmp(const char *str1, const char *str2, size_t maxlen)
818
{
819
820
while (*str1 && *str2 && maxlen) {
if (*str1 != *str2)
821
822
823
824
825
break;
++str1;
++str2;
--maxlen;
}
826
if (!maxlen) {
827
828
return 0;
}
829
return (int) ((unsigned char) *str1 - (unsigned char) *str2);
830
831
832
}
#endif
833
#if !defined(HAVE_STRCASECMP) && !defined(HAVE__STRICMP)
834
835
int
SDL_strcasecmp(const char *str1, const char *str2)
836
837
838
{
char a = 0;
char b = 0;
839
while (*str1 && *str2) {
840
841
a = SDL_tolower((unsigned char) *str1);
b = SDL_tolower((unsigned char) *str2);
842
if (a != b)
843
844
845
846
break;
++str1;
++str2;
}
847
848
a = SDL_tolower(*str1);
b = SDL_tolower(*str2);
849
return (int) ((unsigned char) a - (unsigned char) b);
850
851
852
}
#endif
853
#if !defined(HAVE_STRNCASECMP) && !defined(HAVE__STRNICMP)
854
855
int
SDL_strncasecmp(const char *str1, const char *str2, size_t maxlen)
856
857
858
{
char a = 0;
char b = 0;
859
while (*str1 && *str2 && maxlen) {
860
861
a = SDL_tolower((unsigned char) *str1);
b = SDL_tolower((unsigned char) *str2);
862
if (a != b)
863
864
865
866
867
break;
++str1;
++str2;
--maxlen;
}
868
869
a = SDL_tolower((unsigned char) *str1);
b = SDL_tolower((unsigned char) *str2);
870
return (int) ((unsigned char) a - (unsigned char) b);
871
872
873
}
#endif
874
#ifndef HAVE_SSCANF
875
876
int
SDL_sscanf(const char *text, const char *fmt, ...)
877
878
879
880
881
{
va_list ap;
int retval = 0;
va_start(ap, fmt);
882
883
while (*fmt) {
if (*fmt == ' ') {
884
while (SDL_isspace((unsigned char) *text)) {
885
886
887
888
889
++text;
}
++fmt;
continue;
}
890
if (*fmt == '%') {
891
892
893
SDL_bool done = SDL_FALSE;
long count = 0;
int radix = 10;
894
895
enum
{
896
897
898
899
900
901
902
903
DO_SHORT,
DO_INT,
DO_LONG,
DO_LONGLONG
} inttype = DO_INT;
SDL_bool suppress = SDL_FALSE;
++fmt;
904
905
if (*fmt == '%') {
if (*text == '%') {
906
907
908
909
910
911
++text;
++fmt;
continue;
}
break;
}
912
if (*fmt == '*') {
913
914
915
916
917
suppress = SDL_TRUE;
++fmt;
}
fmt += SDL_ScanLong(fmt, 10, &count);
918
919
if (*fmt == 'c') {
if (!count) {
920
921
count = 1;
}
922
923
if (suppress) {
while (count--) {
924
925
926
++text;
}
} else {
927
928
char *valuep = va_arg(ap, char *);
while (count--) {
929
930
931
932
933
934
935
*valuep++ = *text++;
}
++retval;
}
continue;
}
936
while (SDL_isspace((unsigned char) *text)) {
937
938
939
940
941
++text;
}
/* FIXME: implement more of the format specifiers */
while (!done) {
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
switch (*fmt) {
case '*':
suppress = SDL_TRUE;
break;
case 'h':
if (inttype > DO_SHORT) {
++inttype;
}
break;
case 'l':
if (inttype < DO_LONGLONG) {
++inttype;
}
break;
case 'I':
if (SDL_strncmp(fmt, "I64", 3) == 0) {
fmt += 2;
inttype = DO_LONGLONG;
}
break;
case 'i':
{
int index = 0;
if (text[index] == '-') {
++index;
967
}
968
if (text[index] == '0') {
969
970
if (SDL_tolower((unsigned char) text[index + 1])
== 'x') {
971
972
973
radix = 16;
} else {
radix = 8;
974
975
}
}
976
977
978
}
/* Fall through to %d handling */
case 'd':
979
#ifdef SDL_HAS_64BIT_TYPE
980
981
982
983
984
985
986
if (inttype == DO_LONGLONG) {
Sint64 value;
text += SDL_ScanLongLong(text, radix, &value);
if (!suppress) {
Sint64 *valuep = va_arg(ap, Sint64 *);
*valuep = value;
++retval;
987
}
988
} else
989
#endif /* SDL_HAS_64BIT_TYPE */
990
991
992
993
994
995
996
997
998
999
1000
{
long value;
text += SDL_ScanLong(text, radix, &value);
if (!suppress) {
switch (inttype) {
case DO_SHORT:
{
short *valuep = va_arg(ap, short *);
*valuep = (short) value;
}
break;