Merged the IDL compiler written by Ove Kaaven.

oldstable
Alexandre Julliard 2002-07-16 03:20:45 +00:00
parent b7d3c79beb
commit 7d4ee77cab
18 changed files with 2644 additions and 2 deletions

3
configure vendored
View File

@ -13314,7 +13314,7 @@ MAKE_DLL_RULES=dlls/Makedll.rules
MAKE_PROG_RULES=programs/Makeprog.rules
ac_config_files="$ac_config_files Make.rules dlls/Makedll.rules programs/Makeprog.rules Makefile debugger/Makefile dlls/Makefile dlls/advapi32/Makefile dlls/avicap32/Makefile dlls/avifil32/Makefile dlls/comcat/Makefile dlls/comctl32/Makefile dlls/commdlg/Makefile dlls/crtdll/Makefile dlls/crypt32/Makefile dlls/d3d8/Makefile dlls/dciman32/Makefile dlls/ddraw/Makefile dlls/devenum/Makefile dlls/dinput/Makefile dlls/dinput8/Makefile dlls/dplay/Makefile dlls/dplayx/Makefile dlls/dsound/Makefile dlls/gdi/Makefile dlls/glu32/Makefile dlls/icmp/Makefile dlls/imagehlp/Makefile dlls/imm32/Makefile dlls/kernel/Makefile dlls/lzexpand/Makefile dlls/mapi32/Makefile dlls/mpr/Makefile dlls/msacm/Makefile dlls/msacm/imaadp32/Makefile dlls/msacm/msadp32/Makefile dlls/msacm/msg711/Makefile dlls/msacm/winemp3/Makefile dlls/msdmo/Makefile dlls/msimg32/Makefile dlls/msisys/Makefile dlls/msnet32/Makefile dlls/msrle32/Makefile dlls/msvcrt/Makefile dlls/msvcrt20/Makefile dlls/msvideo/Makefile dlls/netapi32/Makefile dlls/ntdll/Makefile dlls/odbc32/Makefile dlls/ole32/Makefile dlls/oleaut32/Makefile dlls/olecli/Makefile dlls/oledlg/Makefile dlls/olepro32/Makefile dlls/olesvr/Makefile dlls/opengl32/Makefile dlls/psapi/Makefile dlls/qcap/Makefile dlls/quartz/Makefile dlls/rasapi32/Makefile dlls/richedit/Makefile dlls/rpcrt4/Makefile dlls/serialui/Makefile dlls/setupapi/Makefile dlls/shdocvw/Makefile dlls/shell32/Makefile dlls/shfolder/Makefile dlls/shlwapi/Makefile dlls/snmpapi/Makefile dlls/sti/Makefile dlls/tapi32/Makefile dlls/ttydrv/Makefile dlls/twain/Makefile dlls/url/Makefile dlls/urlmon/Makefile dlls/user/Makefile dlls/version/Makefile dlls/win32s/Makefile dlls/winaspi/Makefile dlls/winedos/Makefile dlls/wineps/Makefile dlls/wininet/Makefile dlls/winmm/Makefile dlls/winmm/joystick/Makefile dlls/winmm/mcianim/Makefile dlls/winmm/mciavi/Makefile dlls/winmm/mcicda/Makefile dlls/winmm/mciseq/Makefile dlls/winmm/mciwave/Makefile dlls/winmm/midimap/Makefile dlls/winmm/wavemap/Makefile dlls/winmm/winealsa/Makefile dlls/winmm/winearts/Makefile dlls/winmm/wineoss/Makefile dlls/winnls/Makefile dlls/winsock/Makefile dlls/winspool/Makefile dlls/wintrust/Makefile dlls/wow32/Makefile dlls/wsock32/Makefile dlls/x11drv/Makefile documentation/Makefile include/Makefile library/Makefile miscemu/Makefile ole/Makefile programs/Makefile programs/avitools/Makefile programs/clock/Makefile programs/cmdlgtst/Makefile programs/control/Makefile programs/expand/Makefile programs/notepad/Makefile programs/osversioncheck/Makefile programs/progman/Makefile programs/regapi/Makefile programs/regedit/Makefile programs/regsvr32/Makefile programs/regtest/Makefile programs/uninstaller/Makefile programs/view/Makefile programs/wcmd/Makefile programs/wineconsole/Makefile programs/winefile/Makefile programs/winemine/Makefile programs/winepath/Makefile programs/winetest/Makefile programs/winhelp/Makefile programs/winver/Makefile server/Makefile tools/Makefile tools/winapi/Makefile tools/winebuild/Makefile tools/winedump/Makefile tools/wmc/Makefile tools/wpp/Makefile tools/wrc/Makefile tsx11/Makefile unicode/Makefile"
ac_config_files="$ac_config_files Make.rules dlls/Makedll.rules programs/Makeprog.rules Makefile debugger/Makefile dlls/Makefile dlls/advapi32/Makefile dlls/avicap32/Makefile dlls/avifil32/Makefile dlls/comcat/Makefile dlls/comctl32/Makefile dlls/commdlg/Makefile dlls/crtdll/Makefile dlls/crypt32/Makefile dlls/d3d8/Makefile dlls/dciman32/Makefile dlls/ddraw/Makefile dlls/devenum/Makefile dlls/dinput/Makefile dlls/dinput8/Makefile dlls/dplay/Makefile dlls/dplayx/Makefile dlls/dsound/Makefile dlls/gdi/Makefile dlls/glu32/Makefile dlls/icmp/Makefile dlls/imagehlp/Makefile dlls/imm32/Makefile dlls/kernel/Makefile dlls/lzexpand/Makefile dlls/mapi32/Makefile dlls/mpr/Makefile dlls/msacm/Makefile dlls/msacm/imaadp32/Makefile dlls/msacm/msadp32/Makefile dlls/msacm/msg711/Makefile dlls/msacm/winemp3/Makefile dlls/msdmo/Makefile dlls/msimg32/Makefile dlls/msisys/Makefile dlls/msnet32/Makefile dlls/msrle32/Makefile dlls/msvcrt/Makefile dlls/msvcrt20/Makefile dlls/msvideo/Makefile dlls/netapi32/Makefile dlls/ntdll/Makefile dlls/odbc32/Makefile dlls/ole32/Makefile dlls/oleaut32/Makefile dlls/olecli/Makefile dlls/oledlg/Makefile dlls/olepro32/Makefile dlls/olesvr/Makefile dlls/opengl32/Makefile dlls/psapi/Makefile dlls/qcap/Makefile dlls/quartz/Makefile dlls/rasapi32/Makefile dlls/richedit/Makefile dlls/rpcrt4/Makefile dlls/serialui/Makefile dlls/setupapi/Makefile dlls/shdocvw/Makefile dlls/shell32/Makefile dlls/shfolder/Makefile dlls/shlwapi/Makefile dlls/snmpapi/Makefile dlls/sti/Makefile dlls/tapi32/Makefile dlls/ttydrv/Makefile dlls/twain/Makefile dlls/url/Makefile dlls/urlmon/Makefile dlls/user/Makefile dlls/version/Makefile dlls/win32s/Makefile dlls/winaspi/Makefile dlls/winedos/Makefile dlls/wineps/Makefile dlls/wininet/Makefile dlls/winmm/Makefile dlls/winmm/joystick/Makefile dlls/winmm/mcianim/Makefile dlls/winmm/mciavi/Makefile dlls/winmm/mcicda/Makefile dlls/winmm/mciseq/Makefile dlls/winmm/mciwave/Makefile dlls/winmm/midimap/Makefile dlls/winmm/wavemap/Makefile dlls/winmm/winealsa/Makefile dlls/winmm/winearts/Makefile dlls/winmm/wineoss/Makefile dlls/winnls/Makefile dlls/winsock/Makefile dlls/winspool/Makefile dlls/wintrust/Makefile dlls/wow32/Makefile dlls/wsock32/Makefile dlls/x11drv/Makefile documentation/Makefile include/Makefile library/Makefile miscemu/Makefile ole/Makefile programs/Makefile programs/avitools/Makefile programs/clock/Makefile programs/cmdlgtst/Makefile programs/control/Makefile programs/expand/Makefile programs/notepad/Makefile programs/osversioncheck/Makefile programs/progman/Makefile programs/regapi/Makefile programs/regedit/Makefile programs/regsvr32/Makefile programs/regtest/Makefile programs/uninstaller/Makefile programs/view/Makefile programs/wcmd/Makefile programs/wineconsole/Makefile programs/winefile/Makefile programs/winemine/Makefile programs/winepath/Makefile programs/winetest/Makefile programs/winhelp/Makefile programs/winver/Makefile server/Makefile tools/Makefile tools/widl/Makefile tools/winapi/Makefile tools/winebuild/Makefile tools/winedump/Makefile tools/wmc/Makefile tools/wpp/Makefile tools/wrc/Makefile tsx11/Makefile unicode/Makefile"
cat >confcache <<\_ACEOF
@ -13921,6 +13921,7 @@ do
"programs/winver/Makefile" ) CONFIG_FILES="$CONFIG_FILES programs/winver/Makefile" ;;
"server/Makefile" ) CONFIG_FILES="$CONFIG_FILES server/Makefile" ;;
"tools/Makefile" ) CONFIG_FILES="$CONFIG_FILES tools/Makefile" ;;
"tools/widl/Makefile" ) CONFIG_FILES="$CONFIG_FILES tools/widl/Makefile" ;;
"tools/winapi/Makefile" ) CONFIG_FILES="$CONFIG_FILES tools/winapi/Makefile" ;;
"tools/winebuild/Makefile" ) CONFIG_FILES="$CONFIG_FILES tools/winebuild/Makefile" ;;
"tools/winedump/Makefile" ) CONFIG_FILES="$CONFIG_FILES tools/winedump/Makefile" ;;

View File

