wsprintf.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664
  1. /*
  2. * wsprintf functions
  3. *
  4. * Copyright 1996 Alexandre Julliard
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this library; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19. *
  20. * NOTE:
  21. * This code is duplicated in shlwapi. If you change something here make sure
  22. * to change it in shlwapi too.
  23. */
  24. #include <stdarg.h>
  25. #include <string.h>
  26. #include <stdio.h>
  27. #include "windef.h"
  28. #include "winbase.h"
  29. #include "wingdi.h"
  30. #include "winuser.h"
  31. #include "wine/winbase16.h"
  32. #include "wine/winuser16.h"
  33. #include "wine/debug.h"
  34. WINE_DEFAULT_DEBUG_CHANNEL(string);
  35. #define WPRINTF_LEFTALIGN 0x0001 /* Align output on the left ('-' prefix) */
  36. #define WPRINTF_PREFIX_HEX 0x0002 /* Prefix hex with 0x ('#' prefix) */
  37. #define WPRINTF_ZEROPAD 0x0004 /* Pad with zeros ('0' prefix) */
  38. #define WPRINTF_LONG 0x0008 /* Long arg ('l' prefix) */
  39. #define WPRINTF_SHORT 0x0010 /* Short arg ('h' prefix) */
  40. #define WPRINTF_UPPER_HEX 0x0020 /* Upper-case hex ('X' specifier) */
  41. #define WPRINTF_WIDE 0x0040 /* Wide arg ('w' prefix) */
  42. typedef enum
  43. {
  44. WPR_UNKNOWN,
  45. WPR_CHAR,
  46. WPR_WCHAR,
  47. WPR_STRING,
  48. WPR_WSTRING,
  49. WPR_SIGNED,
  50. WPR_UNSIGNED,
  51. WPR_HEXA
  52. } WPRINTF_TYPE;
  53. typedef struct
  54. {
  55. UINT flags;
  56. UINT width;
  57. UINT precision;
  58. WPRINTF_TYPE type;
  59. } WPRINTF_FORMAT;
  60. typedef union {
  61. WCHAR wchar_view;
  62. CHAR char_view;
  63. LPCSTR lpcstr_view;
  64. LPCWSTR lpcwstr_view;
  65. INT int_view;
  66. } WPRINTF_DATA;
  67. static const CHAR null_stringA[] = "(null)";
  68. static const WCHAR null_stringW[] = { '(', 'n', 'u', 'l', 'l', ')', 0 };
  69. /***********************************************************************
  70. * WPRINTF_ParseFormatA
  71. *
  72. * Parse a format specification. A format specification has the form:
  73. *
  74. * [-][#][0][width][.precision]type
  75. *
  76. * Return value is the length of the format specification in characters.
  77. */
  78. static INT WPRINTF_ParseFormatA( LPCSTR format, WPRINTF_FORMAT *res )
  79. {
  80. LPCSTR p = format;
  81. res->flags = 0;
  82. res->width = 0;
  83. res->precision = 0;
  84. if (*p == '-') { res->flags |= WPRINTF_LEFTALIGN; p++; }
  85. if (*p == '#') { res->flags |= WPRINTF_PREFIX_HEX; p++; }
  86. if (*p == '0') { res->flags |= WPRINTF_ZEROPAD; p++; }
  87. while ((*p >= '0') && (*p <= '9')) /* width field */
  88. {
  89. res->width = res->width * 10 + *p - '0';
  90. p++;
  91. }
  92. if (*p == '.') /* precision field */
  93. {
  94. p++;
  95. while ((*p >= '0') && (*p <= '9'))
  96. {
  97. res->precision = res->precision * 10 + *p - '0';
  98. p++;
  99. }
  100. }
  101. if (*p == 'l') { res->flags |= WPRINTF_LONG; p++; }
  102. else if (*p == 'h') { res->flags |= WPRINTF_SHORT; p++; }
  103. else if (*p == 'w') { res->flags |= WPRINTF_WIDE; p++; }
  104. switch(*p)
  105. {
  106. case 'c':
  107. res->type = (res->flags & WPRINTF_LONG) ? WPR_WCHAR : WPR_CHAR;
  108. break;
  109. case 'C':
  110. res->type = (res->flags & WPRINTF_SHORT) ? WPR_CHAR : WPR_WCHAR;
  111. break;
  112. case 'd':
  113. case 'i':
  114. res->type = WPR_SIGNED;
  115. break;
  116. case 's':
  117. res->type = (res->flags & (WPRINTF_LONG |WPRINTF_WIDE)) ? WPR_WSTRING : WPR_STRING;
  118. break;
  119. case 'S':
  120. res->type = (res->flags & (WPRINTF_SHORT|WPRINTF_WIDE)) ? WPR_STRING : WPR_WSTRING;
  121. break;
  122. case 'u':
  123. res->type = WPR_UNSIGNED;
  124. break;
  125. case 'p':
  126. res->width = 8;
  127. res->flags |= WPRINTF_ZEROPAD;
  128. /* fall through */
  129. case 'X':
  130. res->flags |= WPRINTF_UPPER_HEX;
  131. /* fall through */
  132. case 'x':
  133. res->type = WPR_HEXA;
  134. break;
  135. default: /* unknown format char */
  136. res->type = WPR_UNKNOWN;
  137. p--; /* print format as normal char */
  138. break;
  139. }
  140. return (INT)(p - format) + 1;
  141. }
  142. /***********************************************************************
  143. * WPRINTF_ParseFormatW
  144. *
  145. * Parse a format specification. A format specification has the form:
  146. *
  147. * [-][#][0][width][.precision]type
  148. *
  149. * Return value is the length of the format specification in characters.
  150. */
  151. static INT WPRINTF_ParseFormatW( LPCWSTR format, WPRINTF_FORMAT *res )
  152. {
  153. LPCWSTR p = format;
  154. res->flags = 0;
  155. res->width = 0;
  156. res->precision = 0;
  157. if (*p == '-') { res->flags |= WPRINTF_LEFTALIGN; p++; }
  158. if (*p == '#') { res->flags |= WPRINTF_PREFIX_HEX; p++; }
  159. if (*p == '0') { res->flags |= WPRINTF_ZEROPAD; p++; }
  160. while ((*p >= '0') && (*p <= '9')) /* width field */
  161. {
  162. res->width = res->width * 10 + *p - '0';
  163. p++;
  164. }
  165. if (*p == '.') /* precision field */
  166. {
  167. p++;
  168. while ((*p >= '0') && (*p <= '9'))
  169. {
  170. res->precision = res->precision * 10 + *p - '0';
  171. p++;
  172. }
  173. }
  174. if (*p == 'l') { res->flags |= WPRINTF_LONG; p++; }
  175. else if (*p == 'h') { res->flags |= WPRINTF_SHORT; p++; }
  176. else if (*p == 'w') { res->flags |= WPRINTF_WIDE; p++; }
  177. switch((CHAR)*p)
  178. {
  179. case 'c':
  180. res->type = (res->flags & WPRINTF_SHORT) ? WPR_CHAR : WPR_WCHAR;
  181. break;
  182. case 'C':
  183. res->type = (res->flags & WPRINTF_LONG) ? WPR_WCHAR : WPR_CHAR;
  184. break;
  185. case 'd':
  186. case 'i':
  187. res->type = WPR_SIGNED;
  188. break;
  189. case 's':
  190. res->type = ((res->flags & WPRINTF_SHORT) && !(res->flags & WPRINTF_WIDE)) ? WPR_STRING : WPR_WSTRING;
  191. break;
  192. case 'S':
  193. res->type = (res->flags & (WPRINTF_LONG|WPRINTF_WIDE)) ? WPR_WSTRING : WPR_STRING;
  194. break;
  195. case 'u':
  196. res->type = WPR_UNSIGNED;
  197. break;
  198. case 'p':
  199. res->width = 8;
  200. res->flags |= WPRINTF_ZEROPAD;
  201. /* fall through */
  202. case 'X':
  203. res->flags |= WPRINTF_UPPER_HEX;
  204. /* fall through */
  205. case 'x':
  206. res->type = WPR_HEXA;
  207. break;
  208. default:
  209. res->type = WPR_UNKNOWN;
  210. p--; /* print format as normal char */
  211. break;
  212. }
  213. return (INT)(p - format) + 1;
  214. }
  215. /***********************************************************************
  216. * WPRINTF_GetLen
  217. */
  218. static UINT WPRINTF_GetLen( WPRINTF_FORMAT *format, WPRINTF_DATA *arg,
  219. LPSTR number, UINT maxlen )
  220. {
  221. UINT len;
  222. if (format->flags & WPRINTF_LEFTALIGN) format->flags &= ~WPRINTF_ZEROPAD;
  223. if (format->width > maxlen) format->width = maxlen;
  224. switch(format->type)
  225. {
  226. case WPR_CHAR:
  227. case WPR_WCHAR:
  228. return (format->precision = 1);
  229. case WPR_STRING:
  230. if (!arg->lpcstr_view) arg->lpcstr_view = null_stringA;
  231. for (len = 0; !format->precision || (len < format->precision); len++)
  232. if (!*(arg->lpcstr_view + len)) break;
  233. if (len > maxlen) len = maxlen;
  234. return (format->precision = len);
  235. case WPR_WSTRING:
  236. if (!arg->lpcwstr_view) arg->lpcwstr_view = null_stringW;
  237. for (len = 0; !format->precision || (len < format->precision); len++)
  238. if (!*(arg->lpcwstr_view + len)) break;
  239. if (len > maxlen) len = maxlen;
  240. return (format->precision = len);
  241. case WPR_SIGNED:
  242. len = sprintf( number, "%d", arg->int_view );
  243. break;
  244. case WPR_UNSIGNED:
  245. len = sprintf( number, "%u", (UINT)arg->int_view );
  246. break;
  247. case WPR_HEXA:
  248. len = sprintf( number,
  249. (format->flags & WPRINTF_UPPER_HEX) ? "%X" : "%x",
  250. (UINT)arg->int_view);
  251. break;
  252. default:
  253. return 0;
  254. }
  255. if (len > maxlen) len = maxlen;
  256. if (format->precision < len) format->precision = len;
  257. if (format->precision > maxlen) format->precision = maxlen;
  258. if ((format->flags & WPRINTF_ZEROPAD) && (format->width > format->precision))
  259. format->precision = format->width;
  260. if (format->flags & WPRINTF_PREFIX_HEX) len += 2;
  261. return len;
  262. }
  263. /***********************************************************************
  264. * wvsnprintf16 (Not a Windows API)
  265. */
  266. static INT16 wvsnprintf16( LPSTR buffer, UINT16 maxlen, LPCSTR spec, VA_LIST16 args )
  267. {
  268. WPRINTF_FORMAT format;
  269. LPSTR p = buffer;
  270. UINT i, len, sign;
  271. CHAR number[20];
  272. WPRINTF_DATA cur_arg;
  273. SEGPTR seg_str;
  274. while (*spec && (maxlen > 1))
  275. {
  276. if (*spec != '%') { *p++ = *spec++; maxlen--; continue; }
  277. spec++;
  278. if (*spec == '%') { *p++ = *spec++; maxlen--; continue; }
  279. spec += WPRINTF_ParseFormatA( spec, &format );
  280. switch(format.type)
  281. {
  282. case WPR_WCHAR: /* No Unicode in Win16 */
  283. case WPR_CHAR:
  284. cur_arg.char_view = VA_ARG16( args, CHAR );
  285. break;
  286. case WPR_WSTRING: /* No Unicode in Win16 */
  287. case WPR_STRING:
  288. seg_str = VA_ARG16( args, SEGPTR );
  289. if (IsBadReadPtr16(seg_str, 1 )) cur_arg.lpcstr_view = "";
  290. else cur_arg.lpcstr_view = MapSL( seg_str );
  291. break;
  292. case WPR_SIGNED:
  293. if (!(format.flags & WPRINTF_LONG))
  294. {
  295. cur_arg.int_view = VA_ARG16( args, INT16 );
  296. break;
  297. }
  298. /* fall through */
  299. case WPR_HEXA:
  300. case WPR_UNSIGNED:
  301. if (format.flags & WPRINTF_LONG)
  302. cur_arg.int_view = VA_ARG16( args, UINT );
  303. else
  304. cur_arg.int_view = VA_ARG16( args, UINT16 );
  305. break;
  306. case WPR_UNKNOWN:
  307. continue;
  308. }
  309. len = WPRINTF_GetLen( &format, &cur_arg, number, maxlen - 1 );
  310. sign = 0;
  311. if (!(format.flags & WPRINTF_LEFTALIGN))
  312. for (i = format.precision; i < format.width; i++, maxlen--)
  313. *p++ = ' ';
  314. switch(format.type)
  315. {
  316. case WPR_WCHAR: /* No Unicode in Win16 */
  317. case WPR_CHAR:
  318. *p= cur_arg.char_view;
  319. /* wsprintf16 (unlike wsprintf) ignores null characters */
  320. if (*p != '\0') p++;
  321. else if (format.width > 1) *p++ = ' ';
  322. else len = 0;
  323. break;
  324. case WPR_WSTRING: /* No Unicode in Win16 */
  325. case WPR_STRING:
  326. if (len) memcpy( p, cur_arg.lpcstr_view, len );
  327. p += len;
  328. break;
  329. case WPR_HEXA:
  330. if ((format.flags & WPRINTF_PREFIX_HEX) && (maxlen > 3))
  331. {
  332. *p++ = '0';
  333. *p++ = (format.flags & WPRINTF_UPPER_HEX) ? 'X' : 'x';
  334. maxlen -= 2;
  335. len -= 2;
  336. }
  337. /* fall through */
  338. case WPR_SIGNED:
  339. /* Transfer the sign now, just in case it will be zero-padded*/
  340. if (number[0] == '-')
  341. {
  342. *p++ = '-';
  343. sign = 1;
  344. }
  345. /* fall through */
  346. case WPR_UNSIGNED:
  347. for (i = len; i < format.precision; i++, maxlen--) *p++ = '0';
  348. if (len > sign) memcpy( p, number + sign, len - sign );
  349. p += len-sign;
  350. break;
  351. case WPR_UNKNOWN:
  352. continue;
  353. }
  354. if (format.flags & WPRINTF_LEFTALIGN)
  355. for (i = format.precision; i < format.width; i++, maxlen--)
  356. *p++ = ' ';
  357. maxlen -= len;
  358. }
  359. *p = 0;
  360. return (maxlen > 1) ? (INT)(p - buffer) : -1;
  361. }
  362. /***********************************************************************
  363. * wvsnprintfA (internal)
  364. */
  365. static INT wvsnprintfA( LPSTR buffer, UINT maxlen, LPCSTR spec, va_list args )
  366. {
  367. WPRINTF_FORMAT format;
  368. LPSTR p = buffer;
  369. UINT i, len, sign;
  370. CHAR number[20];
  371. WPRINTF_DATA argData;
  372. TRACE("%p %u %s\n", buffer, maxlen, debugstr_a(spec));
  373. while (*spec && (maxlen > 1))
  374. {
  375. if (*spec != '%') { *p++ = *spec++; maxlen--; continue; }
  376. spec++;
  377. if (*spec == '%') { *p++ = *spec++; maxlen--; continue; }
  378. spec += WPRINTF_ParseFormatA( spec, &format );
  379. switch(format.type)
  380. {
  381. case WPR_WCHAR:
  382. argData.wchar_view = (WCHAR)va_arg( args, int );
  383. break;
  384. case WPR_CHAR:
  385. argData.char_view = (CHAR)va_arg( args, int );
  386. break;
  387. case WPR_STRING:
  388. argData.lpcstr_view = va_arg( args, LPCSTR );
  389. break;
  390. case WPR_WSTRING:
  391. argData.lpcwstr_view = va_arg( args, LPCWSTR );
  392. break;
  393. case WPR_HEXA:
  394. case WPR_SIGNED:
  395. case WPR_UNSIGNED:
  396. argData.int_view = va_arg( args, INT );
  397. break;
  398. default:
  399. argData.wchar_view = 0;
  400. break;
  401. }
  402. len = WPRINTF_GetLen( &format, &argData, number, maxlen - 1 );
  403. sign = 0;
  404. if (!(format.flags & WPRINTF_LEFTALIGN))
  405. for (i = format.precision; i < format.width; i++, maxlen--)
  406. *p++ = ' ';
  407. switch(format.type)
  408. {
  409. case WPR_WCHAR:
  410. *p++ = argData.wchar_view;
  411. break;
  412. case WPR_CHAR:
  413. *p++ = argData.char_view;
  414. break;
  415. case WPR_STRING:
  416. memcpy( p, argData.lpcstr_view, len );
  417. p += len;
  418. break;
  419. case WPR_WSTRING:
  420. {
  421. LPCWSTR ptr = argData.lpcwstr_view;
  422. for (i = 0; i < len; i++) *p++ = (CHAR)*ptr++;
  423. }
  424. break;
  425. case WPR_HEXA:
  426. if ((format.flags & WPRINTF_PREFIX_HEX) && (maxlen > 3))
  427. {
  428. *p++ = '0';
  429. *p++ = (format.flags & WPRINTF_UPPER_HEX) ? 'X' : 'x';
  430. maxlen -= 2;
  431. len -= 2;
  432. }
  433. /* fall through */
  434. case WPR_SIGNED:
  435. /* Transfer the sign now, just in case it will be zero-padded*/
  436. if (number[0] == '-')
  437. {
  438. *p++ = '-';
  439. sign = 1;
  440. }
  441. /* fall through */
  442. case WPR_UNSIGNED:
  443. for (i = len; i < format.precision; i++, maxlen--) *p++ = '0';
  444. memcpy( p, number + sign, len - sign );
  445. p += len - sign;
  446. break;
  447. case WPR_UNKNOWN:
  448. continue;
  449. }
  450. if (format.flags & WPRINTF_LEFTALIGN)
  451. for (i = format.precision; i < format.width; i++, maxlen--)
  452. *p++ = ' ';
  453. maxlen -= len;
  454. }
  455. *p = 0;
  456. TRACE("%s\n",debugstr_a(buffer));
  457. return (maxlen > 1) ? (INT)(p - buffer) : -1;
  458. }
  459. /***********************************************************************
  460. * wvsnprintfW (internal)
  461. */
  462. static INT wvsnprintfW( LPWSTR buffer, UINT maxlen, LPCWSTR spec, va_list args )
  463. {
  464. WPRINTF_FORMAT format;
  465. LPWSTR p = buffer;
  466. UINT i, len, sign;
  467. CHAR number[20];
  468. WPRINTF_DATA argData;
  469. TRACE("%p %u %s\n", buffer, maxlen, debugstr_w(spec));
  470. while (*spec && (maxlen > 1))
  471. {
  472. if (*spec != '%') { *p++ = *spec++; maxlen--; continue; }
  473. spec++;
  474. if (*spec == '%') { *p++ = *spec++; maxlen--; continue; }
  475. spec += WPRINTF_ParseFormatW( spec, &format );
  476. switch(format.type)
  477. {
  478. case WPR_WCHAR:
  479. argData.wchar_view = (WCHAR)va_arg( args, int );
  480. break;
  481. case WPR_CHAR:
  482. argData.char_view = (CHAR)va_arg( args, int );
  483. break;
  484. case WPR_STRING:
  485. argData.lpcstr_view = va_arg( args, LPCSTR );
  486. break;
  487. case WPR_WSTRING:
  488. argData.lpcwstr_view = va_arg( args, LPCWSTR );
  489. break;
  490. case WPR_HEXA:
  491. case WPR_SIGNED:
  492. case WPR_UNSIGNED:
  493. argData.int_view = va_arg( args, INT );
  494. break;
  495. default:
  496. argData.wchar_view = 0;
  497. break;
  498. }
  499. len = WPRINTF_GetLen( &format, &argData, number, maxlen - 1 );
  500. sign = 0;
  501. if (!(format.flags & WPRINTF_LEFTALIGN))
  502. for (i = format.precision; i < format.width; i++, maxlen--)
  503. *p++ = ' ';
  504. switch(format.type)
  505. {
  506. case WPR_WCHAR:
  507. *p++ = argData.wchar_view;
  508. break;
  509. case WPR_CHAR:
  510. *p++ = argData.char_view;
  511. break;
  512. case WPR_STRING:
  513. {
  514. LPCSTR ptr = argData.lpcstr_view;
  515. for (i = 0; i < len; i++) *p++ = (WCHAR)*ptr++;
  516. }
  517. break;
  518. case WPR_WSTRING:
  519. if (len) memcpy( p, argData.lpcwstr_view, len * sizeof(WCHAR) );
  520. p += len;
  521. break;
  522. case WPR_HEXA:
  523. if ((format.flags & WPRINTF_PREFIX_HEX) && (maxlen > 3))
  524. {
  525. *p++ = '0';
  526. *p++ = (format.flags & WPRINTF_UPPER_HEX) ? 'X' : 'x';
  527. maxlen -= 2;
  528. len -= 2;
  529. }
  530. /* fall through */
  531. case WPR_SIGNED:
  532. /* Transfer the sign now, just in case it will be zero-padded*/
  533. if (number[0] == '-')
  534. {
  535. *p++ = '-';
  536. sign = 1;
  537. }
  538. /* fall through */
  539. case WPR_UNSIGNED:
  540. for (i = len; i < format.precision; i++, maxlen--) *p++ = '0';
  541. for (i = sign; i < len; i++) *p++ = (WCHAR)number[i];
  542. break;
  543. case WPR_UNKNOWN:
  544. continue;
  545. }
  546. if (format.flags & WPRINTF_LEFTALIGN)
  547. for (i = format.precision; i < format.width; i++, maxlen--)
  548. *p++ = ' ';
  549. maxlen -= len;
  550. }
  551. *p = 0;
  552. TRACE("%s\n",debugstr_w(buffer));
  553. return (maxlen > 1) ? (INT)(p - buffer) : -1;
  554. }
  555. /***********************************************************************
  556. * wvsprintf (USER.421)
  557. */
  558. INT16 WINAPI wvsprintf16( LPSTR buffer, LPCSTR spec, VA_LIST16 args )
  559. {
  560. INT16 res;
  561. TRACE("for %p got:\n",buffer);
  562. res = wvsnprintf16( buffer, 1024, spec, args );
  563. return ( res == -1 ) ? 1024 : res;
  564. }
  565. /***********************************************************************
  566. * wvsprintfA (USER32.@)
  567. */
  568. INT WINAPI wvsprintfA( LPSTR buffer, LPCSTR spec, va_list args )
  569. {
  570. INT res = wvsnprintfA( buffer, 1024, spec, args );
  571. return ( res == -1 ) ? 1024 : res;
  572. }
  573. /***********************************************************************
  574. * wvsprintfW (USER32.@)
  575. */
  576. INT WINAPI wvsprintfW( LPWSTR buffer, LPCWSTR spec, va_list args )
  577. {
  578. INT res = wvsnprintfW( buffer, 1024, spec, args );
  579. return ( res == -1 ) ? 1024 : res;
  580. }
  581. /***********************************************************************
  582. * _wsprintf (USER.420)
  583. */
  584. INT16 WINAPIV wsprintf16( LPSTR buffer, LPCSTR spec, VA_LIST16 valist )
  585. {
  586. INT16 res;
  587. res = wvsnprintf16( buffer, 1024, spec, valist );
  588. return ( res == -1 ) ? 1024 : res;
  589. }
  590. /***********************************************************************
  591. * wsprintfA (USER32.@)
  592. */
  593. INT WINAPIV wsprintfA( LPSTR buffer, LPCSTR spec, ... )
  594. {
  595. va_list valist;
  596. INT res;
  597. va_start( valist, spec );
  598. res = wvsnprintfA( buffer, 1024, spec, valist );
  599. va_end( valist );
  600. return ( res == -1 ) ? 1024 : res;
  601. }
  602. /***********************************************************************
  603. * wsprintfW (USER32.@)
  604. */
  605. INT WINAPIV wsprintfW( LPWSTR buffer, LPCWSTR spec, ... )
  606. {
  607. va_list valist;
  608. INT res;
  609. va_start( valist, spec );
  610. res = wvsnprintfW( buffer, 1024, spec, valist );
  611. va_end( valist );
  612. return ( res == -1 ) ? 1024 : res;
  613. }