diff --git a/dlls/kernel/debugger.c b/dlls/kernel/debugger.c index c1e95ee5487..b00af11a205 100644 --- a/dlls/kernel/debugger.c +++ b/dlls/kernel/debugger.c @@ -347,26 +347,19 @@ BOOL WINAPI IsDebuggerPresent(void) /*********************************************************************** * _DebugOutput (KERNEL.328) */ -void WINAPIV _DebugOutput( void ) +void WINAPIV _DebugOutput( WORD flags, LPCSTR spec, VA_LIST16 valist ) { - VA_LIST16 valist; - WORD flags; - SEGPTR spec; char caller[101]; /* Decode caller address */ if (!GetModuleName16( GetExePtr(CURRENT_STACK16->cs), caller, sizeof(caller) )) sprintf( caller, "%04X:%04X", CURRENT_STACK16->cs, CURRENT_STACK16->ip ); - /* Build debug message string */ - VA_START16( valist ); - flags = VA_ARG16( valist, WORD ); - spec = VA_ARG16( valist, SEGPTR ); /* FIXME: cannot use wvsnprintf16 from kernel */ - /* wvsnprintf16( temp, sizeof(temp), MapSL(spec), valist ); */ + /* wvsnprintf16( temp, sizeof(temp), spec, valist ); */ /* Output */ - FIXME("%s %04x %s\n", caller, flags, debugstr_a(MapSL(spec)) ); + FIXME("%s %04x %s\n", caller, flags, debugstr_a(spec) ); } /*********************************************************************** diff --git a/dlls/kernel/krnl386.exe.spec b/dlls/kernel/krnl386.exe.spec index c001f0e9560..4706ae32f10 100644 --- a/dlls/kernel/krnl386.exe.spec +++ b/dlls/kernel/krnl386.exe.spec @@ -267,7 +267,7 @@ 325 pascal16 LogParamError(word ptr ptr) LogParamError16 326 pascal16 IsRomFile(word) IsRomFile16 327 pascal -register K327() HandleParamError -328 pascal16 _DebugOutput() _DebugOutput +328 varargs -ret16 _DebugOutput(word str) _DebugOutput 329 pascal16 K329(str word) DebugFillBuffer 332 variable THHOOK(0 0 0 0 0 0 0 0) 334 pascal16 IsBadReadPtr(segptr word) IsBadReadPtr16 diff --git a/dlls/kernel/relay16.c b/dlls/kernel/relay16.c index 7fdd1276de1..9eb1020445d 100644 --- a/dlls/kernel/relay16.c +++ b/dlls/kernel/relay16.c @@ -194,7 +194,7 @@ void RELAY_DebugCallFrom16( CONTEXT86 *context ) if (!call) return; /* happens for the two snoop register relays */ if (!RELAY_ShowDebugmsgRelay(funstr)) return; DPRINTF( "%04lx:Call %s(",GetCurrentThreadId(),funstr); - VA_START16( args16 ); + args16 = (char *)(frame + 1); if (call->lret == 0xcb66) /* cdecl */ { @@ -276,7 +276,6 @@ void RELAY_DebugCallFrom16( CONTEXT86 *context ) } DPRINTF( ") ret=%04x:%04x ds=%04x\n", frame->cs, frame->ip, frame->ds ); - VA_END16( args16 ); if (call->arg_types[0] & ARG_REGISTER) DPRINTF(" AX=%04x BX=%04x CX=%04x DX=%04x SI=%04x DI=%04x ES=%04x EFL=%08lx\n", diff --git a/dlls/msvideo/msvideo.spec b/dlls/msvideo/msvideo.spec index 318871ce540..7690c18786d 100644 --- a/dlls/msvideo/msvideo.spec +++ b/dlls/msvideo/msvideo.spec @@ -45,7 +45,7 @@ 204 pascal ICClose(word) ICClose16 205 pascal ICSendMessage(word word long long) ICSendMessage16 206 pascal16 ICOpenFunction(long long word segptr) ICOpenFunction16 -207 pascal _ICMessage() ICMessage16 +207 varargs _ICMessage(word word word) ICMessage16 212 pascal ICGetInfo(word segptr long) ICGetInfo16 213 pascal16 ICLocate(long long ptr ptr word) ICLocate16 224 cdecl _ICCompress(word long segptr segptr segptr segptr segptr segptr long long long segptr segptr) ICCompress16 diff --git a/dlls/msvideo/msvideo16.c b/dlls/msvideo/msvideo16.c index c0c84afb52e..64d39b06331 100644 --- a/dlls/msvideo/msvideo16.c +++ b/dlls/msvideo/msvideo16.c @@ -25,8 +25,8 @@ #include "msvideo_private.h" #include "winver.h" +#include "winnls.h" #include "vfw16.h" -#include "stackframe.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(msvideo); @@ -139,23 +139,13 @@ LRESULT WINAPI ICClose16(HIC16 hic) /*********************************************************************** * _ICMessage [MSVIDEO.207] */ -LRESULT VFWAPIV ICMessage16(void) +LRESULT VFWAPIV ICMessage16( HIC16 hic, UINT16 msg, UINT16 cb, VA_LIST16 valist ) { - HIC16 hic; - UINT16 msg; - UINT16 cb; LPWORD lpData; SEGPTR segData; LRESULT ret; UINT16 i; - VA_LIST16 valist; - - VA_START16(valist); - hic = VA_ARG16(valist, HIC16); - msg = VA_ARG16(valist, UINT16); - cb = VA_ARG16(valist, UINT16); - lpData = HeapAlloc(GetProcessHeap(), 0, cb); TRACE("0x%08lx, %u, %u, ...)\n", (DWORD) hic, msg, cb); @@ -165,7 +155,6 @@ LRESULT VFWAPIV ICMessage16(void) lpData[i] = VA_ARG16(valist, WORD); } - VA_END16(valist); segData = MapLS(lpData); ret = ICSendMessage16(hic, msg, segData, (DWORD) cb); UnMapLS(segData); diff --git a/dlls/msvideo/vfw16.h b/dlls/msvideo/vfw16.h index 4fd4d944f15..410aa1a7cd5 100644 --- a/dlls/msvideo/vfw16.h +++ b/dlls/msvideo/vfw16.h @@ -113,7 +113,7 @@ LRESULT VFWAPI ICGetInfo16(HIC16,ICINFO16 *,DWORD); BOOL16 VFWAPI ICInfo16(DWORD,DWORD,ICINFO16 *); HIC16 VFWAPI ICLocate16(DWORD,DWORD,LPBITMAPINFOHEADER, LPBITMAPINFOHEADER,WORD); -LRESULT VFWAPIV ICMessage16(void); +LRESULT VFWAPIV ICMessage16( HIC16 hic, UINT16 msg, UINT16 cb, VA_LIST16 valist ); HIC16 VFWAPI ICOpen16(DWORD,DWORD,UINT16); HIC16 VFWAPI ICOpenFunction16(DWORD,DWORD,UINT16,FARPROC16); LRESULT VFWAPI ICSendMessage16(HIC16,UINT16,DWORD,DWORD); diff --git a/dlls/user/user.exe.spec b/dlls/user/user.exe.spec index 02c28a2cbcc..12f64ec1331 100644 --- a/dlls/user/user.exe.spec +++ b/dlls/user/user.exe.spec @@ -387,7 +387,7 @@ 416 pascal16 TrackPopupMenu(word word s_word s_word s_word word ptr) TrackPopupMenu16 417 pascal GetMenuCheckMarkDimensions() GetMenuCheckMarkDimensions 418 pascal16 SetMenuItemBitmaps(word word word word word) SetMenuItemBitmaps16 -420 pascal16 _wsprintf() wsprintf16 +420 varargs -ret16 _wsprintf(ptr str) wsprintf16 421 pascal16 wvsprintf(ptr str ptr) wvsprintf16 422 pascal16 DlgDirSelectEx(word ptr word word) DlgDirSelectEx16 423 pascal16 DlgDirSelectComboBoxEx(word ptr word word) DlgDirSelectComboBoxEx16 diff --git a/dlls/user/wsprintf.c b/dlls/user/wsprintf.c index 8ec547b4016..a822d7f32de 100644 --- a/dlls/user/wsprintf.c +++ b/dlls/user/wsprintf.c @@ -32,7 +32,6 @@ #include "wine/winbase16.h" #include "wine/winuser16.h" -#include "stackframe.h" #include "wine/debug.h" @@ -284,8 +283,7 @@ static UINT WPRINTF_GetLen( WPRINTF_FORMAT *format, WPRINTF_DATA *arg, /*********************************************************************** * wvsnprintf16 (Not a Windows API) */ -static INT16 wvsnprintf16( LPSTR buffer, UINT16 maxlen, LPCSTR spec, - LPCVOID args ) +static INT16 wvsnprintf16( LPSTR buffer, UINT16 maxlen, LPCSTR spec, VA_LIST16 args ) { WPRINTF_FORMAT format; LPSTR p = buffer; @@ -592,7 +590,7 @@ static INT wvsnprintfW( LPWSTR buffer, UINT maxlen, LPCWSTR spec, va_list args ) /*********************************************************************** * wvsprintf (USER.421) */ -INT16 WINAPI wvsprintf16( LPSTR buffer, LPCSTR spec, LPCVOID args ) +INT16 WINAPI wvsprintf16( LPSTR buffer, LPCSTR spec, VA_LIST16 args ) { INT16 res; @@ -625,17 +623,11 @@ INT WINAPI wvsprintfW( LPWSTR buffer, LPCWSTR spec, va_list args ) /*********************************************************************** * _wsprintf (USER.420) */ -INT16 WINAPIV wsprintf16(void) +INT16 WINAPIV wsprintf16( LPSTR buffer, LPCSTR spec, VA_LIST16 valist ) { - VA_LIST16 valist; INT16 res; - SEGPTR buffer, spec; - VA_START16( valist ); - buffer = VA_ARG16( valist, SEGPTR ); - spec = VA_ARG16( valist, SEGPTR ); - res = wvsnprintf16( MapSL(buffer), 1024, MapSL(spec), valist ); - VA_END16( valist ); + res = wvsnprintf16( buffer, 1024, spec, valist ); return ( res == -1 ) ? 1024 : res; } diff --git a/include/stackframe.h b/include/stackframe.h index 237a97f7748..a54c9e2f428 100644 --- a/include/stackframe.h +++ b/include/stackframe.h @@ -73,15 +73,7 @@ typedef struct _STACK16FRAME #define CURRENT_DS (CURRENT_STACK16->ds) /* varargs lists on the 16-bit stack */ - -typedef void *VA_LIST16; - -#define __VA_ROUNDED16(type) \ - ((sizeof(type) + sizeof(WORD) - 1) / sizeof(WORD) * sizeof(WORD)) #define VA_START16(list) ((list) = (VA_LIST16)(CURRENT_STACK16 + 1)) -#define VA_ARG16(list,type) \ - (((list) = (VA_LIST16)((char *)(list) + __VA_ROUNDED16(type))), \ - *((type *)(void *)((char *)(list) - __VA_ROUNDED16(type)))) #define VA_END16(list) ((void)0) diff --git a/include/wine/windef16.h b/include/wine/windef16.h index 610a8c9178b..4c7cf5c6e79 100644 --- a/include/wine/windef16.h +++ b/include/wine/windef16.h @@ -39,6 +39,14 @@ typedef UINT16 *LPUINT16; #define MAKESEGPTR(seg,off) ((SEGPTR)MAKELONG(off,seg)) +typedef WORD *VA_LIST16; + +#define __VA_ROUNDED16(type) \ + ((sizeof(type) + sizeof(WORD) - 1) / sizeof(WORD) * sizeof(WORD)) +#define VA_ARG16(list,type) \ + (((list) = (VA_LIST16)((char *)(list) + __VA_ROUNDED16(type))), \ + *((type *)(void *)((char *)(list) - __VA_ROUNDED16(type)))) + #define HFILE_ERROR16 ((HFILE16)-1) #define DECLARE_HANDLE16(a) \ diff --git a/include/wine/winuser16.h b/include/wine/winuser16.h index c53f2e76293..f0499f846bd 100644 --- a/include/wine/winuser16.h +++ b/include/wine/winuser16.h @@ -937,7 +937,7 @@ HWND16 WINAPI WindowFromDC16(HDC16); HWND16 WINAPI WindowFromPoint16(POINT16); BOOL16 WINAPI WinHelp16(HWND16,LPCSTR,UINT16,DWORD); UINT16 WINAPI WNetAddConnection16(LPCSTR,LPCSTR,LPCSTR); -INT16 WINAPI wvsprintf16(LPSTR,LPCSTR,LPCVOID); +INT16 WINAPI wvsprintf16(LPSTR,LPCSTR,VA_LIST16); BOOL16 WINAPI DrawState16A(HDC16,HBRUSH16,DRAWSTATEPROC16,LPARAM,WPARAM16,INT16,INT16,INT16,INT16,UINT16); BOOL16 WINAPI IsDialogMessage16(HWND16,MSG16*); INT16 WINAPI GetCommError16(INT16,LPCOMSTAT16); diff --git a/tools/winebuild/build.h b/tools/winebuild/build.h index 84d6a9a398c..92f11beb6bf 100644 --- a/tools/winebuild/build.h +++ b/tools/winebuild/build.h @@ -34,8 +34,7 @@ typedef enum { TYPE_VARIABLE, /* variable */ - TYPE_PASCAL_16, /* pascal function with 16-bit return (Win16) */ - TYPE_PASCAL, /* pascal function with 32-bit return (Win16) */ + TYPE_PASCAL, /* pascal function (Win16) */ TYPE_ABS, /* absolute value (Win16) */ TYPE_STUB, /* unimplemented stub */ TYPE_STDCALL, /* stdcall function (Win32) */ @@ -98,11 +97,12 @@ typedef struct /* entry point flags */ #define FLAG_NORELAY 0x01 /* don't use relay debugging for this function */ #define FLAG_NONAME 0x02 /* don't import function by name */ -#define FLAG_RET64 0x04 /* function returns a 64-bit value */ -#define FLAG_I386 0x08 /* function is i386 only */ -#define FLAG_REGISTER 0x10 /* use register calling convention */ -#define FLAG_INTERRUPT 0x20 /* function is an interrupt handler */ -#define FLAG_PRIVATE 0x40 /* function is private (cannot be imported) */ +#define FLAG_RET16 0x04 /* function returns a 16-bit value */ +#define FLAG_RET64 0x08 /* function returns a 64-bit value */ +#define FLAG_I386 0x10 /* function is i386 only */ +#define FLAG_REGISTER 0x20 /* use register calling convention */ +#define FLAG_INTERRUPT 0x40 /* function is an interrupt handler */ +#define FLAG_PRIVATE 0x80 /* function is private (cannot be imported) */ #define FLAG_FORWARD 0x100 /* function is a forwarded name */ diff --git a/tools/winebuild/parser.c b/tools/winebuild/parser.c index 8cca02ede0e..26a2b347533 100644 --- a/tools/winebuild/parser.c +++ b/tools/winebuild/parser.c @@ -44,7 +44,6 @@ static FILE *input_file; static const char * const TypeNames[TYPE_NBTYPES] = { "variable", /* TYPE_VARIABLE */ - "pascal16", /* TYPE_PASCAL_16 */ "pascal", /* TYPE_PASCAL */ "equate", /* TYPE_ABS */ "stub", /* TYPE_STUB */ @@ -58,6 +57,7 @@ static const char * const FlagNames[] = { "norelay", /* FLAG_NORELAY */ "noname", /* FLAG_NONAME */ + "ret16", /* FLAG_RET16 */ "ret64", /* FLAG_RET64 */ "i386", /* FLAG_I386 */ "register", /* FLAG_REGISTER */ @@ -212,14 +212,9 @@ static int ParseExportFunction( ORDDEF *odp ) error( "'stdcall' not supported for Win16\n" ); return 0; } - if (odp->type == TYPE_VARARGS) - { - error( "'varargs' not supported for Win16\n" ); - return 0; - } break; case SPEC_WIN32: - if ((odp->type == TYPE_PASCAL) || (odp->type == TYPE_PASCAL_16)) + if (odp->type == TYPE_PASCAL) { error( "'pascal' not supported for Win32\n" ); return 0; @@ -456,8 +451,17 @@ static int ParseOrdinal(int ordinal) if (odp->type >= TYPE_NBTYPES) { - error( "Expected type after ordinal, found '%s' instead\n", token ); - goto error; + /* special case for backwards compatibility */ + if (!strcmp( token, "pascal16" )) + { + odp->type = TYPE_PASCAL; + odp->flags |= FLAG_RET16; + } + else + { + error( "Expected type after ordinal, found '%s' instead\n", token ); + goto error; + } } if (!(token = GetToken(0))) goto error; @@ -473,7 +477,6 @@ static int ParseOrdinal(int ordinal) case TYPE_VARIABLE: if (!ParseVariable( odp )) goto error; break; - case TYPE_PASCAL_16: case TYPE_PASCAL: case TYPE_STDCALL: case TYPE_VARARGS: diff --git a/tools/winebuild/spec16.c b/tools/winebuild/spec16.c index 9be8747c17a..948949db1a7 100644 --- a/tools/winebuild/spec16.c +++ b/tools/winebuild/spec16.c @@ -250,7 +250,7 @@ static int BuildModule16( FILE *outfile, int max_code_offset, { case TYPE_CDECL: case TYPE_PASCAL: - case TYPE_PASCAL_16: + case TYPE_VARARGS: case TYPE_STUB: selector = 1; /* Code selector */ break; @@ -344,12 +344,14 @@ static void BuildCallFrom16Func( FILE *outfile, const char *profile, const char int short_ret = 0; int reg_func = 0; int usecdecl = 0; + int varargs = 0; const char *args = profile + 7; char *ret_type; /* Parse function type */ if (!strncmp( "c_", profile, 2 )) usecdecl = 1; + else if (!strncmp( "v_", profile, 2 )) varargs = usecdecl = 1; else if (strncmp( "p_", profile, 2 )) { fprintf( stderr, "Invalid function name '%s', ignored\n", profile ); @@ -382,7 +384,8 @@ static void BuildCallFrom16Func( FILE *outfile, const char *profile, const char ret_type = reg_func? "void" : short_ret ? "unsigned short" : "unsigned int"; - fprintf( outfile, "typedef %s (__stdcall *proc_%s_t)( ", ret_type, profile ); + fprintf( outfile, "typedef %s (%s*proc_%s_t)( ", + ret_type, usecdecl ? "" : "__stdcall ", profile ); args = profile + 7; for ( i = 0; args[i]; i++ ) { @@ -395,7 +398,7 @@ static void BuildCallFrom16Func( FILE *outfile, const char *profile, const char case 'p': case 't': fprintf( outfile, "void *" ); break; } } - if ( reg_func ) + if (reg_func || varargs) fprintf( outfile, "%svoid *", i? ", " : "" ); else if ( !i ) fprintf( outfile, "void" ); @@ -447,6 +450,8 @@ static void BuildCallFrom16Func( FILE *outfile, const char *profile, const char } if ( reg_func ) fprintf( outfile, "%s context", i? ",\n" : "" ); + else if (varargs) + fprintf( outfile, "%s args + %d", i? ",\n" : "", argsize ); fprintf( outfile, " );\n}\n\n" ); } @@ -459,10 +464,11 @@ static const char *get_function_name( const ORDDEF *odp ) static char buffer[80]; sprintf( buffer, "%s_%s_%s", - (odp->type == TYPE_CDECL) ? "c" : "p", + (odp->type == TYPE_PASCAL) ? "p" : + (odp->type == TYPE_VARARGS) ? "v" : "c", (odp->flags & FLAG_REGISTER) ? "regs" : (odp->flags & FLAG_INTERRUPT) ? "intr" : - (odp->type == TYPE_PASCAL_16) ? "word" : "long", + (odp->flags & FLAG_RET16) ? "word" : "long", odp->u.func.arg_types ); return buffer; } @@ -476,23 +482,20 @@ static int Spec16TypeCompare( const void *e1, const void *e2 ) const ORDDEF *odp1 = *(const ORDDEF **)e1; const ORDDEF *odp2 = *(const ORDDEF **)e2; int retval; + int type1 = odp1->type; + int type2 = odp2->type; - int type1 = (odp1->type == TYPE_CDECL) ? 0 - : (odp1->type == TYPE_PASCAL_16) ? 1 : 2; + if (type1 == TYPE_STUB) type1 = TYPE_CDECL; + if (type2 == TYPE_STUB) type2 = TYPE_CDECL; - int type2 = (odp2->type == TYPE_CDECL) ? 0 - : (odp2->type == TYPE_PASCAL_16) ? 1 : 2; + if ((retval = type1 - type2) != 0) return retval; - if (odp1->flags & FLAG_REGISTER) type1 += 4; - if (odp1->flags & FLAG_INTERRUPT) type1 += 8; - if (odp2->flags & FLAG_REGISTER) type2 += 4; - if (odp2->flags & FLAG_INTERRUPT) type2 += 8; + type1 = odp1->flags & (FLAG_RET16|FLAG_REGISTER|FLAG_INTERRUPT); + type2 = odp2->flags & (FLAG_RET16|FLAG_REGISTER|FLAG_INTERRUPT); - retval = type1 - type2; - if ( !retval ) - retval = strcmp( odp1->u.func.arg_types, odp2->u.func.arg_types ); + if ((retval = type1 - type2) != 0) return retval; - return retval; + return strcmp( odp1->u.func.arg_types, odp2->u.func.arg_types ); } @@ -598,7 +601,7 @@ void BuildSpec16File( FILE *outfile ) { case TYPE_CDECL: case TYPE_PASCAL: - case TYPE_PASCAL_16: + case TYPE_VARARGS: case TYPE_STUB: typelist[nFuncs++] = odp; @@ -638,7 +641,7 @@ void BuildSpec16File( FILE *outfile ) { case TYPE_CDECL: case TYPE_PASCAL: - case TYPE_PASCAL_16: + case TYPE_VARARGS: fprintf( outfile, "extern void %s();\n", odp->link_name ); break; default: @@ -682,7 +685,7 @@ void BuildSpec16File( FILE *outfile ) int j, argsize = 0; strcpy( profile, get_function_name( typelist[i] )); - if ( typelist[i]->type != TYPE_CDECL ) + if ( typelist[i]->type == TYPE_PASCAL ) for ( arg = typelist[i]->u.func.arg_types; *arg; arg++ ) switch ( *arg ) { @@ -717,13 +720,13 @@ void BuildSpec16File( FILE *outfile ) arg_types[j / 10] |= type << (3 * (j % 10)); } if (typelist[i]->flags & (FLAG_REGISTER|FLAG_INTERRUPT)) arg_types[0] |= ARG_REGISTER; - if (typelist[i]->type == TYPE_PASCAL_16) arg_types[0] |= ARG_RET16; + if (typelist[i]->flags & FLAG_RET16) arg_types[0] |= ARG_RET16; #ifdef __i386__ fprintf( outfile, " { 0x68, __wine_%s_CallFrom16_%s, 0x9a, __wine_call_from_16_%s,\n", make_c_identifier(dll_file_name), profile, (typelist[i]->flags & (FLAG_REGISTER|FLAG_INTERRUPT)) ? "regs": - typelist[i]->type == TYPE_PASCAL_16? "word" : "long" ); + (typelist[i]->flags & FLAG_RET16) ? "word" : "long" ); if (argsize) fprintf( outfile, " 0x%04x, 0xca66, %d, { 0x%08x, 0x%08x } },\n", code_selector, argsize, arg_types[0], arg_types[1] ); @@ -759,7 +762,7 @@ void BuildSpec16File( FILE *outfile ) case TYPE_CDECL: case TYPE_PASCAL: - case TYPE_PASCAL_16: + case TYPE_VARARGS: case TYPE_STUB: type = bsearch( &odp, typelist, nTypes, sizeof(ORDDEF *), Spec16TypeCompare ); assert( type ); diff --git a/tools/winebuild/winebuild.man.in b/tools/winebuild/winebuild.man.in index 7bd7632baba..05f74b46ef0 100644 --- a/tools/winebuild/winebuild.man.in +++ b/tools/winebuild/winebuild.man.in @@ -225,6 +225,9 @@ only). .B -noname The entry point will be imported by ordinal instead of by name. .TP +.B -ret16 +The function returns a 16-bit value (Win16 only). +.TP .B -ret64 The function returns a 64-bit value (Win32 only). .TP @@ -261,17 +264,21 @@ should be one of: .B stdcall for a normal Win32 function .TP +.B pascal +for a normal Win16 function +.TP .B cdecl -for a Win32 function using the C calling convention +for a Win16 or Win32 function using the C calling convention .TP .B varargs -for a Win32 function taking a variable number of arguments -.TP -.B pascal -for a Win16 function returning a 32-bit value +for a Win16 or Win32 function using the C calling convention with a +variable number of arguments .TP .B pascal16 -for a Win16 function returning a 16-bit value. +for a Win16 function returning a 16-bit value; this type is +deprecated, use +.B pascal -ret16 +instead .RE .PP .I args @@ -331,13 +338,13 @@ shows how long lines can be split using a backslash: 100 pascal CreateWindow(ptr ptr long s_word s_word s_word \\ s_word word word word ptr) WIN_CreateWindow .PP -To declare a function using a variable number of arguments in Win16, -specify the function as taking no arguments. The arguments are then -available with CURRENT_STACK16->args. In Win32, specify the function -as +To declare a function using a variable number of arguments, specify +the function as .B varargs -and declare it with a '...' parameter in the C file. See the -wsprintf* functions in user.exe.spec and user32.spec for an example. +and declare it in the C file with a '...' parameter for a Win32 +function, or with an extra VA_LIST16 argument for a Win16 function. +See the wsprintf* functions in user.exe.spec and user32.spec for an +example. .SS "Variable ordinals" Syntax: .br