@ -1374,6 +1374,7 @@ programs/winhelp/Makefile
programs/winver/Makefile
server/Makefile
tools/Makefile
tools/widl/Makefile
tools/winapi/Makefile
tools/winebuild/Makefile
tools/winedump/Makefile

View File

@ -0,0 +1,109 @@
/*
* RPC format chars, as found by studying MIDL output.
*/
#ifndef __WINE_RPCFC_H
#define __WINE_RPCFC_H
/* base types */
#define RPC_FC_BYTE 0x01
#define RPC_FC_CHAR 0x02
#define RPC_FC_SMALL 0x03
#define RPC_FC_USMALL 0x04
#define RPC_FC_WCHAR 0x05
#define RPC_FC_SHORT 0x06
#define RPC_FC_USHORT 0x07
#define RPC_FC_LONG 0x08
#define RPC_FC_ULONG 0x09
#define RPC_FC_FLOAT 0x0a
#define RPC_FC_HYPER 0x0b
#define RPC_FC_DOUBLE 0x0c
#define RPC_FC_ENUM32 0x0e
/* other stuff */
#define RPC_FC_RP 0x11 /* ? */
#define RPC_FC_UP 0x12 /* unique pointer */
#define RPC_FC_OP 0x13 /* ? */
#define RPC_FC_FP 0x14 /* full pointer */
/* FC_RP/UP/OP/FP: flags, NdrFcShort(typeofs) */
#define RPC_FC_P_ONSTACK 0x4 /* [alloced_on_stack] */
#define RPC_FC_P_SIMPLEPOINTER 0x8 /* [simple_pointer] */
/* flag 10 is not tagged */
#define RPC_FC_STRUCT 0x15
/* FC_STRUCT: fieldcount-1, NdrFcShort(size), fields */
#define RPC_FC_PSTRUCT 0x16
#define RPC_FC_CSTRUCT 0x17
#define RPC_FC_BOGUS_STRUCT 0x1a
#define RPC_FC_CARRAY 0x1b /* conformant array? */
#define RPC_FC_CVARRAY 0x1c /* conformant varying array? */
#define RPC_FC_SMFARRAY 0x1d /* simple fixed array? */
/* FC_SMFARRAY: fieldcount-1, NdrFcShort(count), type */
#define RPC_FC_BOGUS_ARRAY 0x21
#define RPC_FC_C_WSTRING 0x25
#define RPC_FC_ENCAPSULATED_UNION 0x2a
#define RPC_FC_NON_ENCAPSULATED_UNION 0x2b
#define RPC_FC_IP 0x2f /* interface pointer */
#define RPC_FC_AUTO_HANDLE 0x33
/* FC_AUTO_HANDLE: oldflags, NdrFcLong(?), NdrFcShort(vtbl_idx), NdrFcShort(stacksiz),
* NdrFcShort(?), NdrFcShort(?), oi2flags, parmcount
* parameters: NdrFcShort(flags), NdrFcShort(stackofs), NdrFcShort(typeofs)/basetype */
/* oldflags: 6c = object + oi2 */
#define RPC_FC_AH_OI2F_SRVMUSTSIZE 0x01
#define RPC_FC_AH_OI2F_CLTMUSTSIZE 0x02
#define RPC_FC_AH_OI2F_HASRETURN 0x04
#define RPC_FC_AH_PF_IN 0x0008
#define RPC_FC_AH_PF_OUT 0x0010
#define RPC_FC_AH_PF_RETURN 0x0020
#define RPC_FC_AH_PF_BASETYPE 0x0040
#define RPC_FC_AH_PF_BYVAL 0x0080
#define RPC_FC_AH_PF_SIMPLEREF 0x0100
/* PF: 03 = mustsize + mustfree */
/* 2000 = srv alloc size=8, 4000 = srv alloc size=16 */
#define RPC_FC_POINTER 0x36
#define RPC_FC_ALIGNM4 0x38
#define RPC_FC_ALIGNM8 0x39
#define RPC_FC_STRUCTPAD2 0x3e
#define RPC_FC_NO_REPEAT 0x46
#define RPC_FC_VARIABLE_REPEAT 0x48
#define RPC_FC_FIXED_OFFSET 0x49
#define RPC_FC_PP 0x4b
#define RPC_FC_EMBEDDED_COMPLEX 0x4c
/* FC_EMBEDDED_COMPLEX: fieldcount-1, NdrFcShort(typeofs) */
#define RPC_FC_IN_PARAM 0x4d
/* FC_IN_PARAM: stacksiz, NdrFcShort(typeofs) */
#define RPC_FC_IN_PARAM_BASETYPE 0x4e
/* FC_IN_PARAM_BASETYPE: basetype */
#define RPC_FC_OUT_PARAM 0x51
/* FC_OUT_PARAM: stacksiz, NdrFcShort(typeofs) */
#define RPC_FC_RETURN_PARAM_BASETYPE 0x53
/* FC_RETURN_PARAM_BASETYPE: basetype */
#define RPC_FC_DEREFERENCE 0x54
#define RPC_FC_CONSTANT_IID 0x5a
/* FC_CONSTANT_IID: NdrFcLong(), NdrFcShort(), NdrFcShort(), 8x () */
#define RPC_FC_END 0x5b
#define RPC_FC_PAD 0x5c
#define RPC_FC_USER_MARSHAL 0xb4
#endif /* __WINE_RPCFC_H */

View File

@ -10,6 +10,7 @@ MODULE = none
C_SRCS = makedep.c fnt2bdf.c bin2res.c
SUBDIRS = \
widl \
winebuild \
winedump \
wmc \
@ -28,7 +29,7 @@ all: $(PROGRAMS) $(SUBDIRS)
@MAKE_RULES@
wrc: wpp
widl wrc: wpp
makedep: makedep.o
$(CC) $(CFLAGS) -o makedep makedep.o

View File

@ -0,0 +1,5 @@
Makefile
lex.yy.c
widl
y.tab.c
y.tab.h

View File

@ -0,0 +1,50 @@
DEFS = -D__WINE__
TOPSRCDIR = @top_srcdir@
TOPOBJDIR = ../..
SRCDIR = @srcdir@
VPATH = @srcdir@
LEXOPT = -Cf #-w -b
YACCOPT = #-v
EXEEXT = @EXEEXT@
EXTRAINCL = -I$(TOPSRCDIR)/tools/wpp
EXTRALIBS = -L$(TOPOBJDIR)/tools/wpp -lwpp
PROGRAMS = widl$(EXEEXT)
MODULE = none
C_SRCS = \
header.c \
proxy.c \
utils.c \
widl.c
EXTRA_SRCS = parser.y parser.l
EXTRA_OBJS = y.tab.o @LEX_OUTPUT_ROOT@.o
all: $(PROGRAMS)
@MAKE_RULES@
widl: $(OBJS) $(TOPOBJDIR)/tools/wpp/libwpp.a
$(CC) $(CFLAGS) -o widl $(OBJS) $(EXTRALIBS) $(LIBWINE) $(LIBUNICODE) $(LEXLIB) $(LDFLAGS)
widl.exe: $(OBJS) $(TOPOBJDIR)/tools/wpp/libwpp.a
$(CC) $(CFLAGS) -o widl.exe $(OBJS) $(EXTRALIBS) $(LIBWINE) $(LIBUNICODE) $(LEXLIB) -liberty $(LDFLAGS)
y.tab.c y.tab.h: parser.y
$(YACC) $(YACCOPT) -d -t $(SRCDIR)/parser.y
@LEX_OUTPUT_ROOT@.c: parser.l
$(LEX) $(LEXOPT) -d -8 $(SRCDIR)/parser.l
clean::
$(RM) parser.output parser.tab.h lex.backup y.output
install:: $(PROGRAMS)
$(MKINSTALLDIRS) $(bindir)
$(INSTALL_PROGRAM) widl$(EXEEXT) $(bindir)/widl$(EXEEXT)
uninstall::
$(RM) $(bindir)/widl$(EXEEXT)
### Dependencies:

408
tools/widl/header.c 100644
View File

