Rob Shearman : widl: Add support for varargs functions.
Alexandre Julliard
julliard at winehq.org
Mon Nov 9 15:14:20 CST 2009
Module: wine
Branch: master
Commit: 97d5f3401d94af2c662c4e45b24d8687ca274d1b
URL: http://source.winehq.org/git/wine.git/?a=commit;h=97d5f3401d94af2c662c4e45b24d8687ca274d1b
Author: Rob Shearman <robertshearman at gmail.com>
Date: Sat Nov 7 15:55:13 2009 +0100
widl: Add support for varargs functions.
---
dlls/rpcrt4/tests/server.c | 3 ++
dlls/rpcrt4/tests/server.idl | 2 +
tools/widl/header.c | 68 ++++++++++++++++++++++-------------------
tools/widl/parser.l | 1 +
tools/widl/parser.y | 12 +++++--
5 files changed, 51 insertions(+), 35 deletions(-)
diff --git a/dlls/rpcrt4/tests/server.c b/dlls/rpcrt4/tests/server.c
index d9a9fcc..1205ea4 100644
--- a/dlls/rpcrt4/tests/server.c
+++ b/dlls/rpcrt4/tests/server.c
@@ -42,6 +42,9 @@ static NDR_SCONTEXT (WINAPI *pNDRSContextUnmarshall2)(RPC_BINDING_HANDLE, void*,
static RPC_STATUS (WINAPI *pRpcServerRegisterIfEx)(RPC_IF_HANDLE,UUID*, RPC_MGR_EPV*, unsigned int,
unsigned int,RPC_IF_CALLBACK_FN*);
+/* type check statements generated in header file */
+fnprintf *p_printf = printf;
+
static void InitFunctionPointers(void)
{
HMODULE hrpcrt4 = GetModuleHandleA("rpcrt4.dll");
diff --git a/dlls/rpcrt4/tests/server.idl b/dlls/rpcrt4/tests/server.idl
index fe2c075..d8e79bd 100644
--- a/dlls/rpcrt4/tests/server.idl
+++ b/dlls/rpcrt4/tests/server.idl
@@ -27,6 +27,8 @@ typedef struct tag_vector
int z;
} vector_t;
+typedef int fnprintf(const char *format, ...);
+
[
uuid(00000000-4114-0704-2301-000000000000),
#ifndef __midl
diff --git a/tools/widl/header.c b/tools/widl/header.c
index a0582f2..e87a44e 100644
--- a/tools/widl/header.c
+++ b/tools/widl/header.c
@@ -348,42 +348,46 @@ void write_type_right(FILE *h, type_t *t, int is_field)
static void write_type_v(FILE *h, type_t *t, int is_field, int declonly, const char *name)
{
- type_t *pt;
+ type_t *pt = NULL;
int ptr_level = 0;
if (!h) return;
- for (pt = t; is_ptr(pt); pt = type_pointer_get_ref(pt), ptr_level++)
- ;
-
- if (type_get_type_detect_alias(pt) == TYPE_FUNCTION) {
- int i;
- const char *callconv = get_attrp(pt->attrs, ATTR_CALLCONV);
- if (!callconv) callconv = "";
- if (is_attr(pt->attrs, ATTR_INLINE)) fprintf(h, "inline ");
- write_type_left(h, type_function_get_rettype(pt), declonly);
- fputc(' ', h);
- if (ptr_level) fputc('(', h);
- fprintf(h, "%s ", callconv);
- for (i = 0; i < ptr_level; i++)
- fputc('*', h);
- } else
- write_type_left(h, t, declonly);
-
- if (name) fprintf(h, "%s%s", needs_space_after(t) ? " " : "", name );
-
- if (type_get_type_detect_alias(pt) == TYPE_FUNCTION) {
- const var_list_t *args = type_function_get_args(pt);
-
- if (ptr_level) fputc(')', h);
- fputc('(', h);
- if (args)
- write_args(h, args, NULL, 0, FALSE);
- else
- fprintf(h, "void");
- fputc(')', h);
- } else
- write_type_right(h, t, is_field);
+ if (t) {
+ for (pt = t; is_ptr(pt); pt = type_pointer_get_ref(pt), ptr_level++)
+ ;
+
+ if (type_get_type_detect_alias(pt) == TYPE_FUNCTION) {
+ int i;
+ const char *callconv = get_attrp(pt->attrs, ATTR_CALLCONV);
+ if (!callconv) callconv = "";
+ if (is_attr(pt->attrs, ATTR_INLINE)) fprintf(h, "inline ");
+ write_type_left(h, type_function_get_rettype(pt), declonly);
+ fputc(' ', h);
+ if (ptr_level) fputc('(', h);
+ fprintf(h, "%s ", callconv);
+ for (i = 0; i < ptr_level; i++)
+ fputc('*', h);
+ } else
+ write_type_left(h, t, declonly);
+ }
+
+ if (name) fprintf(h, "%s%s", !t || needs_space_after(t) ? " " : "", name );
+
+ if (t) {
+ if (type_get_type_detect_alias(pt) == TYPE_FUNCTION) {
+ const var_list_t *args = type_function_get_args(pt);
+
+ if (ptr_level) fputc(')', h);
+ fputc('(', h);
+ if (args)
+ write_args(h, args, NULL, 0, FALSE);
+ else
+ fprintf(h, "void");
+ fputc(')', h);
+ } else
+ write_type_right(h, t, is_field);
+ }
}
void write_type_def_or_decl(FILE *f, type_t *t, int field, const char *name)
diff --git a/tools/widl/parser.l b/tools/widl/parser.l
index d3f355f..f509cb1 100644
--- a/tools/widl/parser.l
+++ b/tools/widl/parser.l
@@ -193,6 +193,7 @@ SAFEARRAY{ws}*/\( return tSAFEARRAY;
<INITIAL,ATTR>\<= return LESSEQUAL;
<INITIAL,ATTR>\|\| return LOGICALOR;
<INITIAL,ATTR>&& return LOGICALAND;
+<INITIAL,ATTR>\.\.\. return ELLIPSIS;
<INITIAL,ATTR>. return yytext[0];
<<EOF>> {
if (import_stack_ptr)
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index 9e1598e..0c216ec 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -194,6 +194,7 @@ static statement_list_t *append_statement(statement_list_t *list, statement_t *s
%token EQUALITY INEQUALITY
%token GREATEREQUAL LESSEQUAL
%token LOGICALOR LOGICALAND
+%token ELLIPSIS
%token tAGGREGATABLE tALLOCATE tANNOTATION tAPPOBJECT tASYNC tASYNCUUID
%token tAUTOHANDLE tBINDABLE tBOOLEAN tBROADCAST tBYTE tBYTECOUNT
%token tCALLAS tCALLBACK tCASE tCDECL tCHAR tCOCLASS tCODE tCOMMSTATUS
@@ -292,7 +293,8 @@ static statement_list_t *append_statement(statement_list_t *list, statement_t *s
%type <ifref> coclass_int
%type <ifref_list> coclass_ints
%type <var> arg ne_union_field union_field s_field case enum declaration
-%type <var_list> m_args args fields ne_union_fields cases enums enum_list dispint_props field
+%type <var_list> m_args arg_list args
+%type <var_list> fields ne_union_fields cases enums enum_list dispint_props field
%type <var> m_ident ident
%type <declarator> declarator direct_declarator init_declarator struct_declarator
%type <declarator> m_any_declarator any_declarator any_declarator_no_ident any_direct_declarator
@@ -426,8 +428,12 @@ m_args: { $$ = NULL; }
| args
;
-args: arg { check_arg_attrs($1); $$ = append_var( NULL, $1 ); }
- | args ',' arg { check_arg_attrs($3); $$ = append_var( $1, $3); }
+arg_list: arg { check_arg_attrs($1); $$ = append_var( NULL, $1 ); }
+ | arg_list ',' arg { check_arg_attrs($3); $$ = append_var( $1, $3 ); }
+ ;
+
+args: arg_list
+ | arg_list ',' ELLIPSIS { $$ = append_var( $1, make_var(strdup("...")) ); }
;
/* split into two rules to get bison to resolve a tVOID conflict */
More information about the wine-cvs
mailing list