From 5d267d7372bfda38edb61ce662904ae2a448f0b9 Mon Sep 17 00:00:00 2001 From: Ove Kaaven Date: Wed, 7 Jan 2004 04:21:27 +0000 Subject: [PATCH] Added rules to parse library, coclass, dispinterface, and module definitions, and a number of attributes, and cleaned up a few things. Started on a typelib generation framework. --- tools/widl/Makefile.in | 1 + tools/widl/header.c | 13 +- tools/widl/header.h | 3 + tools/widl/parser.l | 25 +++- tools/widl/parser.y | 189 ++++++++++++++++++++++++++--- tools/widl/proxy.c | 36 +++--- tools/widl/proxy.h | 3 +- tools/widl/typelib.c | 267 +++++++++++++++++++++++++++++++++++++++++ tools/widl/typelib.h | 31 +++++ tools/widl/widl.c | 24 +++- tools/widl/widl.h | 4 +- tools/widl/widltypes.h | 30 +++++ 12 files changed, 570 insertions(+), 56 deletions(-) create mode 100644 tools/widl/typelib.c create mode 100644 tools/widl/typelib.h diff --git a/tools/widl/Makefile.in b/tools/widl/Makefile.in index ea9c150ff4f..f7058132526 100644 --- a/tools/widl/Makefile.in +++ b/tools/widl/Makefile.in @@ -12,6 +12,7 @@ MODULE = none C_SRCS = \ header.c \ proxy.c \ + typelib.c \ utils.c \ widl.c diff --git a/tools/widl/header.c b/tools/widl/header.c index 71c77370f8f..2c5b5c18a06 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -34,7 +34,6 @@ #include "utils.h" #include "parser.h" #include "header.h" -#include "proxy.h" static int indentation = 0; @@ -409,7 +408,11 @@ void write_externdef(var_t *v) int is_object(attr_t *a) { - return is_attr(a, ATTR_OBJECT); + while (a) { + if (a->type == ATTR_OBJECT || a->type == ATTR_ODL) return 1; + a = NEXT_LINK(a); + } + return 0; } int is_local(attr_t *a) @@ -772,11 +775,7 @@ void write_com_interface(type_t *iface) fprintf(header, "\n\n"); } write_method_proto(iface); - fprintf(header, "\n"); - - if (!is_local(iface->attrs)) - write_proxy(iface); - fprintf(header,"#endif /* __%s_INTERFACE_DEFINED__ */\n\n", iface->name); + fprintf(header,"\n#endif /* __%s_INTERFACE_DEFINED__ */\n\n", iface->name); } void write_rpc_interface(type_t *iface) diff --git a/tools/widl/header.h b/tools/widl/header.h index 9c10b09740d..0fd4e33f112 100644 --- a/tools/widl/header.h +++ b/tools/widl/header.h @@ -21,6 +21,9 @@ #ifndef __WIDL_HEADER_H #define __WIDL_HEADER_H +extern int is_attr(attr_t *a, enum attr_type t); +extern void *get_attrp(attr_t *a, enum attr_type t); +extern DWORD get_attrv(attr_t *a, enum attr_type t); extern int is_void(type_t *t, var_t *v); extern void write_name(FILE *h, var_t *v); extern char* get_name(var_t *v); diff --git a/tools/widl/parser.l b/tools/widl/parser.l index f723d5449eb..55d246361a7 100644 --- a/tools/widl/parser.l +++ b/tools/widl/parser.l @@ -207,8 +207,13 @@ static struct keyword { /* ... */ {"default", tDEFAULT}, /* ... */ - {"double", tDOUBLE}, + {"dispinterface", tDISPINTERFACE}, /* ... */ + {"dllname", tDLLNAME}, + {"double", tDOUBLE}, + {"dual", tDUAL}, +/* ... */ + {"entry", tENTRY}, {"enum", tENUM}, {"error_status_t", tERRORSTATUST}, /* ... */ @@ -218,8 +223,10 @@ static struct keyword { /* ... */ {"handle_t", tHANDLET}, /* ... */ - {"hyper", tHYPER}, + {"helpstring", tHELPSTRING}, /* ... */ + {"hyper", tHYPER}, + {"id", tID}, {"idempotent", tIDEMPOTENT}, /* ... */ {"iid_is", tIIDIS}, @@ -234,9 +241,14 @@ static struct keyword { {"interface", tINTERFACE}, /* ... */ {"length_is", tLENGTHIS}, + {"library", tLIBRARY}, /* ... */ {"local", tLOCAL}, {"long", tLONG}, +/* ... */ + {"methods", tMETHODS}, +/* ... */ + {"module", tMODULE}, /* ... */ {"object", tOBJECT}, {"odl", tODL}, @@ -246,13 +258,22 @@ static struct keyword { /* ... */ {"pointer_default", tPOINTERDEFAULT}, /* ... */ + {"properties", tPROPERTIES}, +/* ... */ + {"public", tPUBLIC}, +/* ... */ + {"readonly", tREADONLY}, {"ref", tREF}, +/* ... */ + {"retval", tRETVAL}, /* ... */ {"short", tSHORT}, {"signed", tSIGNED}, {"size_is", tSIZEIS}, {"sizeof", tSIZEOF}, /* ... */ + {"source", tSOURCE}, +/* ... */ {"string", tSTRING}, {"struct", tSTRUCT}, {"switch", tSWITCH}, diff --git a/tools/widl/parser.y b/tools/widl/parser.y index a427e6b863f..69930b3c7d9 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -35,6 +35,8 @@ #include "utils.h" #include "parser.h" #include "header.h" +#include "proxy.h" +#include "typelib.h" #if defined(YYBYACC) /* Berkeley yacc (byacc) doesn't seem to know about these */ @@ -75,8 +77,10 @@ static typeref_t *make_tref(char *name, type_t *ref); static typeref_t *uniq_tref(typeref_t *ref); static type_t *type_ref(typeref_t *ref); static void set_type(var_t *v, typeref_t *ref, expr_t *arr); +static ifref_t *make_ifref(type_t *iface); static var_t *make_var(char *name); static func_t *make_func(var_t *def, var_t *args); +static class_t *make_class(char *name); static type_t *reg_type(type_t *type, char *name, int t); static type_t *reg_types(type_t *type, var_t *names, int t); @@ -105,6 +109,8 @@ static type_t std_uhyper = { "MIDL_uhyper" }; typeref_t *tref; var_t *var; func_t *func; + ifref_t *ifref; + class_t *clas; char *str; UUID *uuid; unsigned int num; @@ -123,28 +129,35 @@ static type_t std_uhyper = { "MIDL_uhyper" }; %token tCONST tCONTEXTHANDLE tCONTEXTHANDLENOSERIALIZE %token tCONTEXTHANDLESERIALIZE tCONTROL tCPPQUOTE %token tDEFAULT -%token tDOUBLE -%token tENUM tERRORSTATUST +%token tDISPINTERFACE +%token tDLLNAME tDOUBLE tDUAL +%token tENTRY tENUM tERRORSTATUST %token tEXTERN %token tFLOAT %token tHANDLET -%token tHYPER -%token tIDEMPOTENT +%token tHELPSTRING +%token tHYPER tID tIDEMPOTENT %token tIIDIS %token tIMPORT tIMPORTLIB %token tIN tINCLUDE tINLINE %token tINT tINT64 %token tINTERFACE -%token tLENGTHIS +%token tLENGTHIS tLIBRARY %token tLOCAL %token tLONG +%token tMETHODS +%token tMODULE %token tOBJECT tODL tOLEAUTOMATION %token tOUT %token tPOINTERDEFAULT -%token tREF +%token tPROPERTIES +%token tPUBLIC +%token tREADONLY tREF +%token tRETVAL %token tSHORT %token tSIGNED %token tSIZEIS tSIZEOF +%token tSOURCE %token tSTDCALL %token tSTRING tSTRUCT %token tSWITCH tSWITCHIS tSWITCHTYPE @@ -164,15 +177,22 @@ static type_t std_uhyper = { "MIDL_uhyper" }; %type m_attributes attributes attrib_list attribute %type m_exprs /* exprs expr_list */ m_expr expr expr_list_const expr_const %type array array_list -%type inherit interface interfacehdr interfacedef lib_statements +%type inherit interface interfacehdr interfacedef interfacedec +%type dispinterface dispinterfacehdr dispinterfacedef +%type module modulehdr moduledef %type base_type int_std %type enumdef structdef typedef uniondef +%type gbl_statements coclass_ints coclass_int %type type %type m_args no_args args arg %type fields field s_field cases case enums enum_list enum constdef externdef %type m_ident t_ident ident p_ident pident pident_list +%type dispint_props %type funcdef int_statements +%type dispint_meths +%type coclass coclasshdr coclassdef %type pointer_type version +%type libraryhdr %left ',' %left '|' @@ -187,19 +207,29 @@ static type_t std_uhyper = { "MIDL_uhyper" }; %% -input: lib_statements { /* FIXME */ } +input: gbl_statements { write_proxies($1); } ; -lib_statements: { $$ = NULL; } - | lib_statements interface ';' { if (!parse_only) write_forward($2); } - | lib_statements interfacedef { LINK($2, $1); $$ = $2; } -/* | lib_statements librarydef (when implemented) */ - | lib_statements statement +gbl_statements: { $$ = NULL; } + | gbl_statements interfacedec { $$ = $1; } + | gbl_statements interfacedef { $$ = make_ifref($2); LINK($$, $1); } + | gbl_statements coclassdef { $$ = $1; add_coclass($2); } + | gbl_statements moduledef { $$ = $1; add_module($2); } + | gbl_statements librarydef { $$ = $1; } + | gbl_statements statement { $$ = $1; } + ; + +imp_statements: {} + | imp_statements interfacedec { add_interface($2); } + | imp_statements interfacedef { add_interface($2); } + | imp_statements coclassdef { add_coclass($2); } + | imp_statements moduledef { add_module($2); } + | imp_statements statement {} ; int_statements: { $$ = NULL; } - | int_statements funcdef ';' { LINK($2, $1); $$ = $2; } - | int_statements statement + | int_statements funcdef ';' { $$ = $2; LINK($$, $1); } + | int_statements statement { $$ = $1; } ; statement: ';' {} @@ -208,19 +238,24 @@ statement: ';' {} | enumdef ';' { if (!parse_only) { write_type(header, $1, NULL, NULL); fprintf(header, ";\n\n"); } } | externdef ';' { if (!parse_only) { write_externdef($1); } } | import {} -/* | interface ';' {} */ -/* | interfacedef {} */ | structdef ';' { if (!parse_only) { write_type(header, $1, NULL, NULL); fprintf(header, ";\n\n"); } } | typedef ';' {} | uniondef ';' { if (!parse_only) { write_type(header, $1, NULL, NULL); fprintf(header, ";\n\n"); } } ; -cppquote: tCPPQUOTE '(' aSTRING ')' { if (!parse_only) fprintf(header, "%s\n", $3); } +cppquote: tCPPQUOTE '(' aSTRING ')' { if (!parse_only) fprintf(header, "%s\n", $3); } ; -import_start: tIMPORT aSTRING ';' { assert(yychar == YYEMPTY); +import_start: tIMPORT aSTRING ';' { assert(yychar == YYEMPTY); if (!do_import($2)) yychar = aEOF; } ; -import: import_start input aEOF {} +import: import_start imp_statements aEOF {} + ; + +libraryhdr: tLIBRARY aIDENTIFIER { $$ = $2; } + ; +library_start: attributes libraryhdr '{' { start_typelib($2, $1); } + ; +librarydef: library_start imp_statements '}' { end_typelib(); } ; m_args: { $$ = NULL; } @@ -287,16 +322,27 @@ attribute: | tCONTEXTHANDLENOSERIALIZE { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_DONT_SERIALIZE */ } | tCONTEXTHANDLESERIALIZE { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_SERIALIZE */ } | tDEFAULT { $$ = make_attr(ATTR_DEFAULT); } + | tDLLNAME '(' aSTRING ')' { $$ = make_attrp(ATTR_DLLNAME, $3); } + | tDUAL { $$ = make_attr(ATTR_DUAL); } + | tENTRY '(' aSTRING ')' { $$ = make_attrp(ATTR_ENTRY_STRING, $3); } + | tENTRY '(' expr_const ')' { $$ = make_attrp(ATTR_ENTRY_ORDINAL, $3); } + | tHELPSTRING '(' aSTRING ')' { $$ = make_attrp(ATTR_HELPSTRING, $3); } + | tID '(' expr_const ')' { $$ = make_attrp(ATTR_ID, $3); } | tIDEMPOTENT { $$ = make_attr(ATTR_IDEMPOTENT); } | tIIDIS '(' ident ')' { $$ = make_attrp(ATTR_IIDIS, $3); } | tIN { $$ = make_attr(ATTR_IN); } | tLENGTHIS '(' m_exprs ')' { $$ = make_attrp(ATTR_LENGTHIS, $3); } | tLOCAL { $$ = make_attr(ATTR_LOCAL); } | tOBJECT { $$ = make_attr(ATTR_OBJECT); } + | tODL { $$ = make_attr(ATTR_ODL); } | tOLEAUTOMATION { $$ = make_attr(ATTR_OLEAUTOMATION); } | tOUT { $$ = make_attr(ATTR_OUT); } | tPOINTERDEFAULT '(' pointer_type ')' { $$ = make_attrv(ATTR_POINTERDEFAULT, $3); } + | tPUBLIC { $$ = make_attr(ATTR_PUBLIC); } + | tREADONLY { $$ = make_attr(ATTR_READONLY); } + | tRETVAL { $$ = make_attr(ATTR_RETVAL); } | tSIZEIS '(' m_exprs ')' { $$ = make_attrp(ATTR_SIZEIS, $3); } + | tSOURCE { $$ = make_attr(ATTR_SOURCE); } | tSTRING { $$ = make_attr(ATTR_STRING); } | tSWITCHIS '(' expr ')' { $$ = make_attrp(ATTR_SWITCHIS, $3); } | tSWITCHTYPE '(' type ')' { $$ = make_attrp(ATTR_SWITCHTYPE, type_ref($3)); } @@ -446,6 +492,8 @@ t_ident: { $$ = NULL; } ident: aIDENTIFIER { $$ = make_var($1); } /* some "reserved words" used in attributes are also used as field names in some MS IDL files */ + | tID { $$ = make_var($1); } + | tRETVAL { $$ = make_var($1); } | tVERSION { $$ = make_var($1); } ; @@ -483,6 +531,67 @@ int_std: tINT { $$ = make_type(RPC_FC_LONG, &std_int); } /* win32 only */ | tCHAR { $$ = make_type(RPC_FC_CHAR, NULL); } ; +coclass: tCOCLASS aIDENTIFIER { $$ = make_class($2); } + | tCOCLASS aKNOWNTYPE { $$ = make_class($2); } + ; + +coclasshdr: attributes coclass { $$ = $2; + $$->attrs = $1; + } + ; + +coclassdef: coclasshdr '{' coclass_ints '}' { $$ = $1; + $$->ifaces = $3; + } + ; + +coclass_ints: { $$ = NULL; } + | coclass_ints coclass_int { LINK($2, $1); $$ = $2; } + ; + +coclass_int: + m_attributes interfacedec { $$ = make_ifref($2); $$->attrs = $1; } + ; + +dispinterface: tDISPINTERFACE aIDENTIFIER { $$ = get_type(0, $2, 0); } + | tDISPINTERFACE aKNOWNTYPE { $$ = get_type(0, $2, 0); } + ; + +dispinterfacehdr: attributes dispinterface { $$ = $2; + if ($$->defined) yyerror("multiple definition error\n"); + $$->attrs = $1; + /* $$->attrs = make_attr(ATTR_DISPINTERFACE); */ + /* LINK($$->attrs, $1); */ + $$->ref = find_type("IDispatch", 0); + if (!$$->ref) yyerror("IDispatch is undefined\n"); + $$->defined = TRUE; + if (!parse_only) write_forward($$); + } + ; + +dispint_props: tPROPERTIES ':' { $$ = NULL; } + | dispint_props s_field ';' { LINK($2, $1); $$ = $2; } + ; + +dispint_meths: tMETHODS ':' { $$ = NULL; } + | dispint_meths funcdef ';' { LINK($2, $1); $$ = $2; } + ; + +dispinterfacedef: dispinterfacehdr '{' + dispint_props + dispint_meths + '}' { $$ = $1; + $$->fields = $3; + $$->funcs = $4; + if (!parse_only) write_interface($$); + } +/* FIXME: not sure how to handle this yet + | dispinterfacehdr '{' interface '}' { $$ = $1; + if (!parse_only) write_interface($$); + } +*/ + ; + inherit: { $$ = NULL; } | ':' aKNOWNTYPE { $$ = find_type2($2, 0); } ; @@ -514,6 +623,27 @@ interfacedef: interfacehdr inherit $$->funcs = $6; if (!parse_only) write_interface($$); } + | dispinterfacedef { $$ = $1; } + ; + +interfacedec: + interface ';' { $$ = $1; if (!parse_only) write_forward($$); } + | dispinterface ';' { $$ = $1; if (!parse_only) write_forward($$); } + ; + +module: tMODULE aIDENTIFIER { $$ = make_type(0, NULL); $$->name = $2; } + | tMODULE aKNOWNTYPE { $$ = make_type(0, NULL); $$->name = $2; } + ; + +modulehdr: attributes module { $$ = $2; + $$->attrs = $1; + } + ; + +moduledef: modulehdr '{' int_statements '}' { $$ = $1; + $$->funcs = $3; + /* FIXME: if (!parse_only) write_module($$); */ + } ; p_ident: '*' pident %prec PPTR { $$ = $2; $$->ptr_level++; } @@ -810,6 +940,15 @@ static void set_type(var_t *v, typeref_t *ref, expr_t *arr) v->array = arr; } +static ifref_t *make_ifref(type_t *iface) +{ + ifref_t *l = xmalloc(sizeof(ifref_t)); + l->iface = iface; + l->attrs = NULL; + INIT_LINK(l); + return l; +} + static var_t *make_var(char *name) { var_t *v = xmalloc(sizeof(var_t)); @@ -836,6 +975,16 @@ static func_t *make_func(var_t *def, var_t *args) return f; } +static class_t *make_class(char *name) +{ + class_t *c = xmalloc(sizeof(class_t)); + c->name = name; + c->attrs = NULL; + c->ifaces = NULL; + INIT_LINK(c); + return c; +} + #define HASHMAX 64 static int hash_ident(const char *name) diff --git a/tools/widl/proxy.c b/tools/widl/proxy.c index 0234b03f62b..3badc74d6f6 100644 --- a/tools/widl/proxy.c +++ b/tools/widl/proxy.c @@ -35,6 +35,8 @@ #include "parser.h" #include "header.h" +static FILE* proxy; + /* FIXME: support generation of stubless proxies */ static void write_stubdesc(void) @@ -218,22 +220,13 @@ static int write_stub_methods(type_t *iface) return i; } -typedef struct _if_list if_list; -struct _if_list { - type_t *iface; - DECL_LINK(if_list) -}; - -if_list *if_first; - -void write_proxy(type_t *iface) +static void write_proxy(type_t *iface) { int midx = -1, stubs; func_t *cur = iface->funcs; - if_list *if_cur; if (!cur) return; - if (header_only) return; + if (!do_everything) return; while (NEXT_LINK(cur)) cur = NEXT_LINK(cur); @@ -241,12 +234,6 @@ void write_proxy(type_t *iface) init_proxy(); - if_cur = xmalloc(sizeof(if_list)); - if_cur->iface = iface; - INIT_LINK(if_cur); - LINK(if_cur, if_first); - if_first = if_cur; - fprintf(proxy, "/*****************************************************************************\n"); fprintf(proxy, " * %s interface\n", iface->name); fprintf(proxy, " */\n"); @@ -296,16 +283,25 @@ void write_proxy(type_t *iface) fprintf(proxy, "\n"); } -void finish_proxy(void) +void write_proxies(ifref_t *ifaces) { - if_list *lcur = if_first; - if_list *cur; + ifref_t *lcur = ifaces; + ifref_t *cur; char *file_id = proxy_token; int c; if (!lcur) return; while (NEXT_LINK(lcur)) lcur = NEXT_LINK(lcur); + cur = lcur; + while (cur) { + if (is_object(cur->iface->attrs) && !is_local(cur->iface->attrs)) + write_proxy(cur->iface); + cur = PREV_LINK(cur); + } + + if (!proxy) return; + fprintf(proxy, "const CInterfaceProxyVtbl* _%s_ProxyVtblList[] = {\n", file_id); cur = lcur; while (cur) { diff --git a/tools/widl/proxy.h b/tools/widl/proxy.h index aad02c598ad..fb32b5ebd32 100644 --- a/tools/widl/proxy.h +++ b/tools/widl/proxy.h @@ -21,7 +21,6 @@ #ifndef __WIDL_PROXY_H #define __WIDL_PROXY_H -extern void write_proxy(type_t *iface); -extern void finish_proxy(void); +extern void write_proxies(ifref_t *ifaces); #endif diff --git a/tools/widl/typelib.c b/tools/widl/typelib.c new file mode 100644 index 00000000000..addaa0f21c6 --- /dev/null +++ b/tools/widl/typelib.c @@ -0,0 +1,267 @@ +/* + * IDL Compiler + * + * Copyright 2004 Ove Kaaven + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "widl.h" +#include "utils.h" +#include "parser.h" +#include "header.h" +#include "typelib.h" + +int in_typelib = 0; +static FILE* typelib; + +/* Copied from wtypes.h. Not included directly because that would create a + * circular dependency (after all, wtypes.h is generated by widl...) */ + +enum VARENUM { + VT_EMPTY = 0, + VT_NULL = 1, + VT_I2 = 2, + VT_I4 = 3, + VT_R4 = 4, + VT_R8 = 5, + VT_CY = 6, + VT_DATE = 7, + VT_BSTR = 8, + VT_DISPATCH = 9, + VT_ERROR = 10, + VT_BOOL = 11, + VT_VARIANT = 12, + VT_UNKNOWN = 13, + VT_DECIMAL = 14, + VT_I1 = 16, + VT_UI1 = 17, + VT_UI2 = 18, + VT_UI4 = 19, + VT_I8 = 20, + VT_UI8 = 21, + VT_INT = 22, + VT_UINT = 23, + VT_VOID = 24, + VT_HRESULT = 25, + VT_PTR = 26, + VT_SAFEARRAY = 27, + VT_CARRAY = 28, + VT_USERDEFINED = 29, + VT_LPSTR = 30, + VT_LPWSTR = 31, + VT_RECORD = 36, + VT_FILETIME = 64, + VT_BLOB = 65, + VT_STREAM = 66, + VT_STORAGE = 67, + VT_STREAMED_OBJECT = 68, + VT_STORED_OBJECT = 69, + VT_BLOB_OBJECT = 70, + VT_CF = 71, + VT_CLSID = 72, + VT_BSTR_BLOB = 0xfff, + VT_VECTOR = 0x1000, + VT_ARRAY = 0x2000, + VT_BYREF = 0x4000, + VT_RESERVED = 0x8000, + VT_ILLEGAL = 0xffff, + VT_ILLEGALMASKED = 0xfff, + VT_TYPEMASK = 0xfff +}; + +/* List of oleauto types that should be recognized by name. + * (most of) these seem to be intrinsic types in mktyplib. */ + +static struct oatype { + const char *kw; + unsigned short vt; +} oatypes[] = { + {"BSTR", VT_BSTR}, + {"CURRENCY", VT_CY}, + {"DATE", VT_DATE}, + {"DECIMAL", VT_DECIMAL}, + {"HRESULT", VT_HRESULT}, + {"LPSTR", VT_LPSTR}, + {"LPWSTR", VT_LPWSTR}, + {"SCODE", VT_ERROR}, + {"VARIANT", VT_VARIANT} +}; +#define NTYPES (sizeof(oatypes)/sizeof(oatypes[0])) +#define KWP(p) ((struct oatype *)(p)) + +static int kw_cmp_func(const void *s1, const void *s2) +{ + return strcmp(KWP(s1)->kw, KWP(s2)->kw); +} + +static unsigned short builtin_vt(const char *kw) +{ + struct oatype key, *kwp; + key.kw = kw; +#ifdef KW_BSEARCH + kwp = bsearch(&key, oatypes, NTYPES, sizeof(oatypes[0]), kw_cmp_func); +#else + { + int i; + for (kwp=NULL, i=0; i < NTYPES; i++) + if (!kw_cmp_func(&key, &oatypes[i])) { + kwp = &oatypes[i]; + break; + } + } +#endif + if (kwp) { + return kwp->vt; + } + return 0; +} + +static int match(const char*n, const char*m) +{ + if (!n) return 0; + return !strcmp(n, m); +} + +unsigned short get_type_vt(type_t *t) +{ + unsigned short vt; + + if (t->name) { + vt = builtin_vt(t->name); + if (vt) return vt; + } + + switch (t->type) { + case RPC_FC_BYTE: + case RPC_FC_USMALL: + return VT_UI1; + case RPC_FC_CHAR: + case RPC_FC_SMALL: + return VT_I1; + case RPC_FC_WCHAR: + return VT_I2; /* mktyplib seems to parse wchar_t as short */ + case RPC_FC_SHORT: + return VT_I2; + case RPC_FC_USHORT: + return VT_UI2; + case RPC_FC_LONG: + if (t->ref && match(t->ref->name, "int")) return VT_INT; + return VT_I4; + case RPC_FC_ULONG: + if (t->ref && match(t->ref->name, "int")) return VT_UINT; + return VT_UI4; + case RPC_FC_HYPER: + if (t->sign < 0) return VT_UI8; + if (t->ref && match(t->ref->name, "MIDL_uhyper")) return VT_UI8; + return VT_I8; + case RPC_FC_FLOAT: + return VT_R4; + case RPC_FC_DOUBLE: + return VT_R8; + case RPC_FC_RP: + case RPC_FC_UP: + case RPC_FC_OP: + case RPC_FC_FP: + /* it's a pointer... */ + if (t->ref && t->ref->type == RPC_FC_IP) { + /* it's to an interface, which one? */ + if (match(t->ref->name, "IDispatch")) + return VT_DISPATCH; + if (match(t->ref->name, "IUnknown")) + return VT_UNKNOWN; + } + /* FIXME: should we recurse and add a VT_BYREF? */ + /* Or just return VT_PTR? */ + error("get_type_vt: unknown-deref-type: %d\n", t->ref->type); + break; + default: + error("get_type_vt: unknown-type: %d\n", t->type); + } + return 0; +} + +unsigned short get_var_vt(var_t *v) +{ + unsigned short vt; + + if (v->tname) { + vt = builtin_vt(v->tname); + if (vt) return vt; + } + + return get_type_vt(v->type); +} + +void start_typelib(char *name, attr_t *attrs) +{ + in_typelib++; + if (!do_everything && !typelib_only) return; + typelib = fopen(typelib_name, "wb"); +} + +void end_typelib(void) +{ + if (typelib) fclose(typelib); + in_typelib--; +} + +void add_interface(type_t *iface) +{ + if (!typelib) return; + + /* FIXME: add interface and dependent types to typelib */ + printf("add interface: %s\n", iface->name); +} + +void add_coclass(class_t *cls) +{ + ifref_t *lcur = cls->ifaces; + ifref_t *cur; + + if (lcur) { + while (NEXT_LINK(lcur)) lcur = NEXT_LINK(lcur); + } + + if (!typelib) return; + + /* install interfaces the coclass depends on */ + cur = lcur; + while (cur) { + add_interface(cur->iface); + cur = PREV_LINK(cur); + } + + /* FIXME: add coclass to typelib */ + printf("add coclass: %s\n", cls->name); +} + +void add_module(type_t *module) +{ + if (!typelib) return; + + /* FIXME: add module to typelib */ + printf("add module: %s\n", module->name); +} diff --git a/tools/widl/typelib.h b/tools/widl/typelib.h new file mode 100644 index 00000000000..dd1e1cfd2b8 --- /dev/null +++ b/tools/widl/typelib.h @@ -0,0 +1,31 @@ +/* + * IDL Compiler + * + * Copyright 2004 Ove Kaaven + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __WIDL_TYPELIB_H +#define __WIDL_TYPELIB_H + +extern int in_typelib; +extern void start_typelib(char *name, attr_t *attrs); +extern void end_typelib(void); +extern void add_interface(type_t *iface); +extern void add_coclass(class_t *cls); +extern void add_module(type_t *module); + +#endif diff --git a/tools/widl/widl.c b/tools/widl/widl.c index 791d9a53298..37368d8069b 100644 --- a/tools/widl/widl.c +++ b/tools/widl/widl.c @@ -50,8 +50,6 @@ /* P = proxy filename */ /* s = server stub only? */ /* S = server stub filename */ -/* t = typelib only? */ -/* T = typelib filename */ /* u = UUID file only? */ /* U = UUID filename */ /* w = select win16/win32 output (?) */ @@ -66,6 +64,8 @@ static char usage[] = " -H file Name of header file (default is infile.h)\n" " -I path Set include search dir to path (multiple -I allowed)\n" " -N Do not preprocess input\n" +" -t Generate typelib only\n" +" -T file Name of typelib file (default is infile.tlb)\n" " -V Print version and exit\n" " -W Enable pedantic warnings\n" "Debug level 'n' is a bitmask with following meaning:\n" @@ -84,14 +84,17 @@ int win32 = 1; int debuglevel = DEBUGLEVEL_NONE; int pedantic = 0; +int do_everything = 1; int preprocess_only = 0; int header_only = 0; +int typelib_only = 0; int no_preprocess = 0; int compat_icom = 0; char *input_name; char *header_name; char *header_token; +char *typelib_name; char *proxy_name; char *proxy_token; char *temp_name; @@ -135,7 +138,7 @@ int main(int argc,char *argv[]) now = time(NULL); - while((optc = getopt(argc, argv, "bd:D:EhH:I:NVW")) != EOF) { + while((optc = getopt(argc, argv, "bd:D:EhH:I:NtT:VW")) != EOF) { switch(optc) { case 'b': compat_icom = 1; @@ -147,9 +150,11 @@ int main(int argc,char *argv[]) wpp_add_cmdline_define(optarg); break; case 'E': + do_everything = 0; preprocess_only = 1; break; case 'h': + do_everything = 0; header_only = 1; break; case 'H': @@ -161,6 +166,13 @@ int main(int argc,char *argv[]) case 'N': no_preprocess = 1; break; + case 't': + do_everything = 0; + typelib_only = 1; + break; + case 'T': + typelib_name = strdup(optarg); + break; case 'V': printf(version_string); return 0; @@ -199,6 +211,11 @@ int main(int argc,char *argv[]) strcat(header_name, ".h"); } + if (!typelib_name) { + typelib_name = dup_basename(input_name, ".idl"); + strcat(typelib_name, ".tlb"); + } + if (!proxy_name) { proxy_name = dup_basename(input_name, ".idl"); proxy_token = xstrdup(proxy_name); @@ -249,7 +266,6 @@ int main(int argc,char *argv[]) ret = yyparse(); - finish_proxy(); fprintf(header, "#ifdef __cplusplus\n"); fprintf(header, "}\n"); fprintf(header, "#endif\n"); diff --git a/tools/widl/widl.h b/tools/widl/widl.h index 5ef859ffa86..93b5fd5b0c8 100644 --- a/tools/widl/widl.h +++ b/tools/widl/widl.h @@ -38,11 +38,14 @@ extern int debuglevel; extern int win32; extern int pedantic; +extern int do_everything; extern int header_only; +extern int typelib_only; extern int compat_icom; extern char *input_name; extern char *header_name; +extern char *typelib_name; extern char *proxy_name; extern char *proxy_token; extern time_t now; @@ -51,6 +54,5 @@ extern int line_number; extern int char_number; extern FILE* header; -extern FILE* proxy; #endif diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h index d784a391b16..5bb503b5c93 100644 --- a/tools/widl/widltypes.h +++ b/tools/widl/widltypes.h @@ -38,6 +38,8 @@ typedef struct _type_t type_t; typedef struct _typeref_t typeref_t; typedef struct _var_t var_t; typedef struct _func_t func_t; +typedef struct _ifref_t ifref_t; +typedef struct _class_t class_t; #define DECL_LINK(type) \ type *l_next; \ @@ -56,17 +58,28 @@ enum attr_type ATTR_CASE, ATTR_CONTEXTHANDLE, ATTR_DEFAULT, + ATTR_DLLNAME, + ATTR_DUAL, + ATTR_ENTRY_STRING, + ATTR_ENTRY_ORDINAL, + ATTR_HELPSTRING, + ATTR_ID, ATTR_IDEMPOTENT, ATTR_IIDIS, ATTR_IN, ATTR_LENGTHIS, ATTR_LOCAL, ATTR_OBJECT, + ATTR_ODL, ATTR_OLEAUTOMATION, ATTR_OUT, ATTR_POINTERDEFAULT, ATTR_POINTERTYPE, + ATTR_PUBLIC, + ATTR_READONLY, + ATTR_RETVAL, ATTR_SIZEIS, + ATTR_SOURCE, ATTR_STRING, ATTR_SWITCHIS, ATTR_SWITCHTYPE, @@ -167,4 +180,21 @@ struct _func_t { DECL_LINK(func_t) }; +struct _ifref_t { + type_t *iface; + attr_t *attrs; + + /* parser-internal */ + DECL_LINK(ifref_t) +}; + +struct _class_t { + char *name; + attr_t *attrs; + ifref_t *ifaces; + + /* parser-internal */ + DECL_LINK(class_t) +}; + #endif