@ -0,0 +1,408 @@
/*
* IDL Compiler
*
* Copyright 2002 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 "proxy.h"
#include "y.tab.h"
static int indentation = 0;
static void indent(int delta)
{
int c;
if (delta < 0) indentation += delta;
for (c=0; c<indentation; c++) fprintf(header, " ");
if (delta > 0) indentation += delta;
}
int is_void(type_t *t, var_t *v)
{
if (v && v->ptr_level) return 0;
if (!t->type && !t->ref) return 1;
return 0;
}
static void write_pident(var_t *v)
{
int c;
for (c=0; c<v->ptr_level; c++) {
fprintf(header, "*");
}
if (v->name) fprintf(header, "%s", v->name);
}
void write_name(FILE *h, var_t *v)
{
fprintf(h, "%s", v->name);
}
char* get_name(var_t *v)
{
return v->name;
}
static void write_fields(FILE *h, var_t *v)
{
if (!v) return;
while (NEXT_LINK(v)) v = NEXT_LINK(v);
while (v) {
if (v->type) {
indent(0);
write_type(h, v->type, NULL, v->tname);
if (get_name(v)) {
fprintf(header, " ");
write_pident(v);
}
fprintf(header, ";\n");
}
v = PREV_LINK(v);
}
}
void write_type(FILE *h, type_t *t, var_t *v, char *n)
{
int c;
if (n) fprintf(h, "%s", n);
else {
if (t->is_const) fprintf(h, "const ");
if (t->type) {
switch (t->type) {
case RPC_FC_BYTE:
fprintf(h, "byte");
break;
case RPC_FC_CHAR:
fprintf(h, "char");
break;
case RPC_FC_USHORT:
fprintf(h, "unsigned ");
case RPC_FC_SHORT:
if (t->ref) fprintf(h, t->ref->name);
fprintf(h, "short");
break;
case RPC_FC_ULONG:
fprintf(h, "unsigned ");
case RPC_FC_LONG:
if (t->ref) fprintf(h, t->ref->name);
else fprintf(h, "long");
break;
case RPC_FC_STRUCT:
if (t->defined && !t->written) {
if (t->name) fprintf(h, "struct %s {\n", t->name);
else fprintf(h, "struct {\n");
indentation++;
write_fields(h, t->fields);
indent(-1);
fprintf(h, "}");
}
else fprintf(h, "struct %s", t->name);
break;
case RPC_FC_NON_ENCAPSULATED_UNION:
if (t->defined && !t->written) {
if (t->name) fprintf(h, "union %s {\n", t->name);
else fprintf(h, "union {\n");
indentation++;
write_fields(h, t->fields);
indent(-1);
fprintf(h, "}");
}
else fprintf(h, "union %s", t->name);
break;
default:
fprintf(h, "(unknown-type:%d)", t->type);
}
}
else {
if (t->ref) {
write_type(h, t->ref, NULL, t->name);
}
else fprintf(h, "void");
}
}
if (v) {
for (c=0; c<v->ptr_level; c++) {
fprintf(h, "*");
}
}
}
void write_typedef(type_t *type, var_t *names)
{
char *tname = names->tname;
while (NEXT_LINK(names)) names = NEXT_LINK(names);
fprintf(header, "typedef ");
write_type(header, type, NULL, tname);
fprintf(header, " ");
while (names) {
write_pident(names);
if (PREV_LINK(names))
fprintf(header, ", ");
names = PREV_LINK(names);
}
fprintf(header, ";\n");
}
/********** INTERFACES **********/
int is_object(attr_t *a)
{
while (a) {
if (a->type == tOBJECT) return 1;
a = NEXT_LINK(a);
}
return 0;
}
int is_local(attr_t *a)
{
while (a) {
if (a->type == tLOCAL) return 1;
a = NEXT_LINK(a);
}
return 0;
}
var_t *is_callas(attr_t *a)
{
while (a) {
if (a->type == tCALLAS) return a->u.pval;
a = NEXT_LINK(a);
}
return NULL;
}
static void write_method_def(type_t *iface)
{
func_t *cur = iface->funcs;
while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
fprintf(header, "#define %s_METHODS", iface->name);
while (cur) {
var_t *def = cur->def;
if (!is_callas(def->attrs)) {
var_t *arg = cur->args;
int argc = 0;
if (arg) {
argc++;
while (NEXT_LINK(arg)) {
arg = NEXT_LINK(arg);
argc++;
}
}
fprintf(header, " \\\n");
if (!is_void(def->type, def)) {
if (argc)
fprintf(header, " ICOM_METHOD%d (", argc);
else
fprintf(header, " ICOM_METHOD (");
write_type(header, def->type, def, def->tname);
fprintf(header, ",");
} else
if (argc)
fprintf(header, " ICOM_VMETHOD%d(", argc);
else
fprintf(header, " ICOM_VMETHOD (");
write_name(header, def);
while (arg) {
fprintf(header, ",");
write_type(header, arg->type, arg, arg->tname);
fprintf(header, ",");
write_name(header,arg);
arg = PREV_LINK(arg);
}
fprintf(header, ")");
}
cur = PREV_LINK(cur);
}
fprintf(header, "\n");
}
static int write_method_macro(type_t *iface, char *name)
{
int idx;
func_t *cur = iface->funcs;
while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
if (iface->ref) idx = write_method_macro(iface->ref, name);
else idx = 0;
fprintf(header, "/*** %s methods ***/\n", iface->name);
while (cur) {
var_t *def = cur->def;
if (!is_callas(def->attrs)) {
var_t *arg = cur->args;
int argc = 0;
int c;
while (arg) {
arg = NEXT_LINK(arg);
argc++;
}
fprintf(header, "#define %s_", name);
write_name(header,def);
fprintf(header, "(p");
for (c=0; c<argc; c++)
fprintf(header, ",%c", c+'a');
fprintf(header, ") ");
if (argc)
fprintf(header, "ICOM_CALL%d(", argc);
else
fprintf(header, "ICOM_CALL(");
write_name(header,def);
fprintf(header, ",p");
for (c=0; c<argc; c++)
fprintf(header, ",%c", c+'a');
fprintf(header, ")\n");
if (cur->idx == -1) cur->idx = idx;
else if (cur->idx != idx) yyerror("BUG: method index mismatch in write_method_macro");
idx++;
}
cur = PREV_LINK(cur);
}
return idx;
}
void write_method_args(FILE *h, var_t *arg, char *name)
{
if (arg) {
while (NEXT_LINK(arg))
arg = NEXT_LINK(arg);
}
fprintf(h, " %s* This", name);
while (arg) {
fprintf(h, ",\n ");
write_type(h, arg->type, arg, arg->tname);
fprintf(h, " ");
write_name(h,arg);
arg = PREV_LINK(arg);
}
}
static void write_method_proto(type_t *iface)
{
func_t *cur = iface->funcs;
while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
while (cur) {
var_t *def = cur->def;
var_t *cas = is_callas(def->attrs);
if (!is_local(def->attrs)) {
/* proxy prototype */
write_type(header, def->type, def, def->tname);
fprintf(header, " CALLBACK %s_", iface->name);
write_name(header,def);
fprintf(header, "_Proxy(\n");
write_method_args(header, cur->args, iface->name);
fprintf(header, ");\n");
/* stub prototype */
fprintf(header, "void __RPC_STUB %s_", iface->name);
write_name(header,def);
fprintf(header, "_Stub(\n");
fprintf(header, " IRpcStubBuffer* This,\n");
fprintf(header, " IRpcChannelBuffer* pRpcChannelBuffer,\n");
fprintf(header, " PRPC_MESSAGE pRpcMessage,\n");
fprintf(header, " DWORD* pdwStubPhase);\n");
}
if (cas) {
func_t *m = iface->funcs;
while (m && strcmp(get_name(m->def), cas->name))
m = NEXT_LINK(m);
if (m) {
var_t *mdef = m->def;
/* proxy prototype - use local prototype */
write_type(header, mdef->type, mdef, mdef->tname);
fprintf(header, " CALLBACK %s_", iface->name);
write_name(header, mdef);
fprintf(header, "_Proxy(\n");
write_method_args(header, m->args, iface->name);
fprintf(header, ");\n");
/* stub prototype - use remotable prototype */
write_type(header, def->type, def, def->tname);
fprintf(header, " __RPC_STUB %s_", iface->name);
write_name(header, mdef);
fprintf(header, "_Stub(\n");
write_method_args(header, cur->args, iface->name);
fprintf(header, ");\n");
}
else {
yywarning("invalid call_as attribute (%s -> %s)\n", get_name(def), cas->name);
}
}
cur = PREV_LINK(cur);
}
}
void write_forward(type_t *iface)
{
if (!iface->written) {
fprintf(header, "typedef struct %s %s;\n", iface->name, iface->name);
iface->written = TRUE;
}
}
void write_interface(type_t *iface)
{
if (!is_object(iface->attrs)) {
if (!iface->funcs) return;
yywarning("RPC interfaces not supported yet\n");
return;
}
if (!iface->funcs) {
yywarning("%s has no methods", iface->name);
return;
}
fprintf(header, "/*****************************************************************************\n");
fprintf(header, " * %s interface\n", iface->name);
fprintf(header, " */\n");
write_forward(iface);
if (iface->ref)
fprintf(header, "#define ICOM_INTERFACE %s\n", iface->name);
write_method_def(iface);
fprintf(header, "#define %s_IMETHODS \\\n", iface->name);
if (iface->ref)
fprintf(header, " %s_IMETHODS \\\n", iface->ref->name);
fprintf(header, " %s_METHODS \\\n", iface->name);
if (iface->ref) {
fprintf(header, "ICOM_DEFINE(%s,%s)\n", iface->name, iface->ref->name);
fprintf(header, "#undef ICOM_INTERFACE\n");
}
fprintf(header, "\n");
write_method_macro(iface, iface->name);
fprintf(header, "\n");
write_method_proto(iface);
fprintf(header, "\n");
if (!is_local(iface->attrs))
write_proxy(iface);
}

View File

