Commit 5d267d73 authored by Ove Kaaven's avatar Ove Kaaven Committed by Alexandre Julliard

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.
parent e6f491aa
......@@ -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},
/* ... */
{"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,10 +241,15 @@ static struct keyword {
{"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 @@ 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 "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
/*
* 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);
}
/*
* 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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment