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.
This commit is contained in:
Ove Kaaven 2004-01-07 04:21:27 +00:00 committed by Alexandre Julliard
parent e6f491aa5c
commit 5d267d7372
12 changed files with 570 additions and 56 deletions

View File

@ -12,6 +12,7 @@ MODULE = none
C_SRCS = \
header.c \
proxy.c \
typelib.c \
utils.c \
widl.c

View File

@ -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)

View File

@ -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);

View File

@ -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},

View File

@ -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 <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 @@ 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($<str>1); }
| tRETVAL { $$ = make_var($<str>1); }
| tVERSION { $$ = make_var($<str>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)

View File

@ -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) {

View File

@ -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

267
tools/widl/typelib.c Normal file
View File

@ -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 <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);
}

31
tools/widl/typelib.h Normal file
View File

@ -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

View File

@ -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");

View File

@ -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

View File

@ -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