@ -0,0 +1,36 @@
/*
* IDL Compiler
*
* Copyright 2002 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_HEADER_H
#define __WIDL_HEADER_H
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);
extern void write_type(FILE *h, type_t *t, var_t *v, char *n);
extern int is_object(attr_t *a);
extern int is_local(attr_t *a);
extern var_t *is_callas(attr_t *a);
extern void write_method_args(FILE *h, var_t *arg, char *name);
extern void write_forward(type_t *iface);
extern void write_interface(type_t *iface);
extern void write_typedef(type_t *type, var_t *names);
#endif

View File

@ -0,0 +1,41 @@
/*
* IDL Compiler
*
* Copyright 2002 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_PARSER_H
#define __WIDL_PARSER_H
int yyparse(void);
extern FILE *yyin;
extern char *yytext;
extern int yydebug;
extern int yy_flex_debug;
int yylex(void);
extern int import_stack_ptr;
void do_import(char *fname);
void abort_import(void);
#define parse_only import_stack_ptr
int is_type(const char *name);
#endif

311
tools/widl/parser.l 100644
View File

@ -0,0 +1,311 @@
/*
* IDL Compiler
*
* Copyright 2002 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
*/
%option stack
%option never-interactive
nl \r?\n
ws [ \f\t\r]
cident [a-zA-Z_][0-9a-zA-Z_]*
int [0-9]+
hexd [0-9a-fA-F]
hex 0x{hexd}+
uuid {hexd}{8}-{hexd}{4}-{hexd}{4}-{hexd}{4}-{hexd}{12}
%x QUOTE
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include "widl.h"
#include "utils.h"
#include "parser.h"
#include "wpp.h"
#include "y.tab.h"
#define YY_USE_PROTOS
#define YY_NO_UNPUT
#define YY_NO_TOP_STATE
extern char *temp_name;
static void addcchar(char c);
static char *get_buffered_cstring(void);
static char *cbuffer;
static int cbufidx;
static int cbufalloc = 0;
static int kw_token(const char *kw);
#define MAX_IMPORT_DEPTH 10
struct {
YY_BUFFER_STATE state;
char *temp_name;
} import_stack[MAX_IMPORT_DEPTH];
int import_stack_ptr = 0;
static void pop_import(void);
%}
/*
**************************************************************************
* The flexer starts here
**************************************************************************
*/
%%
^#.*
\" yy_push_state(QUOTE); cbufidx = 0;
<QUOTE>\" {
yy_pop_state();
yylval.str = get_buffered_cstring();
return aSTRING;
}
<QUOTE>\\\\ |
<QUOTE>\\\" addcchar(yytext[1]);
<QUOTE>\\. addcchar('\\'); addcchar(yytext[1]);
<QUOTE>. addcchar(yytext[0]);
{uuid} return aUUID;
{hex} return aNUM;
{int} return aNUM;
{cident} return kw_token(yytext);
\n
{ws}
\<\< return SHL;
\>\> return SHR;
. return yytext[0];
<<EOF>> {
if (import_stack_ptr) pop_import();
else yyterminate();
}
%%
#ifndef yywrap
int yywrap(void)
{
return 1;
}
#endif
static struct {
const char *kw;
int token;
int val;
} keywords[] = {
{"__cdecl", tCDECL},
{"__int64", tINT64},
{"__stdcall", tSTDCALL},
{"_stdcall", tSTDCALL},
{"aggregatable", tAGGREGATABLE},
{"allocate", tALLOCATE},
{"appobject", tAPPOBJECT},
{"arrays", tARRAYS},
{"async", tASYNC},
{"async_uuid", tASYNCUUID},
{"auto_handle", tAUTOHANDLE},
{"bindable", tBINDABLE},
{"boolean", tBOOLEAN},
{"broadcast", tBROADCAST},
{"byte", tBYTE},
{"byte_count", tBYTECOUNT},
{"call_as", tCALLAS},
{"callback", tCALLBACK},
{"case", tCASE},
{"char", tCHAR},
{"coclass", tCOCLASS},
{"code", tCODE},
{"comm_status", tCOMMSTATUS},
{"const", tCONST},
{"context_handle", tCONTEXTHANDLE},
{"context_handle_noserialize", tCONTEXTHANDLENOSERIALIZE},
{"context_handle_serialize", tCONTEXTHANDLENOSERIALIZE},
{"control", tCONTROL},
{"cpp_quote", tCPPQUOTE},
/* ... */
{"default", tDEFAULT},
/* ... */
{"double", tDOUBLE},
/* ... */
{"enum", tENUM},
/* ... */
{"extern", tEXTERN},
/* ... */
{"float", tFLOAT},
/* ... */
{"hyper", tHYPER},
/* ... */
{"iid_is", tIIDIS},
/* ... */
{"import", tIMPORT},
{"importlib", tIMPORTLIB},
{"in", tIN},
{"include", tINCLUDE},
{"in_line", tINLINE},
{"int", tINT},
/* ... */
{"interface", tINTERFACE},
/* ... */
{"length_is", tLENGTHIS},
/* ... */
{"local", tLOCAL},
{"long", tLONG},
/* ... */
{"object", tOBJECT},
{"odl", tODL},
{"oleautomation", tOLEAUTOMATION},
/* ... */
{"out", tOUT},
/* ... */
{"pointer_default", tPOINTERDEFAULT},
/* ... */
{"ref", tREF},
/* ... */
{"short", tSHORT},
{"signed", tSIGNED},
{"size_is", tSIZEIS},
{"sizeof", tSIZEOF},
/* ... */
{"string", tSTRING},
{"struct", tSTRUCT},
{"switch", tSWITCH},
{"switch_is", tSWITCHIS},
{"switch_type", tSWITCHTYPE},
/* ... */
{"typedef", tTYPEDEF},
{"union", tUNION},
/* ... */
{"unique", tUNIQUE},
{"unsigned", tUNSIGNED},
/* ... */
{"uuid", tUUID},
{"v1_enum", tV1ENUM},
/* ... */
{"version", tVERSION},
{"void", tVOID},
{"wchar_t", tWCHAR},
{"wire_marshal", tWIREMARSHAL},
{NULL}
};
static int kw_token(const char *kw)
{
int i;
for (i=0; keywords[i].kw; i++)
if (strcmp(kw, keywords[i].kw) == 0)
return keywords[i].token;
yylval.str = xstrdup(kw);
return is_type(kw) ? aKNOWNTYPE : aIDENTIFIER;
}
static void addcchar(char c)
{
if(cbufidx >= cbufalloc)
{
cbufalloc += 1024;
cbuffer = xrealloc(cbuffer, cbufalloc * sizeof(cbuffer[0]));
if(cbufalloc > 65536)
yywarning("Reallocating string buffer larger than 64kB");
}
cbuffer[cbufidx++] = c;
}
static char *get_buffered_cstring(void)
{
addcchar(0);
return xstrdup(cbuffer);
}
static void pop_import(void)
{
int ptr = import_stack_ptr-1;
fclose(yyin);
yy_delete_buffer( YY_CURRENT_BUFFER );
yy_switch_to_buffer( import_stack[ptr].state );
if (temp_name) {
unlink(temp_name);
free(temp_name);
}
temp_name = import_stack[ptr].temp_name;
import_stack_ptr--;
}
struct imports {
char *name;
struct imports *next;
} *first_import;
void do_import(char *fname)
{
FILE *f;
char *hname, *path;
struct imports *import;
int ptr = import_stack_ptr;
int ret;
if (!parse_only) {
hname = dup_basename(fname, ".idl");
strcat(hname, ".h");
fprintf(header, "#include \"%s\"\n", hname);
free(hname);
}
import = first_import;
while (import && strcmp(import->name, fname))
import = import->next;
if (import) return; /* already imported */
import = xmalloc(sizeof(struct imports));
import->name = xstrdup(fname);
import->next = first_import;
first_import = import;
if (!(path = wpp_find_include( fname, 1 )))
yyerror("Unable to open include file %s", fname);
import_stack[ptr].temp_name = temp_name;
import_stack_ptr++;
ret = wpp_parse_temp( path, &temp_name );
free( path );
if (ret) exit(1);
if((f = fopen(temp_name, "r")) == NULL)
yyerror("Unable to open %s", temp_name);
import_stack[ptr].state = YY_CURRENT_BUFFER;
yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE));
}
void abort_import(void)
{
int ptr;
for (ptr=0; ptr<import_stack_ptr; ptr++)
unlink(import_stack[ptr].temp_name);
}

679
tools/widl/parser.y 100644
View File

