widl patch
Ove Kaaven
ovek at arcticnet.no
Mon Jan 5 21:03:43 CST 2004
With this patch, widl can be made to parse a suitably adapted version of
the stdole2.odl file previously sent to wine-patches (but it can't yet
generate anything useful from it). Not unchanged, though, as widl is
supposed to be more of a MIDL than a mktyplib (even though I can't seem
to convince MIDL to generate stdole32.tlb). And there's a new typelib.c
file to eventually fill in...
Log:
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.
? typelib.c
? typelib.h
Index: Makefile.in
===================================================================
RCS file: /home/wine/wine/tools/widl/Makefile.in,v
retrieving revision 1.8
diff -u -r1.8 Makefile.in
--- Makefile.in 1 May 2003 03:16:21 -0000 1.8
+++ Makefile.in 6 Jan 2004 02:11:36 -0000
@@ -12,6 +12,7 @@
C_SRCS = \
header.c \
proxy.c \
+ typelib.c \
utils.c \
widl.c
Index: header.c
===================================================================
RCS file: /home/wine/wine/tools/widl/header.c,v
retrieving revision 1.19
diff -u -r1.19 header.c
--- header.c 3 Sep 2003 20:16:24 -0000 1.19
+++ header.c 6 Jan 2004 02:11:38 -0000
@@ -34,7 +34,6 @@
#include "utils.h"
#include "parser.h"
#include "header.h"
-#include "proxy.h"
static int indentation = 0;
@@ -409,7 +408,11 @@
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)
@@ -773,10 +776,6 @@
}
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);
}
void write_rpc_interface(type_t *iface)
Index: header.h
===================================================================
RCS file: /home/wine/wine/tools/widl/header.h,v
retrieving revision 1.4
diff -u -r1.4 header.h
--- header.h 3 Sep 2003 20:16:24 -0000 1.4
+++ header.h 6 Jan 2004 02:11:38 -0000
@@ -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);
Index: parser.l
===================================================================
RCS file: /home/wine/wine/tools/widl/parser.l,v
retrieving revision 1.14
diff -u -r1.14 parser.l
--- parser.l 3 Sep 2003 19:31:14 -0000 1.14
+++ parser.l 6 Jan 2004 02:11:39 -0000
@@ -207,8 +207,13 @@
/* ... */
{"default", tDEFAULT},
/* ... */
+ {"dispinterface", tDISPINTERFACE},
+/* ... */
+ {"dllname", tDLLNAME},
{"double", tDOUBLE},
+ {"dual", tDUAL},
/* ... */
+ {"entry", tENTRY},
{"enum", tENUM},
{"error_status_t", tERRORSTATUST},
/* ... */
@@ -218,8 +223,10 @@
/* ... */
{"handle_t", tHANDLET},
/* ... */
- {"hyper", tHYPER},
+ {"helpstring", tHELPSTRING},
/* ... */
+ {"hyper", tHYPER},
+ {"id", tID},
{"idempotent", tIDEMPOTENT},
/* ... */
{"iid_is", tIIDIS},
@@ -234,10 +241,15 @@
{"interface", tINTERFACE},
/* ... */
{"length_is", tLENGTHIS},
+ {"library", tLIBRARY},
/* ... */
{"local", tLOCAL},
{"long", tLONG},
/* ... */
+ {"methods", tMETHODS},
+/* ... */
+ {"module", tMODULE},
+/* ... */
{"object", tOBJECT},
{"odl", tODL},
{"oleautomation", tOLEAUTOMATION},
@@ -246,13 +258,22 @@
/* ... */
{"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},
Index: parser.y
===================================================================
RCS file: /home/wine/wine/tools/widl/parser.y,v
retrieving revision 1.11
diff -u -r1.11 parser.y
--- parser.y 3 Sep 2003 20:16:24 -0000 1.11
+++ parser.y 6 Jan 2004 02:11:40 -0000
@@ -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 *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 @@
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 @@
%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 @@
%type <attr> m_attributes attributes attrib_list attribute
%type <expr> m_exprs /* exprs expr_list */ m_expr expr expr_list_const expr_const
%type <expr> array array_list
-%type <type> inherit interface interfacehdr interfacedef lib_statements
+%type <type> inherit interface interfacehdr interfacedef interfacedec
+%type <type> dispinterface dispinterfacehdr dispinterfacedef
+%type <type> module modulehdr moduledef
%type <type> base_type int_std
%type <type> enumdef structdef typedef uniondef
+%type <ifref> gbl_statements coclass_ints coclass_int
%type <tref> type
%type <var> m_args no_args args arg
%type <var> fields field s_field cases case enums enum_list enum constdef externdef
%type <var> m_ident t_ident ident p_ident pident pident_list
+%type <var> dispint_props
%type <func> funcdef int_statements
+%type <func> dispint_meths
+%type <clas> coclass coclasshdr coclassdef
%type <num> pointer_type version
+%type <str> libraryhdr
%left ','
%left '|'
@@ -187,19 +207,29 @@
%%
-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 @@
| 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 @@
| 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,7 @@
ident: aIDENTIFIER { $$ = make_var($1); }
/* some "reserved words" used in attributes are also used as field names in some MS IDL files */
+ | tRETVAL { $$ = make_var($<str>1); }
| tVERSION { $$ = make_var($<str>1); }
;
@@ -483,6 +530,67 @@
| 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 +622,27 @@
$$->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 +939,15 @@
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));
@@ -834,6 +972,16 @@
f->idx = -1;
INIT_LINK(f);
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
Index: proxy.c
===================================================================
RCS file: /home/wine/wine/tools/widl/proxy.c,v
retrieving revision 1.8
diff -u -r1.8 proxy.c
--- proxy.c 3 Sep 2003 20:16:24 -0000 1.8
+++ proxy.c 6 Jan 2004 02:11:40 -0000
@@ -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 @@
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 @@
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,15 +283,24 @@
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;
Index: proxy.h
===================================================================
RCS file: /home/wine/wine/tools/widl/proxy.h,v
retrieving revision 1.1
diff -u -r1.1 proxy.h
--- proxy.h 16 Jul 2002 03:20:46 -0000 1.1
+++ proxy.h 6 Jan 2004 02:11:40 -0000
@@ -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
Index: widl.c
===================================================================
RCS file: /home/wine/wine/tools/widl/widl.c,v
retrieving revision 1.14
diff -u -r1.14 widl.c
--- widl.c 3 Sep 2003 19:31:14 -0000 1.14
+++ widl.c 6 Jan 2004 02:11:41 -0000
@@ -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 @@
" -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 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 @@
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 @@
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 @@
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 @@
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 @@
ret = yyparse();
- finish_proxy();
fprintf(header, "#ifdef __cplusplus\n");
fprintf(header, "}\n");
fprintf(header, "#endif\n");
Index: widl.h
===================================================================
RCS file: /home/wine/wine/tools/widl/widl.h,v
retrieving revision 1.5
diff -u -r1.5 widl.h
--- widl.h 10 Apr 2003 21:13:58 -0000 1.5
+++ widl.h 6 Jan 2004 02:11:41 -0000
@@ -38,11 +38,14 @@
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 char_number;
extern FILE* header;
-extern FILE* proxy;
#endif
Index: widltypes.h
===================================================================
RCS file: /home/wine/wine/tools/widl/widltypes.h,v
retrieving revision 1.10
diff -u -r1.10 widltypes.h
--- widltypes.h 5 Sep 2003 23:15:40 -0000 1.10
+++ widltypes.h 6 Jan 2004 02:11:41 -0000
@@ -38,6 +38,8 @@
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 @@
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,
@@ -165,6 +178,23 @@
/* parser-internal */
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
--- /dev/null 2003-12-06 19:36:34.000000000 +0100
+++ typelib.h 2004-01-06 03:11:08.000000000 +0100
@@ -0,0 +1,17 @@
+/*
+ * IDL Compiler
+ *
+ * Copyright 2004 Ove Kaaven
+ */
+
+#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
--- /dev/null 2003-12-06 19:36:34.000000000 +0100
+++ typelib.c 2004-01-06 03:26:34.000000000 +0100
@@ -0,0 +1,253 @@
+/*
+ * IDL Compiler
+ *
+ * Copyright 2004 Ove Kaaven
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <assert.h>
+#include <ctype.h>
+#include <signal.h>
+
+#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);
+}
More information about the wine-patches
mailing list