Module: wine Branch: master Commit: 97d5f3401d94af2c662c4e45b24d8687ca274d1b URL: http://source.winehq.org/git/wine.git/?a=commit;h=97d5f3401d94af2c662c4e45b2...
Author: Rob Shearman robertshearman@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 */