@ -0,0 +1,679 @@
%{
/*
* IDL Compiler
*
* Copyright 2002 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 <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include <string.h>
#ifdef HAVE_ALLOCA_H
#include <alloca.h>
#endif
#include "widl.h"
#include "utils.h"
#include "parser.h"
#include "header.h"
#if defined(YYBYACC)
/* Berkeley yacc (byacc) doesn't seem to know about these */
/* Some *BSD supplied versions do define these though */
# ifndef YYEMPTY
# define YYEMPTY (-1) /* Empty lookahead value of yychar */
# endif
# ifndef YYLEX
# define YYLEX yylex()
# endif
#elif defined(YYBISON)
/* Bison was used for original development */
/* #define YYEMPTY -2 */
/* #define YYLEX yylex() */
#else
/* No yacc we know yet */
# if !defined(YYEMPTY) || !defined(YYLEX)
# error Yacc version/type unknown. This version needs to be verified for settings of YYEMPTY and YYLEX.
# elif defined(__GNUC__) /* gcc defines the #warning directive */
# warning Yacc version/type unknown. It defines YYEMPTY and YYLEX, but is not tested
/* #else we just take a chance that it works... */
# endif
#endif
static attr_t *make_attr(int type);
static attr_t *make_attrv(int type, DWORD val);
static attr_t *make_attrp(int type, void *val);
static type_t *make_type(BYTE type, type_t *ref);
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);
static var_t *make_var(char *name);
static func_t *make_func(var_t *def, var_t *args);
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);
static type_t *find_type(char *name, int t);
static type_t *find_type2(char *name, int t);
static type_t *get_type(BYTE type, char *name, int t);
static type_t *get_typev(BYTE type, var_t *name, int t);
#define tsENUM 1
#define tsSTRUCT 2
#define tsUNION 3
static type_t std_int = { "int" };
%}
%union {
attr_t *attr;
type_t *type;
typeref_t *tref;
var_t *var;
func_t *func;
char *str;
int num;
}
%token <str> aIDENTIFIER
%token <str> aKNOWNTYPE
%token <num> aNUM
%token <str> aSTRING
%token <uuid> aUUID
%token SHL SHR
%token tAGGREGATABLE tALLOCATE tAPPOBJECT tARRAYS tASYNC tASYNCUUID
%token tAUTOHANDLE tBINDABLE tBOOLEAN tBROADCAST tBYTE tBYTECOUNT
%token tCALLAS tCALLBACK tCASE tCDECL tCHAR tCOCLASS tCODE tCOMMSTATUS
%token tCONST tCONTEXTHANDLE tCONTEXTHANDLENOSERIALIZE
%token tCONTEXTHANDLESERIALIZE tCONTROL tCPPQUOTE
%token tDEFAULT
%token tDOUBLE
%token tENUM
%token tEXTERN
%token tFLOAT
%token tHYPER
%token tIIDIS
%token tIMPORT tIMPORTLIB
%token tIN tINCLUDE tINLINE
%token tINT tINT64
%token tINTERFACE
%token tLENGTHIS
%token tLOCAL
%token tLONG
%token tOBJECT tODL tOLEAUTOMATION
%token tOUT
%token tPOINTERDEFAULT
%token tREF
%token tSHORT
%token tSIGNED
%token tSIZEIS tSIZEOF
%token tSTDCALL
%token tSTRING tSTRUCT
%token tSWITCH tSWITCHIS tSWITCHTYPE
%token tTYPEDEF
%token tUNION
%token tUNIQUE
%token tUNSIGNED
%token tUUID
%token tV1ENUM
%token tVERSION
%token tVOID
%token tWCHAR tWIREMARSHAL
/* used in attr_t */
%token tPOINTERTYPE
%type <attr> m_attributes attributes attrib_list attribute
%type <type> inherit interface interfacedef
%type <type> base_type int_std
%type <type> enumdef structdef typedef uniondef
%type <tref> type
%type <var> m_args no_args args arg
%type <var> fields field
%type <var> m_ident t_ident ident p_ident pident pident_list
%type <func> funcdef statements
%type <num> expr pointer_type
%left ','
%left '|'
%left '&'
%left '-' '+'
%left '*' '/'
%left SHL SHR
%right CAST
%right PPTR
%right NEG
%%
statements: { $$ = NULL; }
| statements funcdef ';' { LINK($2, $1); $$ = $2; }
| statements statement
;
statement: ';' {}
| constdef {}
| cppquote {}
| enumdef ';' { if (!parse_only) { write_type(header, $1, NULL, NULL); fprintf(header, ";\n"); } }
| externdef ';' {}
| import {}
| interface ';' {}
| interfacedef {}
| structdef ';' { if (!parse_only) { write_type(header, $1, NULL, NULL); fprintf(header, ";\n"); } }
| typedef ';' {}
| uniondef ';' { if (!parse_only) { write_type(header, $1, NULL, NULL); fprintf(header, ";\n"); } }
;
cppquote: tCPPQUOTE '(' aSTRING ')' { if (!parse_only) fprintf(header, "%s\n", $3); }
;
import: tIMPORT aSTRING ';' { do_import($2); }
;
m_args: { $$ = NULL; }
| args
;
no_args: tVOID { $$ = NULL; }
;
args: arg
| args ',' arg { LINK($3, $1); $$ = $3; }
| no_args
;
/* split into two rules to get bison to resolve a tVOID conflict */
arg: attributes type pident array { $$ = $3;
set_type($$, $2);
$$->attrs = $1; /* FIXME: array */
}
| type pident array { $$ = $2;
set_type($$, $1); /* FIXME: array */
}
;
aexprs:
| aexpr_list
;
aexpr_list: aexpr
| aexprs ',' aexpr
;
aexpr: aNUM {}
| aIDENTIFIER {}
| aexpr '|' aexpr
| aexpr '&' aexpr
| aexpr '+' aexpr
| aexpr '-' aexpr
| aexpr '*' aexpr
| aexpr '/' aexpr
| '-' aexpr %prec NEG
| '*' aexpr %prec PPTR
| '(' type ')' aexpr %prec CAST
| '(' aexpr ')'
| tSIZEOF '(' type ')'
;
array:
| '[' aexprs ']'
| '[' '*' ']'
;
m_attributes: { $$ = NULL; }
| attributes
;
attributes:
m_attributes '[' attrib_list ']' { LINK_LAST($3, $1); $$ = $3; }
;
attrib_list: attribute
| attrib_list ',' attribute { LINK_SAFE($3, $1); $$ = $3; /* FIXME: don't use SAFE */ }
;
attribute:
tASYNC { $$ = make_attr(tASYNC); }
| tCALLAS '(' ident ')' { $$ = make_attrp(tCALLAS, $3); }
| tCASE '(' expr_list ')' { $$ = NULL; }
| tCONTEXTHANDLE { $$ = NULL; }
| tCONTEXTHANDLENOSERIALIZE { $$ = NULL; }
| tCONTEXTHANDLESERIALIZE { $$ = NULL; }
| tDEFAULT { $$ = make_attr(tDEFAULT); }
| tIIDIS '(' ident ')' { $$ = make_attrp(tIIDIS, $3); }
| tIN { $$ = make_attr(tIN); }
| tLENGTHIS '(' aexprs ')' { $$ = NULL; }
| tLOCAL { $$ = make_attr(tLOCAL); }
| tOBJECT { $$ = make_attr(tOBJECT); }
| tOLEAUTOMATION { $$ = make_attr(tOLEAUTOMATION); }
| tOUT { $$ = make_attr(tOUT); }
| tPOINTERDEFAULT '(' pointer_type ')' { $$ = make_attrv(tPOINTERDEFAULT, $3); }
| tSIZEIS '(' aexprs ')' { $$ = NULL; }
| tSTRING { $$ = make_attr(tSTRING); }
| tSWITCHIS '(' aexpr ')' { $$ = NULL; }
| tSWITCHTYPE '(' type ')' { $$ = NULL; }
| tUUID '(' aUUID ')' { $$ = NULL; }
| tV1ENUM { $$ = make_attr(tV1ENUM); }
| tVERSION '(' version ')' { $$ = NULL; }
| tWIREMARSHAL '(' type ')' { $$ = make_attrp(tWIREMARSHAL, type_ref($3)); }
| pointer_type { $$ = make_attrv(tPOINTERTYPE, $1); }
;
callconv:
| tSTDCALL
;
cases:
| cases case
;
case: tCASE expr ':' field
| tDEFAULT ':' field
;
constdef: tCONST type ident '=' expr
;
enums:
| enum_list ','
| enum_list
;
enum_list: enum
| enum_list ',' enum
;
enum: ident '=' expr {}
| ident {}
;
enumdef: tENUM t_ident '{' enums '}' { $$ = get_typev(RPC_FC_SHORT /* FIXME */, $2, tsENUM);
$$->defined = TRUE;
}
;
expr_list: expr {}
| expr_list ',' expr {}
;
expr: aNUM
| aIDENTIFIER {}
| expr '|' expr {}
| expr SHL expr {}
| expr SHR expr {}
| '-' expr %prec NEG {}
;
externdef: tEXTERN tCONST type ident
;
fields: { $$ = NULL; }
| fields field { LINK($2, $1); $$ = $2; }
;
field: m_attributes type pident array ';' { $$ = $3; set_type($$, $2); $$->attrs = $1; /* FIXME: array */ }
| m_attributes uniondef ';' { $$ = make_var(NULL); $$->type = $2; $$->attrs = $1; }
| attributes ';' { $$ = make_var(NULL); $$->attrs = $1; }
| ';' { $$ = NULL; }
;
funcdef:
m_attributes type callconv pident
'(' m_args ')' { set_type($4, $2);
$4->attrs = $1;
$$ = make_func($4, $6);
}
;
m_ident: { $$ = NULL; }
| ident
;
t_ident: { $$ = NULL; }
| aIDENTIFIER { $$ = make_var($1); }
| aKNOWNTYPE { $$ = make_var($1); }
;
ident: aIDENTIFIER { $$ = make_var($1); }
;
base_type: tBYTE { $$ = make_type(RPC_FC_BYTE, NULL); }
| tCHAR { $$ = make_type(RPC_FC_CHAR, NULL); }
| tUNSIGNED tCHAR { $$ = make_type(RPC_FC_CHAR, NULL); }
| tWCHAR { $$ = make_type(RPC_FC_WCHAR, NULL); }
| int_std
| tSIGNED int_std { $$ = $2; /* FIXME */ }
| tUNSIGNED int_std { $$ = $2; /* FIXME */ }
| tFLOAT { $$ = make_type(RPC_FC_FLOAT, NULL); }
| tDOUBLE { $$ = make_type(RPC_FC_DOUBLE, NULL); }
| tBOOLEAN { $$ = make_type(RPC_FC_BYTE, NULL); /* ? */ }
;
m_int:
| tINT
;
int_std: tINT { $$ = make_type(RPC_FC_LONG, &std_int); } /* win32 only */
| tSHORT m_int { $$ = make_type(RPC_FC_SHORT, NULL); }
| tLONG m_int { $$ = make_type(RPC_FC_LONG, NULL); }
| tHYPER m_int { $$ = make_type(RPC_FC_HYPER, NULL); }
| tINT64 { $$ = make_type(RPC_FC_HYPER, NULL); }
;
inherit: { $$ = NULL; }
| ':' aKNOWNTYPE { $$ = find_type2($2, 0); }
;
interface: tINTERFACE aIDENTIFIER { $$ = get_type(RPC_FC_IP, $2, 0); if (!parse_only) write_forward($$); }
| tINTERFACE aKNOWNTYPE { $$ = get_type(RPC_FC_IP, $2, 0); if (!parse_only) write_forward($$); }
;
interfacedef: attributes interface inherit
'{' statements '}' { $$ = $2;
if ($$->defined) yyerror("multiple definition error\n");
$$->ref = $3;
$$->attrs = $1;
$$->funcs = $5;
$$->defined = TRUE;
if (!parse_only) write_interface($$);
}
;
p_ident: '*' pident %prec PPTR { $$ = $2; $$->ptr_level++; }
| tCONST p_ident { $$ = $2; }
;
pident: ident
| p_ident
| '(' pident ')' { $$ = $2; }
;
pident_list:
pident
| pident_list ',' pident { LINK($3, $1); $$ = $3; }
;
pointer_type:
tREF { $$ = RPC_FC_RP; }
| tUNIQUE { $$ = RPC_FC_UP; }
;
structdef: tSTRUCT t_ident '{' fields '}' { $$ = get_typev(RPC_FC_STRUCT, $2, tsSTRUCT);
$$->fields = $4;
$$->defined = TRUE;
}
;
type: tVOID { $$ = make_tref(NULL, make_type(0, NULL)); }
| aKNOWNTYPE { $$ = make_tref($1, find_type($1, 0)); }
| base_type { $$ = make_tref(NULL, $1); }
| tCONST type { $$ = uniq_tref($2); $$->ref->is_const = TRUE; }
| enumdef { $$ = make_tref(NULL, $1); }
| tENUM aIDENTIFIER { $$ = make_tref(NULL, find_type2($2, tsENUM)); }
| structdef { $$ = make_tref(NULL, $1); }
| tSTRUCT aIDENTIFIER { $$ = make_tref(NULL, get_type(RPC_FC_STRUCT, $2, tsSTRUCT)); }
| uniondef { $$ = make_tref(NULL, $1); }
| tUNION aIDENTIFIER { $$ = make_tref(NULL, find_type2($2, tsUNION)); }
;
typedef: tTYPEDEF m_attributes type pident_list { typeref_t *tref = uniq_tref($3);
$4->tname = tref->name;
tref->name = NULL;
$$ = type_ref(tref);
$$->attrs = $2;
if (!parse_only) write_typedef($$, $4);
reg_types($$, $4, 0);
}
;
uniondef: tUNION t_ident '{' fields '}' { $$ = get_typev(RPC_FC_NON_ENCAPSULATED_UNION, $2, tsUNION);
$$->fields = $4;
$$->defined = TRUE;
}
| tUNION t_ident
tSWITCH '(' type ident ')'
m_ident '{' cases '}' { $$ = get_typev(RPC_FC_ENCAPSULATED_UNION, $2, tsUNION);
$$->defined = TRUE;
}
;
version:
aNUM {}
| aNUM '.' aNUM {}
;
%%
static attr_t *make_attr(int type)
{
attr_t *a = xmalloc(sizeof(attr_t));
a->type = type;
a->u.ival = 0;
return a;
}
static attr_t *make_attrv(int type, DWORD val)
{
attr_t *a = xmalloc(sizeof(attr_t));
a->type = type;
a->u.ival = val;
return a;
}
static attr_t *make_attrp(int type, void *val)
{
attr_t *a = xmalloc(sizeof(attr_t));
a->type = type;
a->u.pval = val;
return a;
}
static type_t *make_type(BYTE type, type_t *ref)
{
type_t *t = xmalloc(sizeof(type_t));
t->name = NULL;
t->type = type;
t->ref = ref;
t->rname = NULL;
t->attrs = NULL;
t->funcs = NULL;
t->fields = NULL;
t->ignore = parse_only;
t->is_const = FALSE;
t->defined = FALSE;
t->written = FALSE;
INIT_LINK(t);
return t;
}
static typeref_t *make_tref(char *name, type_t *ref)
{
typeref_t *t = xmalloc(sizeof(typeref_t));
t->name = name;
t->ref = ref;
t->uniq = ref ? 0 : 1;
return t;
}
static typeref_t *uniq_tref(typeref_t *ref)
{
typeref_t *t = ref;
type_t *tp;
if (t->uniq) return t;
tp = make_type(0, t->ref);
tp->name = t->name;
t->name = NULL;
t->ref = tp;
t->uniq = 1;
return t;
}
static type_t *type_ref(typeref_t *ref)
{
type_t *t = ref->ref;
if (ref->name) free(ref->name);
free(ref);
return t;
}
static void set_type(var_t *v, typeref_t *ref)
{
v->type = ref->ref;
v->tname = ref->name;
ref->name = NULL;
free(ref);
}
static var_t *make_var(char *name)
{
var_t *v = xmalloc(sizeof(var_t));
v->name = name;
v->ptr_level = 0;
v->type = NULL;
v->tname = NULL;
v->attrs = NULL;
INIT_LINK(v);
return v;
}
static func_t *make_func(var_t *def, var_t *args)
{
func_t *f = xmalloc(sizeof(func_t));
f->def = def;
f->args = args;
f->ignore = parse_only;
f->idx = -1;
INIT_LINK(f);
return f;
}
struct rtype {
char *name;
type_t *type;
int t;
struct rtype *next;
};
struct rtype *first;
static type_t *reg_type(type_t *type, char *name, int t)
{
struct rtype *nt;
if (!name) {
yyerror("registering named type without name\n");
return type;
}
nt = xmalloc(sizeof(struct rtype));
nt->name = name;
nt->type = type;
nt->t = t;
nt->next = first;
first = nt;
return type;
}
static type_t *reg_types(type_t *type, var_t *names, int t)
{
type_t *ptr = type;
int ptrc = 0;
while (names) {
var_t *next = NEXT_LINK(names);
if (names->name) {
type_t *cur = ptr;
int cptr = names->ptr_level;
if (cptr > ptrc) {
while (cptr > ptrc) {
cur = ptr = make_type(RPC_FC_FP, cur); /* FIXME: pointer type from attrs? */
ptrc++;
}
} else {
while (cptr < ptrc) {
cur = cur->ref;
cptr++;
}
}
reg_type(cur, names->name, t);
}
free(names);
names = next;
}
return type;
}
static type_t *find_type(char *name, int t)
{
struct rtype *cur = first;
while (cur && (cur->t != t || strcmp(cur->name, name)))
cur = cur->next;
if (!cur) {
yyerror("type %s not found\n", name);
return NULL;
}
return cur->type;
}
static type_t *find_type2(char *name, int t)
{
type_t *tp = find_type(name, t);
free(name);
return tp;
}
int is_type(const char *name)
{
struct rtype *cur = first;
while (cur && (cur->t || strcmp(cur->name, name)))
cur = cur->next;
if (cur) return TRUE;
return FALSE;
}
static type_t *get_type(BYTE type, char *name, int t)
{
struct rtype *cur = NULL;
type_t *tp;
if (name) {
cur = first;
while (cur && (cur->t != t || strcmp(cur->name, name)))
cur = cur->next;
}
if (cur) {
free(name);
return cur->type;
}
tp = make_type(type, NULL);
tp->name = name;
if (!name) return tp;
return reg_type(tp, name, t);
}
static type_t *get_typev(BYTE type, var_t *name, int t)
{
char *sname = NULL;
if (name) {
sname = name->name;
free(name);
}
return get_type(type, sname, t);
}

368
tools/widl/proxy.c 100644
View File

@ -0,0 +1,368 @@
/*
* IDL Compiler
*
* Copyright 2002 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 "y.tab.h"
/* FIXME: support generation of stubless proxies */
static void write_stubdesc(void)
{
fprintf(proxy, "const MIDL_STUB_DESC Object_StubDesc = {\n");
fprintf(proxy, " 0,\n");
fprintf(proxy, " NdrOleAllocate,\n");
fprintf(proxy, " NdrOleFree,\n");
fprintf(proxy, " {0}, 0, 0, 0, 0,\n");
fprintf(proxy, " 0 /* __MIDL_TypeFormatString.Format */\n");
fprintf(proxy, "};\n");
fprintf(proxy, "\n");
}
static void init_proxy(void)
{
if (proxy) return;
proxy = fopen(proxy_name, "w");
fprintf(proxy, "/*** Autogenerated by WIDL %s - Do not edit ***/\n", WIDL_FULLVERSION);
fprintf(proxy, "#include \"rpcproxy.h\"\n");
fprintf(proxy, "#include \"%s\"\n", header_name);
fprintf(proxy, "\n");
write_stubdesc();
}
static void gen_proxy(type_t *iface, func_t *cur, int idx)
{
var_t *def = cur->def;
int has_ret = !is_void(def->type, def);
write_type(proxy, def->type, def, def->tname);
fprintf(proxy, " CALLBACK %s_", iface->name);
write_name(proxy, def);
fprintf(proxy, "_Proxy(\n");
write_method_args(proxy, cur->args, iface->name);
fprintf(proxy, ")\n");
fprintf(proxy, "{\n");
/* local variables */
if (has_ret) {
fprintf(proxy, " ");
write_type(proxy, def->type, def, def->tname);
fprintf(proxy, " _Ret;\n");
}
fprintf(proxy, " RPC_MESSAGE _Msg;\n");
fprintf(proxy, " MIDL_STUB_MESSAGE _StubMsg;\n");
fprintf(proxy, "\n");
/* FIXME: trace */
/* FIXME: clear output vars? */
fprintf(proxy, " NdrProxyInitialize(This, &_Msg, &_StubMsg, &Object_StubDesc, %d);\n", idx);
/* FIXME: size buffer */
fprintf(proxy, " NdrProxyGetBuffer(This, &_StubMsg);\n");
/* FIXME: marshall */
fprintf(proxy, " NdrProxySendReceive(This, &_StubMsg);\n");
/* FIXME: unmarshall */
fprintf(proxy, " NdrProxyFreeBuffer(This, &_StubMsg);\n");
if (has_ret) {
fprintf(proxy, " return _Ret;\n");
}
fprintf(proxy, "}\n");
fprintf(proxy, "\n");
}
static void gen_stub(type_t *iface, func_t *cur, char *cas)
{
var_t *def = cur->def;
var_t *arg;
int has_ret = !is_void(def->type, def);
fprintf(proxy, "void __RPC_STUB %s_", iface->name);
write_name(proxy, def);
fprintf(proxy, "_Stub(\n");
fprintf(proxy, " IRpcStubBuffer* This,\n");
fprintf(proxy, " IRpcChannelBuffer* pRpcChannelBuffer,\n");
fprintf(proxy, " PRPC_MESSAGE pRpcMessage,\n");
fprintf(proxy, " DWORD* pdwStubPhase)\n");
fprintf(proxy, "{\n");
/* local variables */
if (has_ret) {
fprintf(proxy, " ");
write_type(proxy, def->type, def, def->tname);
fprintf(proxy, " _Ret;\n");
}
fprintf(proxy, " %s* _This = (%s*)((CStdStubBuffer*)This)->pvServerObject;\n", iface->name, iface->name);
fprintf(proxy, " MIDL_STUB_MESSAGE _StubMsg;\n");
arg = cur->args;
while (arg) {
fprintf(proxy, " ");
write_type(proxy, arg->type, arg, arg->tname);
fprintf(proxy, " ");
write_name(proxy, arg);
fprintf(proxy, ";\n");
arg = NEXT_LINK(arg);
}
fprintf(proxy, "\n");
/* FIXME: trace */
/* FIXME: clear output vars? */
fprintf(proxy, " NdrStubInitialize(pRpcMessage, &_StubMsg, &Object_StubDesc, pRpcChannelBuffer);\n");
/* FIXME: unmarshall */
fprintf(proxy, " *pdwStubPhase = STUB_CALL_SERVER;\n");
fprintf(proxy, " ");
if (has_ret) fprintf(proxy, "_Ret = ");
fprintf(proxy, "%s_", iface->name);
if (cas) fprintf(proxy, "%s_Stub", cas);
else write_name(proxy, def);
fprintf(proxy, "(_This");
arg = cur->args;
if (arg) {
while (NEXT_LINK(arg)) arg = NEXT_LINK(arg);
while (arg) {
fprintf(proxy, ", ");
write_name(proxy, arg);
arg = PREV_LINK(arg);
}
}
fprintf(proxy, ");\n");
fprintf(proxy, " *pdwStubPhase = STUB_MARSHAL;\n");
/* FIXME: size buffer */
fprintf(proxy, " NdrStubGetBuffer(This, pRpcChannelBuffer, &_StubMsg);\n");
/* FIXME: marshall */
fprintf(proxy, "}\n");
fprintf(proxy, "\n");
}
static int write_proxy_methods(type_t *iface)
{
func_t *cur = iface->funcs;
int i = 0;
while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
if (iface->ref) i = write_proxy_methods(iface->ref);
while (cur) {
var_t *def = cur->def;
if (!is_callas(def->attrs)) {
if (i) fprintf(proxy, ",\n ");
fprintf(proxy, "%s_", iface->name);
write_name(proxy, def);
fprintf(proxy, "_Proxy");
i++;
}
cur = PREV_LINK(cur);
}
return i;
}
static int write_stub_methods(type_t *iface)
{
func_t *cur = iface->funcs;
int i = 0;
while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
if (iface->ref) i = write_stub_methods(iface->ref);
else return i; /* skip IUnknown */
while (cur) {
var_t *def = cur->def;
if (!is_local(def->attrs)) {
if (i) fprintf(proxy, ",\n");
fprintf(proxy, " %s_", iface->name);
write_name(proxy, def);
fprintf(proxy, "_Stub");
i++;
}
cur = PREV_LINK(cur);
}
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)
{
int midx = -1, stubs;
func_t *cur = iface->funcs;
if_list *if_cur;
if (!cur) {
yywarning("%s has no methods", iface->name);
return;
}
while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
/* FIXME: check for [oleautomation], shouldn't generate proxies/stubs if specified */
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");
while (cur) {
var_t *def = cur->def;
if (!is_local(def->attrs)) {
var_t *cas = is_callas(def->attrs);
char *cname = cas ? cas->name : NULL;
int idx = cur->idx;
if (cname) {
func_t *m = iface->funcs;
while (m && strcmp(get_name(m->def), cname))
m = NEXT_LINK(m);
idx = m->idx;
}
gen_proxy(iface, cur, idx);
gen_stub(iface, cur, cname);
if (midx == -1) midx = idx;
else if (midx != idx) yyerror("method index mismatch in write_proxy");
midx++;
}
cur = PREV_LINK(cur);
}
/* proxy vtable */
fprintf(proxy, "const CINTERFACE_PROXY_VTABLE(%d) %sProxyVtbl = {\n", midx, iface->name);
fprintf(proxy, " {&IID_%s},\n", iface->name);
fprintf(proxy, " {");
write_proxy_methods(iface);
fprintf(proxy, "}\n");
fprintf(proxy, "};\n");
fprintf(proxy, "\n");
/* stub vtable */
fprintf(proxy, "static const PRPC_STUB_FUNCTION %s_table[] = {\n", iface->name);
stubs = write_stub_methods(iface);
fprintf(proxy, "\n");
fprintf(proxy, "};\n");
fprintf(proxy, "\n");
fprintf(proxy, "const CInterfaceStubVtbl %sStubVtbl = {\n", iface->name);
fprintf(proxy, " {&IID_%s,\n", iface->name);
fprintf(proxy, " 0,\n");
fprintf(proxy, " %d,\n", stubs+3);
fprintf(proxy, " &%s_table[-3]},\n", iface->name);
fprintf(proxy, " {CStdStubBuffer_METHODS}\n");
fprintf(proxy, "};\n");
fprintf(proxy, "\n");
}
void finish_proxy(void)
{
if_list *lcur = if_first;
if_list *cur;
int c;
if (!lcur) return;
while (NEXT_LINK(lcur)) lcur = NEXT_LINK(lcur);
fprintf(proxy, "const CInterfaceProxyVtbl* _XXX_ProxyVtblList[] = {\n");
cur = lcur;
while (cur) {
fprintf(proxy, " (CInterfaceProxyVtbl*)&%sProxyVtbl,\n", cur->iface->name);
cur = PREV_LINK(cur);
}
fprintf(proxy, " 0\n");
fprintf(proxy, "};\n");
fprintf(proxy, "\n");
fprintf(proxy, "const CInterfaceStubVtbl* _XXX_StubVtblList[] = {\n");
cur = lcur;
while (cur) {
fprintf(proxy, " (CInterfaceStubVtbl*)&%sStubVtbl,\n", cur->iface->name);
cur = PREV_LINK(cur);
}
fprintf(proxy, " 0\n");
fprintf(proxy, "};\n");
fprintf(proxy, "\n");
fprintf(proxy, "const PCInterfaceName _XXX_InterfaceNamesList[] = {\n");
cur = lcur;
while (cur) {
fprintf(proxy, " \"%s\",\n", cur->iface->name);
cur = PREV_LINK(cur);
}
fprintf(proxy, " 0\n");
fprintf(proxy, "};\n");
fprintf(proxy, "\n");
fprintf(proxy, "#define _XXX_CHECK_IID(n) IID_GENERIC_CHECK_IID(_XXX, pIID, n)\n");
fprintf(proxy, "\n");
fprintf(proxy, "int __stdcall _XXX_IID_Lookup(const IID* pIID, int* pIndex)\n");
fprintf(proxy, "{\n");
cur = lcur;
c = 0;
while (cur) {
fprintf(proxy, " if (!_XXX_CHECK_IID(%d)) {\n", c);
fprintf(proxy, " *pIndex = %d\n", c);
fprintf(proxy, " return 1;\n");
fprintf(proxy, " }\n");
cur = PREV_LINK(cur);
c++;
}
fprintf(proxy, " return 0;\n");
fprintf(proxy, "}\n");
fprintf(proxy, "\n");
fprintf(proxy, "const ExtendedProxyFileInfo XXX_ProxyFileInfo = {\n");
fprintf(proxy, " (PCInterfaceProxyVtblList*)&_XXX_ProxyVtblList,\n");
fprintf(proxy, " (PCInterfaceStubVtblList*)&_XXX_StubVtblList,\n");
fprintf(proxy, " (const PCInterfaceName*)&_XXX_InterfaceNamesList,\n");
fprintf(proxy, " 0,\n");
fprintf(proxy, " &_XXX_IID_Lookup,\n");
fprintf(proxy, " %d,\n", c);
fprintf(proxy, " 1\n");
fprintf(proxy, "};\n");
fclose(proxy);
}

