00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
#include "precomp.h"
00015
#pragma hdrstop
00016
00017 #define out(c) if (cchLimit) {*lpOut++=(c); cchLimit--;} else goto errorout
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 int SP_PutNumber(
00032 LPSTR lpstr,
00033 ULONG_PTR n,
00034
int limit,
00035 DWORD radix,
00036
int uppercase)
00037 {
00038
DWORD mod;
00039
int count = 0;
00040
00041
00042
if(uppercase)
00043 uppercase =
'A'-
'0'-10;
00044
else
00045 uppercase =
'a'-
'0'-10;
00046
00047
if (count < limit) {
00048
do {
00049 mod = (ULONG)(
n % radix);
00050
n /= radix;
00051
00052 mod +=
'0';
00053
if (mod >
'9')
00054 mod += uppercase;
00055 *lpstr++ = (
char)mod;
00056 count++;
00057 }
while((count < limit) &&
n);
00058 }
00059
00060
return count;
00061 }
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 void SP_Reverse(
00074 LPSTR lpFirst,
00075 LPSTR lpLast)
00076 {
00077
char ch;
00078
00079
while(lpLast > lpFirst){
00080 ch = *lpFirst;
00081 *lpFirst++ = *lpLast;
00082 *lpLast-- = ch;
00083 }
00084 }
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 LPCSTR
SP_GetFmtValue(
00096 LPCSTR lpch,
00097
int *lpw)
00098 {
00099
int ii = 0;
00100
00101
00102
while (*lpch >=
'0' && *lpch <=
'9') {
00103 ii *= 10;
00104 ii += (
int)(*lpch -
'0');
00105 lpch++;
00106 }
00107
00108 *lpw = ii;
00109
00110
00111
00112
00113
return lpch;
00114 }
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 LPCWSTR
SP_GetFmtValueW(
00127 LPCWSTR lpch,
00128
int *lpw)
00129 {
00130
int ii = 0;
00131
00132
00133
while (*lpch >=
L'0' && *lpch <=
L'9') {
00134 ii *= 10;
00135 ii += (
int)(*lpch -
L'0');
00136 lpch++;
00137 }
00138
00139 *lpw = ii;
00140
00141
00142
00143
00144
return lpch;
00145 }
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168 int wvsprintfA(
00169 LPSTR lpOut,
00170 LPCSTR lpFmt,
00171 va_list arglist)
00172 {
00173
BOOL fAllocateMem;
00174
char prefix, fillch;
00175
int left, width, prec, size, sign, radix, upper, hprefix;
00176
int cchLimit = WSPRINTF_LIMIT, cch;
00177 LPSTR lpT, lpTMB;
00178 LPWSTR pwsz;
00179 va_list varglist = arglist;
00180
union {
00181 LONG_PTR l;
00182 ULONG_PTR ul;
00183
char sz[2];
00184 WCHAR wsz[2];
00185 } val;
00186
00187
while (*lpFmt != 0) {
00188
if (*lpFmt ==
'%') {
00189
00190
00191
00192
00193 left = 0;
00194 prefix = 0;
00195
while (*++lpFmt) {
00196
if (*lpFmt ==
'-')
00197 left++;
00198
else if (*lpFmt ==
'#')
00199 prefix++;
00200
else
00201
break;
00202 }
00203
00204
00205
00206
00207
if (*lpFmt ==
'0') {
00208 fillch =
'0';
00209 lpFmt++;
00210 }
else
00211 fillch =
' ';
00212
00213
00214
00215
00216 lpFmt =
SP_GetFmtValue((LPCSTR)lpFmt, &cch);
00217 width = cch;
00218
00219
00220
00221
00222
if (*lpFmt ==
'.') {
00223 lpFmt =
SP_GetFmtValue((LPCSTR)++lpFmt, &cch);
00224 prec = cch;
00225 }
else
00226 prec = -1;
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236 hprefix = 0;
00237
if (*lpFmt ==
'w') {
00238 size = 2;
00239 lpFmt++;
00240 }
else if (*lpFmt ==
'l') {
00241 size = 1;
00242 lpFmt++;
00243 }
else if (*lpFmt ==
't') {
00244 size = 0;
00245 lpFmt++;
00246 }
else {
00247 size = 0;
00248
if (*lpFmt ==
'h') {
00249 lpFmt++;
00250 hprefix = 1;
00251 }
00252 }
00253
00254 upper = 0;
00255 sign = 0;
00256 radix = 10;
00257
00258
switch (*lpFmt) {
00259
case 0:
00260
goto errorout;
00261
00262
case 'i':
00263
case 'd':
00264 size=1;
00265 sign++;
00266
00267
00268
00269
case 'u':
00270
00271 prefix = 0;
00272 donumeric:
00273
00274
if (left || prec >= 0)
00275 fillch =
' ';
00276
00277
00278
00279
00280
00281
00282
if (size == 3) {
00283 val.l = va_arg(varglist, LONG_PTR);
00284 }
else if (size) {
00285 val.l = va_arg(varglist,
long);
00286 }
else if (sign) {
00287 val.l = (
long)va_arg(varglist,
short);
00288 }
else {
00289 val.ul = va_arg(varglist,
unsigned);
00290 }
00291
00292
if (sign && val.l < 0
L)
00293 val.l = -val.l;
00294
else
00295 sign = 0;
00296
00297
00298
00299
00300
00301
00302
if (size != 3) {
00303 val.l &= MAXULONG;
00304 }
00305
00306 lpT = lpOut;
00307
00308
00309
00310
00311 cch =
SP_PutNumber(lpOut, val.l, cchLimit, radix, upper);
00312
if (!(cchLimit -= cch))
00313
goto errorout;
00314
00315 lpOut += cch;
00316 width -= cch;
00317 prec -= cch;
00318
if (prec > 0)
00319 width -= prec;
00320
00321
00322
00323
00324
while (prec-- > 0)
00325
out(
'0');
00326
00327
if (width > 0 && !left) {
00328
00329
00330
00331
if (fillch !=
'0') {
00332
if (sign) {
00333 sign = 0;
00334
out(
'-');
00335 width--;
00336 }
00337
00338
if (prefix) {
00339
out(prefix);
00340
out(
'0');
00341 prefix = 0;
00342 }
00343 }
00344
00345
if (sign)
00346 width--;
00347
00348
00349
00350
00351
while (width-- > 0)
00352
out(fillch);
00353
00354
00355
00356
00357
if (sign)
00358
out(
'-');
00359
00360
if (prefix) {
00361
out(prefix);
00362
out(
'0');
00363 }
00364
00365
00366
00367
00368
SP_Reverse(lpT, lpOut - 1);
00369 }
else {
00370
00371
00372
00373
if (sign) {
00374
out(
'-');
00375 width--;
00376 }
00377
00378
if (prefix) {
00379
out(prefix);
00380
out(
'0');
00381 }
00382
00383
00384
00385
00386
SP_Reverse(lpT, lpOut - 1);
00387
00388
00389
00390
00391
while (width-- > 0)
00392
out(fillch);
00393 }
00394
break;
00395
00396
case 'p':
00397 size = 3;
00398
if (prec == -1) {
00399 prec = 2 *
sizeof(LONG_PTR);
00400 }
00401
00402
00403
00404
case 'X':
00405 upper++;
00406
00407
00408
00409
case 'x':
00410 radix = 16;
00411
if (prefix)
00412
if (upper)
00413 prefix =
'X';
00414
else
00415 prefix =
'x';
00416
goto donumeric;
00417
00418
case 'C':
00419
00420
00421
00422
if (!size && !hprefix) {
00423 size = 1;
00424 }
00425
00426
00427
00428
case 'c':
00429
00430
00431
00432
00433
00434 cch = 1;
00435
if (size) {
00436 val.wsz[0] = va_arg(varglist, WCHAR);
00437 val.wsz[1] = 0x0000;
00438 pwsz = val.wsz;
00439
goto putwstring;
00440 }
else {
00441 val.sz[0] = va_arg(varglist,
CHAR);
00442 val.sz[1] = 0;
00443 lpT = val.sz;
00444
goto putstring;
00445 }
00446
00447
case 'S':
00448
00449
00450
00451
if (!size && !hprefix) {
00452 size = 1;
00453 }
00454
00455
00456
00457
case 's':
00458
00459
00460
00461
00462
00463
if (size) {
00464 pwsz = va_arg(varglist, LPWSTR);
00465
if (pwsz ==
NULL) {
00466 cch = 0;
00467 }
else {
00468 cch = wcslen(pwsz);
00469 }
00470 putwstring:
00471 cch = WCSToMB(pwsz, cch, &lpTMB, -1,
TRUE);
00472 fAllocateMem = (
BOOL) cch;
00473 lpT = lpTMB;
00474 }
else {
00475 lpT = va_arg(varglist, LPSTR);
00476
if (lpT ==
NULL) {
00477 cch = 0;
00478 }
else {
00479 cch =
strlen(lpT);
00480 }
00481
00482 putstring:
00483 fAllocateMem =
FALSE;
00484 }
00485
00486
if (prec >= 0 && cch > prec)
00487 cch = prec;
00488 width -= cch;
00489
00490
if (fAllocateMem) {
00491
if (cch + (width < 0 ? 0 : width) >= cchLimit) {
00492
UserLocalFree(lpTMB);
00493
goto errorout;
00494 }
00495 }
00496
00497
if (left) {
00498
while (cch--)
00499
out(*lpT++);
00500
while (width-- > 0)
00501
out(fillch);
00502 }
else {
00503
while (width-- > 0)
00504
out(fillch);
00505
while (cch--)
00506
out(*lpT++);
00507 }
00508
00509
if (fAllocateMem) {
00510
UserLocalFree(lpTMB);
00511 }
00512
break;
00513
00514
default:
00515 normalch:
00516
out(*lpFmt);
00517
break;
00518 }
00519 }
else
00520
goto normalch;
00521
00522
00523
00524
00525 lpFmt++;
00526 }
00527
00528 errorout:
00529 *lpOut = 0;
00530
00531
return WSPRINTF_LIMIT - cchLimit;
00532 }
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544 int WINAPIV
wsprintfA(
00545 LPSTR lpOut,
00546 LPCSTR lpFmt,
00547 ...)
00548 {
00549 va_list arglist;
00550
int ret;
00551
00552 va_start(arglist, lpFmt);
00553 ret =
wvsprintfA(lpOut, lpFmt, arglist);
00554 va_end(arglist);
00555
return ret;
00556 }
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571 int SP_PutNumberW(
00572 LPWSTR lpstr,
00573 ULONG_PTR n,
00574
int limit,
00575 DWORD radix,
00576
int uppercase)
00577 {
00578
DWORD mod;
00579
int count = 0;
00580
00581
00582
if(uppercase)
00583 uppercase =
'A'-
'0'-10;
00584
else
00585 uppercase =
'a'-
'0'-10;
00586
00587
if (count < limit) {
00588
do {
00589 mod = (ULONG)(
n % radix);
00590
n /= radix;
00591
00592 mod +=
'0';
00593
if (mod >
'9')
00594 mod += uppercase;
00595 *lpstr++ = (WCHAR)mod;
00596 count++;
00597 }
while((count < limit) &&
n);
00598 }
00599
00600
return count;
00601 }
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614 void SP_ReverseW(
00615 LPWSTR lpFirst,
00616 LPWSTR lpLast)
00617 {
00618 WCHAR ch;
00619
00620
while(lpLast > lpFirst){
00621 ch = *lpFirst;
00622 *lpFirst++ = *lpLast;
00623 *lpLast-- = ch;
00624 }
00625 }
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638 int wvsprintfW(
00639 LPWSTR lpOut,
00640 LPCWSTR lpFmt,
00641 va_list arglist)
00642 {
00643
BOOL fAllocateMem;
00644 WCHAR prefix, fillch;
00645
int left, width, prec, size, sign, radix, upper, hprefix;
00646
int cchLimit = WSPRINTF_LIMIT, cch;
00647 LPWSTR lpT, lpTWC;
00648 LPBYTE psz;
00649 va_list varglist = arglist;
00650
union {
00651 LONG_PTR l;
00652 ULONG_PTR ul;
00653
char sz[2];
00654 WCHAR wsz[2];
00655 } val;
00656
00657
while (*lpFmt != 0) {
00658
if (*lpFmt ==
L'%') {
00659
00660
00661
00662
00663 left = 0;
00664 prefix = 0;
00665
while (*++lpFmt) {
00666
if (*lpFmt ==
L'-')
00667 left++;
00668
else if (*lpFmt ==
L'#')
00669 prefix++;
00670
else
00671
break;
00672 }
00673
00674
00675
00676
00677
if (*lpFmt ==
L'0') {
00678 fillch =
L'0';
00679 lpFmt++;
00680 }
else
00681 fillch =
L' ';
00682
00683
00684
00685
00686 lpFmt =
SP_GetFmtValueW(lpFmt, &cch);
00687 width = cch;
00688
00689
00690
00691
00692
if (*lpFmt ==
L'.') {
00693 lpFmt =
SP_GetFmtValueW(++lpFmt, &cch);
00694 prec = cch;
00695 }
else
00696 prec = -1;
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706 hprefix = 0;
00707
if ((*lpFmt ==
L'w') || (*lpFmt ==
L't')) {
00708 size = 2;
00709 lpFmt++;
00710 }
else if (*lpFmt ==
L'l') {
00711 size = 1;
00712 lpFmt++;
00713 }
else {
00714 size = 0;
00715
if (*lpFmt ==
L'h') {
00716 lpFmt++;
00717 hprefix = 1;
00718 }
00719 }
00720
00721 upper = 0;
00722 sign = 0;
00723 radix = 10;
00724
00725
switch (*lpFmt) {
00726
case 0:
00727
goto errorout;
00728
00729
case L'i':
00730
case L'd':
00731 size=1;
00732 sign++;
00733
00734
00735
00736
case L'u':
00737
00738 prefix = 0;
00739 donumeric:
00740
00741
if (left || prec >= 0)
00742 fillch =
L' ';
00743
00744
00745
00746
00747
00748
00749
if (size == 3) {
00750 val.l = va_arg(varglist, LONG_PTR);
00751 }
else if (size) {
00752 val.l = va_arg(varglist, LONG);
00753 }
else if (sign) {
00754 val.l = va_arg(varglist,
SHORT);
00755 }
else {
00756 val.ul = va_arg(varglist,
unsigned);
00757 }
00758
00759
if (sign && val.l < 0
L)
00760 val.l = -val.l;
00761
else
00762 sign = 0;
00763
00764
00765
00766
00767
00768
00769
if (size != 3) {
00770 val.l &= MAXULONG;
00771 }
00772
00773 lpT = lpOut;
00774
00775
00776
00777
00778 cch =
SP_PutNumberW(lpOut, val.l, cchLimit, radix, upper);
00779
if (!(cchLimit -= cch))
00780
goto errorout;
00781
00782 lpOut += cch;
00783 width -= cch;
00784 prec -= cch;
00785
if (prec > 0)
00786 width -= prec;
00787
00788
00789
00790
00791
while (prec-- > 0)
00792
out(
L'0');
00793
00794
if (width > 0 && !left) {
00795
00796
00797
00798
if (fillch !=
L'0') {
00799
if (sign) {
00800 sign = 0;
00801
out(
L'-');
00802 width--;
00803 }
00804
00805
if (prefix) {
00806
out(prefix);
00807
out(
L'0');
00808 prefix = 0;
00809 }
00810 }
00811
00812
if (sign)
00813 width--;
00814
00815
00816
00817
00818
while (width-- > 0)
00819
out(fillch);
00820
00821
00822
00823
00824
if (sign)
00825
out(
L'-');
00826
00827
if (prefix) {
00828
out(prefix);
00829
out(
L'0');
00830 }
00831
00832
00833
00834
00835
SP_ReverseW(lpT, lpOut - 1);
00836 }
else {
00837
00838
00839
00840
if (sign) {
00841
out(
L'-');
00842 width--;
00843 }
00844
00845
if (prefix) {
00846
out(prefix);
00847
out(
L'0');
00848 }
00849
00850
00851
00852
00853
SP_ReverseW(lpT, lpOut - 1);
00854
00855
00856
00857
00858
while (width-- > 0)
00859
out(fillch);
00860 }
00861
break;
00862
00863
case L'p':
00864 size = 3;
00865
if (prec == -1) {
00866 prec = 2 *
sizeof(LONG_PTR);
00867 }
00868
00869
00870
00871
case L'X':
00872 upper++;
00873
00874
00875
00876
case L'x':
00877 radix = 16;
00878
if (prefix)
00879
if (upper)
00880 prefix =
L'X';
00881
else
00882 prefix =
L'x';
00883
goto donumeric;
00884
00885
case L'c':
00886
if (!size && !hprefix) {
00887 size = 1;
00888 }
00889
00890
00891
00892
case L'C':
00893
00894
00895
00896
00897
00898 cch = 1;
00899
if (size) {
00900 val.wsz[0] = va_arg(varglist, WCHAR);
00901 val.wsz[1] = 0;
00902 lpT = val.wsz;
00903
goto putwstring;
00904 }
else {
00905 val.sz[0] = va_arg(varglist,
CHAR);
00906 val.sz[1] = 0;
00907 psz = val.sz;
00908
goto putstring;
00909 }
00910
00911
case L's':
00912
if (!size && !hprefix) {
00913 size = 1;
00914 }
00915
00916
00917
00918
case L'S':
00919
00920
00921
00922
00923
00924
if (size) {
00925 lpT = va_arg(varglist, LPWSTR);
00926
if (lpT ==
NULL) {
00927 cch = 0;
00928 }
else {
00929 cch = wcslen(lpT);
00930 }
00931 putwstring:
00932 fAllocateMem =
FALSE;
00933 }
else {
00934 psz = va_arg(varglist, LPBYTE);
00935
if (psz ==
NULL) {
00936 cch = 0;
00937 }
else {
00938 cch =
strlen(psz);
00939 }
00940 putstring:
00941 cch = MBToWCS(psz, cch, &lpTWC, -1,
TRUE);
00942 fAllocateMem = (
BOOL) cch;
00943 lpT = lpTWC;
00944 }
00945
00946
if (prec >= 0 && cch > prec)
00947 cch = prec;
00948 width -= cch;
00949
00950
if (fAllocateMem) {
00951
if (cch + (width < 0 ? 0 : width) >= cchLimit) {
00952
UserLocalFree(lpTWC);
00953
goto errorout;
00954 }
00955 }
00956
00957
if (left) {
00958
while (cch--)
00959
out(*lpT++);
00960
while (width-- > 0)
00961
out(fillch);
00962 }
else {
00963
while (width-- > 0)
00964
out(fillch);
00965
while (cch--)
00966
out(*lpT++);
00967 }
00968
00969
if (fAllocateMem) {
00970
UserLocalFree(lpTWC);
00971 }
00972
00973
break;
00974
00975
default:
00976 normalch:
00977
out((WCHAR)*lpFmt);
00978
break;
00979 }
00980 }
else
00981
goto normalch;
00982
00983
00984
00985
00986 lpFmt++;
00987 }
00988
00989 errorout:
00990 *lpOut = 0;
00991
00992
return WSPRINTF_LIMIT - cchLimit;
00993 }
00994
00995 int WINAPIV
wsprintfW(
00996 LPWSTR lpOut,
00997 LPCWSTR lpFmt,
00998 ...)
00999 {
01000 va_list arglist;
01001
int ret;
01002
01003 va_start(arglist, lpFmt);
01004 ret =
wvsprintfW(lpOut, lpFmt, arglist);
01005 va_end(arglist);
01006
return ret;
01007 }