Merged the IDL compiler written by Ove Kaaven.
This commit is contained in:
parent
b7d3c79beb
commit
7d4ee77cab
|
@ -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" ;;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
Makefile
|
||||
lex.yy.c
|
||||
widl
|
||||
y.tab.c
|
||||
y.tab.h
|
|
@ -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:
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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();
|
||||
}
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in New Issue