27
tools/widl/proxy.h 100644
View File

@ -0,0 +1,27 @@
/*
* IDL Compiler
*
* Copyright 2002 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_PROXY_H
#define __WIDL_PROXY_H
extern void write_proxy(type_t *iface);
extern void finish_proxy(void);
#endif

201
tools/widl/utils.c 100644
View File

@ -0,0 +1,201 @@
/*
* Utility routines
*
* Copyright 1998 Bertho A. Stultiens
* Copyright 2002 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 <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <assert.h>
#include <ctype.h>
#include "wine/unicode.h"
#include "widl.h"
#include "utils.h"
#include "parser.h"
/* #define WANT_NEAR_INDICATION */
#ifdef WANT_NEAR_INDICATION
void make_print(char *str)
{
while(*str)
{
if(!isprint(*str))
*str = ' ';
str++;
}
}
#endif
static void generic_msg(const char *s, const char *t, const char *n, va_list ap)
{
fprintf(stderr, "%s:%d:%d: %s: ", input_name ? input_name : "stdin", line_number, char_number, t);
vfprintf(stderr, s, ap);
#ifdef WANT_NEAR_INDICATION
{
char *cpy;
if(n)
{
cpy = xstrdup(n);
make_print(cpy);
fprintf(stderr, " near '%s'", cpy);
free(cpy);
}
}
#endif
fprintf(stderr, "\n");
}
int yyerror(const char *s, ...)
{
va_list ap;
va_start(ap, s);
generic_msg(s, "Error", yytext, ap);
va_end(ap);
exit(1);
return 1;
}
int yywarning(const char *s, ...)
{
va_list ap;
va_start(ap, s);
generic_msg(s, "Warning", yytext, ap);
va_end(ap);
return 0;
}
void internal_error(const char *file, int line, const char *s, ...)
{
va_list ap;
va_start(ap, s);
fprintf(stderr, "Internal error (please report) %s %d: ", file, line);
vfprintf(stderr, s, ap);
fprintf(stderr, "\n");
va_end(ap);
exit(3);
}
void error(const char *s, ...)
{
va_list ap;
va_start(ap, s);
fprintf(stderr, "Error: ");
vfprintf(stderr, s, ap);
fprintf(stderr, "\n");
va_end(ap);
exit(2);
}
void warning(const char *s, ...)
{
va_list ap;
va_start(ap, s);
fprintf(stderr, "Warning: ");
vfprintf(stderr, s, ap);
fprintf(stderr, "\n");
va_end(ap);
}
void chat(const char *s, ...)
{
if(debuglevel & DEBUGLEVEL_CHAT)
{
va_list ap;
va_start(ap, s);
fprintf(stderr, "FYI: ");
vfprintf(stderr, s, ap);
fprintf(stderr, "\n");
va_end(ap);
}
}
char *dup_basename(const char *name, const char *ext)
{
int namelen;
int extlen = strlen(ext);
char *base;
char *slash;
if(!name)
name = "widl.tab";
slash = strrchr(name, '/');
if (slash)
name = slash + 1;
namelen = strlen(name);
/* +4 for later extension and +1 for '\0' */
base = (char *)xmalloc(namelen +4 +1);
strcpy(base, name);
if(!strcasecmp(name + namelen-extlen, ext))
{
base[namelen - extlen] = '\0';
}
return base;
}
void *xmalloc(size_t size)
{
void *res;
assert(size > 0);
res = malloc(size);
if(res == NULL)
{
error("Virtual memory exhausted.\n");
}
/*
* We set it to 0.
* This is *paramount* because we depend on it
* just about everywhere in the rest of the code.
*/
memset(res, 0, size);
return res;
}
void *xrealloc(void *p, size_t size)
{
void *res;
assert(size > 0);
res = realloc(p, size);
if(res == NULL)
{
error("Virtual memory exhausted.\n");
}
return res;
}
char *xstrdup(const char *str)
{
char *s;
assert(str != NULL);
s = (char *)xmalloc(strlen(str)+1);
return strcpy(s, str);
}

