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:
parent
e6f491aa5c
commit
5d267d7372
|
@ -12,6 +12,7 @@ MODULE = none
|
|||
C_SRCS = \
|
||||
header.c \
|
||||
proxy.c \
|
||||
typelib.c \
|
||||
utils.c \
|
||||
widl.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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue