Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

wsprintf.cpp

Go to the documentation of this file.
00001 /*
00002  * wsprintf functions
00003  *
00004  * Copyright 1996 Alexandre Julliard
00005  */
00006 
00007 #ifdef __WIN32OS2__
00008 #include <odin.h>
00009 #include <odinwrap.h>
00010 #include <os2sel.h>
00011 #include <os2win.h>
00012 
00013 #include <misc.h>
00014 
00015 #define DBG_LOCALLOG    DBG_wsprintf
00016 #include "dbglocal.h"
00017 
00018 ODINDEBUGCHANNEL(USER32-WSPRINTF)
00019 #endif
00020 
00021 #include <stdarg.h>
00022 #include <string.h>
00023 #include <stdio.h>
00024 #include "wine/winbase16.h"
00025 #include "windef.h"
00026 #include "wingdi.h"
00027 #include "winuser.h"
00028 #include "stackframe.h"
00029 #include "debugtools.h"
00030 
00031 DEFAULT_DEBUG_CHANNEL(string);
00032 
00033 
00034 #define WPRINTF_LEFTALIGN   0x0001  /* Align output on the left ('-' prefix) */
00035 #define WPRINTF_PREFIX_HEX  0x0002  /* Prefix hex with 0x ('#' prefix) */
00036 #define WPRINTF_ZEROPAD     0x0004  /* Pad with zeros ('0' prefix) */
00037 #define WPRINTF_LONG        0x0008  /* Long arg ('l' prefix) */
00038 #define WPRINTF_SHORT       0x0010  /* Short arg ('h' prefix) */
00039 #define WPRINTF_UPPER_HEX   0x0020  /* Upper-case hex ('X' specifier) */
00040 #define WPRINTF_WIDE        0x0040  /* Wide arg ('w' prefix) */
00041 
00042 typedef enum
00043 {
00044     WPR_UNKNOWN,
00045     WPR_CHAR,
00046     WPR_WCHAR,
00047     WPR_STRING,
00048     WPR_WSTRING,
00049     WPR_SIGNED,
00050     WPR_UNSIGNED,
00051     WPR_HEXA
00052 } WPRINTF_TYPE;
00053 
00054 typedef struct
00055 {
00056     UINT         flags;
00057     UINT         width;
00058     UINT         precision;
00059     WPRINTF_TYPE   type;
00060 } WPRINTF_FORMAT;
00061 
00062 typedef union {
00063     WCHAR   wchar_view;
00064     CHAR    char_view;
00065     LPCSTR  lpcstr_view;
00066     LPCWSTR lpcwstr_view;
00067     INT     int_view;
00068 } WPRINTF_DATA;
00069 
00070 static const CHAR null_stringA[] = "(null)";
00071 static const WCHAR null_stringW[] = { '(', 'n', 'u', 'l', 'l', ')', 0 };
00072 
00073 /***********************************************************************
00074  *           WPRINTF_ParseFormatA
00075  *
00076  * Parse a format specification. A format specification has the form:
00077  *
00078  * [-][#][0][width][.precision]type
00079  *
00080  * Return value is the length of the format specification in characters.
00081  */
00082 static INT WPRINTF_ParseFormatA( LPCSTR format, WPRINTF_FORMAT *res )
00083 {
00084     LPCSTR p = format;
00085 
00086     res->flags = 0;
00087     res->width = 0;
00088     res->precision = 0;
00089     if (*p == '-') { res->flags |= WPRINTF_LEFTALIGN; p++; }
00090     if (*p == '#') { res->flags |= WPRINTF_PREFIX_HEX; p++; }
00091     if (*p == '0') { res->flags |= WPRINTF_ZEROPAD; p++; }
00092     while ((*p >= '0') && (*p <= '9'))  /* width field */
00093     {
00094         res->width = res->width * 10 + *p - '0';
00095         p++;
00096     }
00097     if (*p == '.')  /* precision field */
00098     {
00099         p++;
00100         while ((*p >= '0') && (*p <= '9'))
00101         {
00102             res->precision = res->precision * 10 + *p - '0';
00103             p++;
00104         }
00105     }
00106     if (*p == 'l') { res->flags |= WPRINTF_LONG; p++; }
00107     else if (*p == 'h') { res->flags |= WPRINTF_SHORT; p++; }
00108     else if (*p == 'w') { res->flags |= WPRINTF_WIDE; p++; }
00109     switch(*p)
00110     {
00111     case 'c':
00112         res->type = (res->flags & WPRINTF_LONG) ? WPR_WCHAR : WPR_CHAR;
00113         break;
00114     case 'C':
00115         res->type = (res->flags & WPRINTF_SHORT) ? WPR_CHAR : WPR_WCHAR;
00116         break;
00117     case 'd':
00118     case 'i':
00119         res->type = WPR_SIGNED;
00120         break;
00121     case 's':
00122         res->type = (res->flags & (WPRINTF_LONG |WPRINTF_WIDE)) ? WPR_WSTRING : WPR_STRING;
00123         break;
00124     case 'S':
00125         res->type = (res->flags & (WPRINTF_SHORT|WPRINTF_WIDE)) ? WPR_STRING : WPR_WSTRING;
00126         break;
00127     case 'u':
00128         res->type = WPR_UNSIGNED;
00129         break;
00130     case 'X':
00131         res->flags |= WPRINTF_UPPER_HEX;
00132         /* fall through */
00133     case 'x':
00134         res->type = WPR_HEXA;
00135         break;
00136     default: /* unknown format char */
00137         res->type = WPR_UNKNOWN;
00138         p--;  /* print format as normal char */
00139         break;
00140     }
00141     return (INT)(p - format) + 1;
00142 }
00143 
00144 
00145 /***********************************************************************
00146  *           WPRINTF_ParseFormatW
00147  *
00148  * Parse a format specification. A format specification has the form:
00149  *
00150  * [-][#][0][width][.precision]type
00151  *
00152  * Return value is the length of the format specification in characters.
00153  */
00154 static INT WPRINTF_ParseFormatW( LPCWSTR format, WPRINTF_FORMAT *res )
00155 {
00156     LPCWSTR p = format;
00157 
00158     res->flags = 0;
00159     res->width = 0;
00160     res->precision = 0;
00161     if (*p == '-') { res->flags |= WPRINTF_LEFTALIGN; p++; }
00162     if (*p == '#') { res->flags |= WPRINTF_PREFIX_HEX; p++; }
00163     if (*p == '0') { res->flags |= WPRINTF_ZEROPAD; p++; }
00164     while ((*p >= '0') && (*p <= '9'))  /* width field */
00165     {
00166         res->width = res->width * 10 + *p - '0';
00167         p++;
00168     }
00169     if (*p == '.')  /* precision field */
00170     {
00171         p++;
00172         while ((*p >= '0') && (*p <= '9'))
00173         {
00174             res->precision = res->precision * 10 + *p - '0';
00175             p++;
00176         }
00177     }
00178     if (*p == 'l') { res->flags |= WPRINTF_LONG; p++; }
00179     else if (*p == 'h') { res->flags |= WPRINTF_SHORT; p++; }
00180     else if (*p == 'w') { res->flags |= WPRINTF_WIDE; p++; }
00181     switch((CHAR)*p)
00182     {
00183     case 'c':
00184         res->type = (res->flags & WPRINTF_SHORT) ? WPR_CHAR : WPR_WCHAR;
00185         break;
00186     case 'C':
00187         res->type = (res->flags & WPRINTF_LONG) ? WPR_WCHAR : WPR_CHAR;
00188         break;
00189     case 'd':
00190     case 'i':
00191         res->type = WPR_SIGNED;
00192         break;
00193     case 's':
00194         res->type = ((res->flags & WPRINTF_SHORT) && !(res->flags & WPRINTF_WIDE)) ? WPR_STRING : WPR_WSTRING;
00195         break;
00196     case 'S':
00197         res->type = (res->flags & (WPRINTF_LONG|WPRINTF_WIDE)) ? WPR_WSTRING : WPR_STRING;
00198         break;
00199     case 'u':
00200         res->type = WPR_UNSIGNED;
00201         break;
00202     case 'X':
00203         res->flags |= WPRINTF_UPPER_HEX;
00204         /* fall through */
00205     case 'x':
00206         res->type = WPR_HEXA;
00207         break;
00208     default:
00209         res->type = WPR_UNKNOWN;
00210         p--;  /* print format as normal char */
00211         break;
00212     }
00213     return (INT)(p - format) + 1;
00214 }
00215 
00216 
00217 /***********************************************************************
00218  *           WPRINTF_GetLen
00219  */
00220 static UINT WPRINTF_GetLen( WPRINTF_FORMAT *format, WPRINTF_DATA *arg,
00221                               LPSTR number, UINT maxlen )
00222 {
00223     UINT len;
00224 
00225     if (format->flags & WPRINTF_LEFTALIGN) format->flags &= ~WPRINTF_ZEROPAD;
00226     if (format->width > maxlen) format->width = maxlen;
00227     switch(format->type)
00228     {
00229     case WPR_CHAR:
00230     case WPR_WCHAR:
00231         return (format->precision = 1);
00232     case WPR_STRING:
00233         if (!arg->lpcstr_view) arg->lpcstr_view = null_stringA;
00234         for (len = 0; !format->precision || (len < format->precision); len++)
00235             if (!*(arg->lpcstr_view + len)) break;
00236         if (len > maxlen) len = maxlen;
00237         return (format->precision = len);
00238     case WPR_WSTRING:
00239         if (!arg->lpcwstr_view) arg->lpcwstr_view = null_stringW;
00240         for (len = 0; !format->precision || (len < format->precision); len++)
00241             if (!*(arg->lpcwstr_view + len)) break;
00242         if (len > maxlen) len = maxlen;
00243         return (format->precision = len);
00244     case WPR_SIGNED:
00245         len = sprintf( number, "%d", arg->int_view );
00246         break;
00247     case WPR_UNSIGNED:
00248         len = sprintf( number, "%u", (UINT)arg->int_view );
00249         break;
00250     case WPR_HEXA:
00251         len = sprintf( number,
00252                        (format->flags & WPRINTF_UPPER_HEX) ? "%X" : "%x",
00253                        (UINT)arg->int_view);
00254         break;
00255     default:
00256         return 0;
00257     }
00258     if (len > maxlen) len = maxlen;
00259     if (format->precision < len) format->precision = len;
00260     if (format->precision > maxlen) format->precision = maxlen;
00261     if ((format->flags & WPRINTF_ZEROPAD) && (format->width > format->precision))
00262         format->precision = format->width;
00263     if (format->flags & WPRINTF_PREFIX_HEX) len += 2;
00264     return len;
00265 }
00266 
00267 
00268 #ifndef __WIN32OS2__
00269 /***********************************************************************
00270  *           wvsnprintf16   (Not a Windows API)
00271  */
00272 static INT16 wvsnprintf16( LPSTR buffer, UINT16 maxlen, LPCSTR spec,
00273                            LPCVOID args )
00274 {
00275     WPRINTF_FORMAT format;
00276     LPSTR p = buffer;
00277     UINT i, len;
00278     CHAR number[20];
00279     WPRINTF_DATA cur_arg;
00280     SEGPTR seg_str;
00281 
00282     while (*spec && (maxlen > 1))
00283     {
00284         if (*spec != '%') { *p++ = *spec++; maxlen--; continue; }
00285         spec++;
00286         if (*spec == '%') { *p++ = *spec++; maxlen--; continue; }
00287         spec += WPRINTF_ParseFormatA( spec, &format );
00288         switch(format.type)
00289         {
00290         case WPR_WCHAR:  /* No Unicode in Win16 */
00291         case WPR_CHAR:
00292             cur_arg.char_view = VA_ARG16( args, CHAR );
00293             break;
00294         case WPR_WSTRING:  /* No Unicode in Win16 */
00295         case WPR_STRING:
00296             seg_str = VA_ARG16( args, SEGPTR );
00297             if (IsBadReadPtr16(seg_str, 1 )) cur_arg.lpcstr_view = "";
00298             else cur_arg.lpcstr_view = MapSL( seg_str );
00299             break;
00300         case WPR_SIGNED:
00301             if (!(format.flags & WPRINTF_LONG))
00302             {
00303                 cur_arg.int_view = VA_ARG16( args, INT16 );
00304                 break;
00305             }
00306             /* fall through */
00307         case WPR_HEXA:
00308         case WPR_UNSIGNED:
00309             if (format.flags & WPRINTF_LONG)
00310                 cur_arg.int_view = VA_ARG16( args, UINT );
00311             else
00312                 cur_arg.int_view = VA_ARG16( args, UINT16 );
00313             break;
00314         case WPR_UNKNOWN:
00315             continue;
00316         }
00317         len = WPRINTF_GetLen( &format, &cur_arg, number, maxlen - 1 );
00318         if (!(format.flags & WPRINTF_LEFTALIGN))
00319             for (i = format.precision; i < format.width; i++, maxlen--)
00320                 *p++ = ' ';
00321         switch(format.type)
00322         {
00323         case WPR_WCHAR:  /* No Unicode in Win16 */
00324         case WPR_CHAR:
00325             *p= cur_arg.char_view;
00326             if (*p != '\0') p++;
00327             else if (format.width > 1) *p++ = ' ';
00328             else len = 0;
00329             break;
00330         case WPR_WSTRING:  /* No Unicode in Win16 */
00331         case WPR_STRING:
00332             if (len) memcpy( p, cur_arg.lpcstr_view, len );
00333             p += len;
00334             break;
00335         case WPR_HEXA:
00336             if ((format.flags & WPRINTF_PREFIX_HEX) && (maxlen > 3))
00337             {
00338                 *p++ = '0';
00339                 *p++ = (format.flags & WPRINTF_UPPER_HEX) ? 'X' : 'x';
00340                 maxlen -= 2;
00341                 len -= 2;
00342             }
00343             /* fall through */
00344         case WPR_SIGNED:
00345         case WPR_UNSIGNED:
00346             for (i = len; i < format.precision; i++, maxlen--) *p++ = '0';
00347             if (len) memcpy( p, number, len );
00348             p += len;
00349             break;
00350         case WPR_UNKNOWN:
00351             continue;
00352         }
00353         if (format.flags & WPRINTF_LEFTALIGN)
00354             for (i = format.precision; i < format.width; i++, maxlen--)
00355                 *p++ = ' ';
00356         maxlen -= len;
00357     }
00358     *p = 0;
00359     return (maxlen > 1) ? (INT)(p - buffer) : -1;
00360 }
00361 #endif //!__WIN32OS2__
00362 
00363 
00364 /***********************************************************************
00365  *           wvsnprintfA   (USER32.@) (Not a Windows API, but we export it from USER32 anyway)
00366  */
00367 INT WINAPI wvsnprintfA( LPSTR buffer, UINT maxlen, LPCSTR spec, va_list args )
00368 {
00369     WPRINTF_FORMAT format;
00370     LPSTR p = buffer;
00371     UINT i, len;
00372     CHAR number[20];
00373     WPRINTF_DATA argData;
00374 
00375     TRACE("%p %u %s\n", buffer, maxlen, debugstr_a(spec));
00376 
00377     while (*spec && (maxlen > 1))
00378     {
00379         if (*spec != '%') { *p++ = *spec++; maxlen--; continue; }
00380         spec++;
00381         if (*spec == '%') { *p++ = *spec++; maxlen--; continue; }
00382         spec += WPRINTF_ParseFormatA( spec, &format );
00383 
00384         switch(format.type)
00385         {
00386         case WPR_WCHAR:
00387             argData.wchar_view = (WCHAR)va_arg( args, int );
00388             break;
00389         case WPR_CHAR:
00390             argData.char_view = (CHAR)va_arg( args, int );
00391             break;
00392         case WPR_STRING:
00393             argData.lpcstr_view = va_arg( args, LPCSTR );
00394             break;
00395         case WPR_WSTRING:
00396             argData.lpcwstr_view = va_arg( args, LPCWSTR );
00397             break;
00398         case WPR_HEXA:
00399         case WPR_SIGNED:
00400         case WPR_UNSIGNED:
00401             argData.int_view = va_arg( args, INT );
00402             break;
00403         default:
00404             argData.wchar_view = 0;
00405             break;
00406         }
00407 
00408         len = WPRINTF_GetLen( &format, &argData, number, maxlen - 1 );
00409         if (!(format.flags & WPRINTF_LEFTALIGN))
00410             for (i = format.precision; i < format.width; i++, maxlen--)
00411                 *p++ = ' ';
00412         switch(format.type)
00413         {
00414         case WPR_WCHAR:
00415             *p = argData.wchar_view;
00416             if (*p != '\0') p++;
00417             else if (format.width > 1) *p++ = ' ';
00418             else len = 0;
00419             break;
00420         case WPR_CHAR:
00421             *p = argData.char_view;
00422             if (*p != '\0') p++;
00423             else if (format.width > 1) *p++ = ' ';
00424             else len = 0;
00425             break;
00426         case WPR_STRING:
00427             memcpy( p, argData.lpcstr_view, len );
00428             p += len;
00429             break;
00430         case WPR_WSTRING:
00431             {
00432                 LPCWSTR ptr = argData.lpcwstr_view;
00433                 for (i = 0; i < len; i++) *p++ = (CHAR)*ptr++;
00434             }
00435             break;
00436         case WPR_HEXA:
00437             if ((format.flags & WPRINTF_PREFIX_HEX) && (maxlen > 3))
00438             {
00439                 *p++ = '0';
00440                 *p++ = (format.flags & WPRINTF_UPPER_HEX) ? 'X' : 'x';
00441                 maxlen -= 2;
00442                 len -= 2;
00443             }
00444             /* fall through */
00445         case WPR_SIGNED:
00446         case WPR_UNSIGNED:
00447             for (i = len; i < format.precision; i++, maxlen--) *p++ = '0';
00448             memcpy( p, number, len );
00449             p += len;
00450             break;
00451         case WPR_UNKNOWN:
00452             continue;
00453         }
00454         if (format.flags & WPRINTF_LEFTALIGN)
00455             for (i = format.precision; i < format.width; i++, maxlen--)
00456                 *p++ = ' ';
00457         maxlen -= len;
00458     }
00459     *p = 0;
00460     TRACE("%s\n",debugstr_a(buffer));
00461     return (maxlen > 1) ? (INT)(p - buffer) : -1;
00462 }
00463 
00464 
00465 /***********************************************************************
00466  *           wvsnprintfW   (USER32.@) (Not a Windows API, but we export it from USER32 anyway)
00467  */
00468 INT WINAPI wvsnprintfW( LPWSTR buffer, UINT maxlen, LPCWSTR spec, va_list args )
00469 {
00470     WPRINTF_FORMAT format;
00471     LPWSTR p = buffer;
00472     UINT i, len;
00473     CHAR number[20];
00474     WPRINTF_DATA argData;
00475 
00476     TRACE("%p %u %s\n", buffer, maxlen, debugstr_w(spec));
00477 
00478     while (*spec && (maxlen > 1))
00479     {
00480         if (*spec != '%') { *p++ = *spec++; maxlen--; continue; }
00481         spec++;
00482         if (*spec == '%') { *p++ = *spec++; maxlen--; continue; }
00483         spec += WPRINTF_ParseFormatW( spec, &format );
00484 
00485         switch(format.type)
00486         {
00487         case WPR_WCHAR:
00488             argData.wchar_view = (WCHAR)va_arg( args, int );
00489             break;
00490         case WPR_CHAR:
00491             argData.char_view = (CHAR)va_arg( args, int );
00492             break;
00493         case WPR_STRING:
00494             argData.lpcstr_view = va_arg( args, LPCSTR );
00495             break;
00496         case WPR_WSTRING:
00497             argData.lpcwstr_view = va_arg( args, LPCWSTR );
00498             break;
00499         case WPR_HEXA:
00500         case WPR_SIGNED:
00501         case WPR_UNSIGNED:
00502             argData.int_view = va_arg( args, INT );
00503             break;
00504         default:
00505             argData.wchar_view = 0;
00506             break;
00507         }
00508 
00509         len = WPRINTF_GetLen( &format, &argData, number, maxlen - 1 );
00510         if (!(format.flags & WPRINTF_LEFTALIGN))
00511             for (i = format.precision; i < format.width; i++, maxlen--)
00512                 *p++ = ' ';
00513         switch(format.type)
00514         {
00515         case WPR_WCHAR:
00516             *p = argData.wchar_view;
00517             if (*p != '\0') p++;
00518             else if (format.width > 1) *p++ = ' ';
00519             else len = 0;
00520             break;
00521         case WPR_CHAR:
00522             *p = argData.char_view;
00523             if (*p != '\0') p++;
00524             else if (format.width > 1) *p++ = ' ';
00525             else len = 0;
00526             break;
00527         case WPR_STRING:
00528             {
00529                 LPCSTR ptr = argData.lpcstr_view;
00530                 for (i = 0; i < len; i++) *p++ = (WCHAR)*ptr++;
00531             }
00532             break;
00533         case WPR_WSTRING:
00534             if (len) memcpy( p, argData.lpcwstr_view, len * sizeof(WCHAR) );
00535             p += len;
00536             break;
00537         case WPR_HEXA:
00538             if ((format.flags & WPRINTF_PREFIX_HEX) && (maxlen > 3))
00539             {
00540                 *p++ = '0';
00541                 *p++ = (format.flags & WPRINTF_UPPER_HEX) ? 'X' : 'x';
00542                 maxlen -= 2;
00543                 len -= 2;
00544             }
00545             /* fall through */
00546         case WPR_SIGNED:
00547         case WPR_UNSIGNED:
00548             for (i = len; i < format.precision; i++, maxlen--) *p++ = '0';
00549             for (i = 0; i < len; i++) *p++ = (WCHAR)number[i];
00550             break;
00551         case WPR_UNKNOWN:
00552             continue;
00553         }
00554         if (format.flags & WPRINTF_LEFTALIGN)
00555             for (i = format.precision; i < format.width; i++, maxlen--)
00556                 *p++ = ' ';
00557         maxlen -= len;
00558     }
00559     *p = 0;
00560     TRACE("%s\n",debugstr_w(buffer));
00561     return (maxlen > 1) ? (INT)(p - buffer) : -1;
00562 }
00563 
00564 
00565 #ifndef __WIN32OS2__
00566 /***********************************************************************
00567  *           wvsprintf16   (USER.421)
00568  */
00569 INT16 WINAPI wvsprintf16( LPSTR buffer, LPCSTR spec, LPCVOID args )
00570 {
00571     INT16 res;
00572 
00573     TRACE("for %p got:\n",buffer);
00574     res = wvsnprintf16( buffer, 1024, spec, args );
00575     return ( res == -1 ) ? 1024 : res;
00576 }
00577 #endif //!__WIN32OS2__
00578 
00579 
00580 /***********************************************************************
00581  *           wvsprintfA   (USER32.@)
00582  */
00583 INT WINAPI wvsprintfA( LPSTR buffer, LPCSTR spec, va_list args )
00584 {
00585     INT res = wvsnprintfA( buffer, 1024, spec, args );
00586     return ( res == -1 ) ? 1024 : res;
00587 }
00588 
00589 
00590 /***********************************************************************
00591  *           wvsprintfW   (USER32.@)
00592  */
00593 INT WINAPI wvsprintfW( LPWSTR buffer, LPCWSTR spec, va_list args )
00594 {
00595     INT res = wvsnprintfW( buffer, 1024, spec, args );
00596     return ( res == -1 ) ? 1024 : res;
00597 }
00598 
00599 #ifndef __WIN32OS2__
00600 /***********************************************************************
00601  *           wsprintf16   (USER.420)
00602  */
00603 INT16 WINAPIV wsprintf16(void)
00604 {
00605     VA_LIST16 valist;
00606     INT16 res;
00607     SEGPTR buffer, spec;
00608 
00609     VA_START16( valist );
00610     buffer = VA_ARG16( valist, SEGPTR );
00611     spec   = VA_ARG16( valist, SEGPTR );
00612     res = wvsnprintf16( MapSL(buffer), 1024, MapSL(spec), valist );
00613     VA_END16( valist );
00614     return ( res == -1 ) ? 1024 : res;
00615 }
00616 #endif //!__WIN32OS2__
00617 
00618 
00619 /***********************************************************************
00620  *           wsprintfA   (USER32.@)
00621  */
00622 INT WINAPIV wsprintfA( LPSTR buffer, LPCSTR spec, ... )
00623 {
00624     va_list valist;
00625     INT res;
00626 
00627     va_start( valist, spec );
00628     res = wvsnprintfA( buffer, 1024, spec, valist );
00629     va_end( valist );
00630     return ( res == -1 ) ? 1024 : res;
00631 }
00632 
00633 
00634 /***********************************************************************
00635  *           wsprintfW   (USER32.@)
00636  */
00637 INT WINAPIV wsprintfW( LPWSTR buffer, LPCWSTR spec, ... )
00638 {
00639     va_list valist;
00640     INT res;
00641 
00642     va_start( valist, spec );
00643     res = wvsnprintfW( buffer, 1024, spec, valist );
00644     va_end( valist );
00645     return ( res == -1 ) ? 1024 : res;
00646 }
00647 
00648 /***********************************************************************
00649  *           wsnprintfA   (Not a Windows API)
00650  */
00651 INT WINAPIV wsnprintfA( LPSTR buffer, UINT maxlen, LPCSTR spec, ... )
00652 {
00653     va_list valist;
00654     INT res;
00655 
00656     va_start( valist, spec );
00657     res = wvsnprintfA( buffer, maxlen, spec, valist );
00658     va_end( valist );
00659     return res;
00660 }
00661 
00662 /***********************************************************************
00663  *           wsnprintfW   (Not a Windows API)
00664  */
00665 INT WINAPIV wsnprintfW( LPWSTR buffer, UINT maxlen, LPCWSTR spec, ... )
00666 {
00667     va_list valist;
00668     INT res;
00669 
00670     va_start( valist, spec );
00671     res = wvsnprintfW( buffer, maxlen, spec, valist );
00672     va_end( valist );
00673     return res;
00674 }

Generated on Wed Jan 23 23:17:56 2002 for ODIN-user32 by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001