41
tools/widl/utils.h 100644
View File

@ -0,0 +1,41 @@
/*
* Utility routines' prototypes etc.
*
* Copyright 1998 Bertho A. Stultiens (BS)
*
* 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_UTILS_H
#define __WIDL_UTILS_H
#include "widltypes.h"
#include <stddef.h> /* size_t */
void *xmalloc(size_t);
void *xrealloc(void *, size_t);
char *xstrdup(const char *str);
int yyerror(const char *s, ...) __attribute__((format (printf, 1, 2)));
int yywarning(const char *s, ...) __attribute__((format (printf, 1, 2)));
void internal_error(const char *file, int line, const char *s, ...) __attribute__((format (printf, 3, 4)));
void error(const char *s, ...) __attribute__((format (printf, 1, 2)));
void warning(const char *s, ...) __attribute__((format (printf, 1, 2)));
void chat(const char *s, ...) __attribute__((format (printf, 1, 2)));
char *dup_basename(const char *name, const char *ext);
#endif

213
tools/widl/widl.c 100644
View File

@ -0,0 +1,213 @@
/*
* IDL Compiler
*
* Copyright 2002 Ove Kaaven
* based on WRC code by Bertho Stultiens
*
* 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>
#define WIDL_FULLVERSION "0.1"
#include "widl.h"
#include "utils.h"
#include "parser.h"
#include "proxy.h"
#include "wpp.h"
static char usage[] =
"Usage: widl [options...] infile.idl\n"
" -d n Set debug level to 'n'\n"
" -D id[=val] Define preprocessor identifier id=val\n"
" -E Preprocess only\n"
" -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"
" -V Print version and exit\n"
" -W Enable pedantic warnings\n"
"Debug level 'n' is a bitmask with following meaning:\n"
" * 0x01 Tell which resource is parsed (verbose mode)\n"
" * 0x02 Dump internal structures\n"
" * 0x04 Create a parser trace (yydebug=1)\n"
" * 0x08 Preprocessor messages\n"
" * 0x10 Preprocessor lex messages\n"
" * 0x20 Preprocessor yacc trace\n"
;
char version_string[] = "Wine IDL Compiler Version " WIDL_FULLVERSION "\n"
"Copyright 2002 Ove Kaaven\n";
int win32 = 1;
int debuglevel = DEBUGLEVEL_NONE;
int pedantic = 0;
int preprocess_only = 0;
int no_preprocess = 0;
char *input_name;
char *header_name;
char *proxy_name;
char *temp_name;
int line_number = 1;
int char_number = 1;
FILE *header;
FILE *proxy;
time_t now;
int getopt (int argc, char *const *argv, const char *optstring);
static void rm_tempfile(void);
static void segvhandler(int sig);
int main(int argc,char *argv[])
{
extern char* optarg;
extern int optind;
int optc;
int ret;
signal(SIGSEGV, segvhandler);
now = time(NULL);
while((optc = getopt(argc, argv, "d:D:EH:I:NVW")) != EOF) {
switch(optc) {
case 'd':
debuglevel = strtol(optarg, NULL, 0);
break;
case 'D':
wpp_add_cmdline_define(optarg);
break;
case 'E':
preprocess_only = 1;
break;
case 'H':
header_name = strdup(optarg);
break;
case 'I':
wpp_add_include_path(optarg);
break;
case 'N':
no_preprocess = 1;
break;
case 'V':
printf(version_string);
return 0;
case 'W':
pedantic = 1;
break;
default:
fprintf(stderr, usage);
return 1;
}
}
if(optind < argc) {
input_name = argv[optind];
}
else {
fprintf(stderr, usage);
return 1;
}
if(debuglevel)
{
setbuf(stdout,0);
setbuf(stderr,0);
}
yydebug = debuglevel & DEBUGLEVEL_TRACE ? 1 : 0;
yy_flex_debug = debuglevel & DEBUGLEVEL_TRACE ? 1 : 0;
wpp_set_debug( (debuglevel & DEBUGLEVEL_PPLEX) != 0,
(debuglevel & DEBUGLEVEL_PPTRACE) != 0,
(debuglevel & DEBUGLEVEL_PPMSG) != 0 );
if (!header_name) {
header_name = dup_basename(input_name, ".idl");
strcat(header_name, ".h");
}
if (!proxy_name) {
proxy_name = dup_basename(input_name, ".idl");
strcat(proxy_name, "_p.c");
}
atexit(rm_tempfile);
if (!no_preprocess)
{
chat("Starting preprocess");
if (!preprocess_only)
{
ret = wpp_parse_temp( input_name, &temp_name );
}
else
{
ret = wpp_parse( input_name, stdout );
}
if(ret) exit(1);
if(preprocess_only) exit(0);
input_name = temp_name;
}
if(!(yyin = fopen(input_name, "r"))) {
fprintf(stderr, "Could not open %s for input\n", input_name);
return 1;
}
header = fopen(header_name, "w");
fprintf(header, "/*** Autogenerated by WIDL %s - Do not edit ***/\n", WIDL_FULLVERSION);
ret = yyparse();
finish_proxy();
fclose(header);
fclose(yyin);
if(ret) {
exit(1);
}
return 0;
}
static void rm_tempfile(void)
{
abort_import();
if(temp_name)
unlink(temp_name);
}
static void segvhandler(int sig)
{
fprintf(stderr, "\n%s:%d: Oops, segment violation\n", input_name, line_number);
fflush(stdout);
fflush(stderr);
abort();
}

53
tools/widl/widl.h 100644
View File

@ -0,0 +1,53 @@
/*
* IDL Compiler
*
* Copyright 2002 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_WIDL_H
#define __WIDL_WIDL_H
#include "widltypes.h"
#include <time.h>
#define WIDL_FULLVERSION "0.1"
extern int debuglevel;
#define DEBUGLEVEL_NONE 0x0000
#define DEBUGLEVEL_CHAT 0x0001
#define DEBUGLEVEL_DUMP 0x0002
#define DEBUGLEVEL_TRACE 0x0004
#define DEBUGLEVEL_PPMSG 0x0008
#define DEBUGLEVEL_PPLEX 0x0010
#define DEBUGLEVEL_PPTRACE 0x0020
extern int win32;
extern int pedantic;
extern char *input_name;
extern char *header_name;
extern char *proxy_name;
extern time_t now;
extern int line_number;
extern int char_number;
extern FILE* header;
extern FILE* proxy;
#endif

View File

@ -0,0 +1,97 @@
/*
* IDL Compiler
*
* Copyright 2002 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_WIDLTYPES_H
#define __WIDL_WIDLTYPES_H
#include "windef.h"
#include "oleauto.h"
#include "wine/rpcfc.h"
typedef struct _attr_t attr_t;
typedef struct _type_t type_t;
typedef struct _typeref_t typeref_t;
typedef struct _var_t var_t;
typedef struct _func_t func_t;
#define DECL_LINK(type) \
type *l_next; \
type *l_prev;
#define LINK(x,y) do { x->l_next = y; if (y) y->l_prev = x; } while (0)
#define LINK_LAST(x,y) do { if (y) { typeof(x) _c = x; while (_c->l_next) _c = _c->l_next; LINK(_c, y); } } while (0)
#define LINK_SAFE(x,y) do { if (x) LINK_LAST(x,y); else { x = y; } } while (0)
#define INIT_LINK(x) do { x->l_next = NULL; x->l_prev = NULL; } while (0)
#define NEXT_LINK(x) ((x)->l_next)
#define PREV_LINK(x) ((x)->l_prev)
struct _attr_t {
int type;
union {
DWORD ival;
void *pval;
} u;
/* parser-internal */
DECL_LINK(attr_t)
};
struct _type_t {
char *name;
BYTE type;
struct _type_t *ref;
char *rname;
attr_t *attrs;
func_t *funcs;
var_t *fields;
int ignore, is_const;
int defined, written;
/* parser-internal */
DECL_LINK(type_t)
};
struct _typeref_t {
char *name;
type_t *ref;
int uniq;
};
struct _var_t {
char *name;
int ptr_level;
type_t *type;
char *tname;
attr_t *attrs;
/* parser-internal */
DECL_LINK(var_t)
};
struct _func_t {
var_t *def;
var_t *args;
int ignore, idx;
/* parser-internal */
DECL_LINK(func_t)
};
#endif