mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-08-26 19:33:31 +00:00
[WIDL][WPP] Sync to wine-10.0
Update widl/wpp tools to Wine-10.0. This is needed for compiling WinRT idl files, and for various winesyncs.
This commit is contained in:
committed by
Timo Kreuzer
parent
ff87209e7c
commit
8608467b84
@@ -8,7 +8,6 @@
|
||||
#define DECLSPEC_HIDDEN
|
||||
|
||||
#include <objbase.h>
|
||||
#include <rpcproxy.h>
|
||||
#include <rpc.h>
|
||||
#include <rpcndr.h>
|
||||
#include <windows.h>
|
||||
|
||||
@@ -790,6 +790,9 @@ static size_t write_type_tfs(ITypeInfo *typeinfo, unsigned char *str,
|
||||
ITypeInfo *refinfo;
|
||||
TYPEATTR *attr;
|
||||
size_t off;
|
||||
#ifdef __REACTOS__
|
||||
GUID guid;
|
||||
#endif
|
||||
|
||||
TRACE("vt %d%s\n", desc->vt, toplevel ? " (toplevel)" : "");
|
||||
|
||||
@@ -811,11 +814,25 @@ static size_t write_type_tfs(ITypeInfo *typeinfo, unsigned char *str,
|
||||
case TKIND_RECORD:
|
||||
off = write_struct_tfs(refinfo, str, len, attr);
|
||||
break;
|
||||
#ifdef __REACTOS__
|
||||
case TKIND_INTERFACE:
|
||||
case TKIND_DISPATCH:
|
||||
/* These are treated as if they were interface pointers. */
|
||||
off = *len;
|
||||
write_ip_tfs(str, len, &attr->guid);
|
||||
break;
|
||||
case TKIND_COCLASS:
|
||||
off = *len;
|
||||
get_default_iface(refinfo, attr->cImplTypes, &guid);
|
||||
write_ip_tfs(str, len, &guid);
|
||||
break;
|
||||
#else
|
||||
case TKIND_INTERFACE:
|
||||
case TKIND_DISPATCH:
|
||||
case TKIND_COCLASS:
|
||||
assert(0);
|
||||
break;
|
||||
#endif
|
||||
case TKIND_ALIAS:
|
||||
off = write_type_tfs(refinfo, str, len, &attr->tdescAlias, toplevel, onstack);
|
||||
break;
|
||||
@@ -1001,6 +1018,14 @@ static HRESULT get_param_info(ITypeInfo *typeinfo, TYPEDESC *tdesc, int is_in,
|
||||
hr = get_param_info(refinfo, &attr->tdescAlias, is_in, is_out,
|
||||
server_size, flags, basetype, tfs_tdesc);
|
||||
break;
|
||||
#ifdef __REACTOS__
|
||||
case TKIND_INTERFACE:
|
||||
case TKIND_DISPATCH:
|
||||
case TKIND_COCLASS:
|
||||
/* These are treated as if they were interface pointers. */
|
||||
*flags |= MustFree;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
FIXME("unhandled kind %#x\n", attr->typekind);
|
||||
hr = E_NOTIMPL;
|
||||
|
||||
@@ -18,8 +18,8 @@ The following build tools are shared with Wine.
|
||||
base/ctf/msctf # Forked at Wine-10.12
|
||||
|
||||
sdk/tools/unicode # Synced to WineStaging-4.18
|
||||
sdk/tools/widl # Synced to WineStaging-4.0
|
||||
sdk/tools/wpp # Synced to WineStaging-2.9
|
||||
sdk/tools/widl # Synced to Wine-10.0
|
||||
sdk/tools/wpp # Synced to Wine-10.0 (Module was moved into wrc tool)
|
||||
|
||||
The following libraries are shared with Wine.
|
||||
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
|
||||
#idl files support
|
||||
if(ARCH STREQUAL "i386")
|
||||
set(IDL_FLAGS -m32 --win32 -b i386-x-y)
|
||||
set(IDL_FLAGS -m32 --win32 -b i386-x-y -nostdinc)
|
||||
elseif(ARCH STREQUAL "amd64")
|
||||
set(IDL_FLAGS -m64 --win64 -b amd64-x-y)
|
||||
set(IDL_FLAGS -m64 --win64 -b amd64-x-y -nostdinc)
|
||||
else()
|
||||
set(IDL_FLAGS -b ${ARCH}-x-y)
|
||||
set(IDL_FLAGS -b ${ARCH}-x-y -nostdinc)
|
||||
endif()
|
||||
|
||||
function(add_typelib)
|
||||
get_includes(INCLUDES)
|
||||
get_defines(DEFINES)
|
||||
get_includes(LIBS)
|
||||
string(REPLACE "-I" "-L" LIBS "${LIBS}")
|
||||
|
||||
foreach(FILE ${ARGN})
|
||||
if(${FILE} STREQUAL "std_ole_v1.idl")
|
||||
set(IDL_FLAGS ${IDL_FLAGS} --oldtlb)
|
||||
@@ -18,7 +21,7 @@ function(add_typelib)
|
||||
get_filename_component(NAME ${FILE} NAME_WE)
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${NAME}.tlb
|
||||
COMMAND native-widl ${INCLUDES} ${DEFINES} ${IDL_FLAGS} -t -o ${CMAKE_CURRENT_BINARY_DIR}/${NAME}.tlb ${CMAKE_CURRENT_SOURCE_DIR}/${FILE}
|
||||
COMMAND native-widl ${INCLUDES} ${LIBS} ${DEFINES} ${IDL_FLAGS} -t -o ${CMAKE_CURRENT_BINARY_DIR}/${NAME}.tlb ${CMAKE_CURRENT_SOURCE_DIR}/${FILE}
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${FILE} native-widl)
|
||||
list(APPEND OBJECTS ${CMAKE_CURRENT_BINARY_DIR}/${NAME}.tlb)
|
||||
endforeach()
|
||||
@@ -28,11 +31,11 @@ function(add_idl_headers TARGET)
|
||||
get_includes(INCLUDES)
|
||||
get_defines(DEFINES)
|
||||
foreach(FILE ${ARGN})
|
||||
get_filename_component(NAME ${FILE} NAME_WE)
|
||||
get_filename_component(NAME ${FILE} NAME_WLE)
|
||||
set(HEADER ${CMAKE_CURRENT_BINARY_DIR}/${NAME}.h)
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${NAME}.h
|
||||
COMMAND native-widl ${INCLUDES} ${DEFINES} ${IDL_FLAGS} -h -o ${CMAKE_CURRENT_BINARY_DIR}/${NAME}.h ${FILE}
|
||||
COMMAND native-widl ${INCLUDES} ${DEFINES} ${IDL_FLAGS} -Oicf -h -o ${CMAKE_CURRENT_BINARY_DIR}/${NAME}.h ${FILE}
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${FILE} native-widl
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
list(APPEND HEADERS ${HEADER})
|
||||
@@ -45,7 +48,7 @@ function(add_rpcproxy_files)
|
||||
get_defines(DEFINES)
|
||||
|
||||
foreach(FILE ${ARGN})
|
||||
get_filename_component(NAME ${FILE} NAME_WE)
|
||||
get_filename_component(NAME ${FILE} NAME_WLE)
|
||||
# Most proxy idl's have names like <proxyname>_<original>.idl
|
||||
# We use this to create a dependency from the proxy to the original idl
|
||||
string(REPLACE "_" ";" SPLIT_FILE ${FILE})
|
||||
@@ -62,8 +65,8 @@ function(add_rpcproxy_files)
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${NAME}_p.c ${CMAKE_CURRENT_BINARY_DIR}/${NAME}_p.h
|
||||
# We generate the two files in two passes because WIDL accepts only one custom file name as output
|
||||
COMMAND native-widl ${INCLUDES} ${DEFINES} ${IDL_FLAGS} -p -o ${CMAKE_CURRENT_BINARY_DIR}/${NAME}_p.c -H ${NAME}_p.h ${FILE}
|
||||
COMMAND native-widl ${INCLUDES} ${DEFINES} ${IDL_FLAGS} -h -o ${CMAKE_CURRENT_BINARY_DIR}/${NAME}_p.h ${FILE}
|
||||
COMMAND native-widl ${INCLUDES} ${DEFINES} ${IDL_FLAGS} -Oicf -p -o ${CMAKE_CURRENT_BINARY_DIR}/${NAME}_p.c -H ${NAME}_p.h ${FILE}
|
||||
COMMAND native-widl ${INCLUDES} ${DEFINES} ${IDL_FLAGS} -Oicf -h -o ${CMAKE_CURRENT_BINARY_DIR}/${NAME}_p.h ${FILE}
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${FILE} ${EXTRA_DEP} native-widl
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
endforeach()
|
||||
@@ -71,7 +74,7 @@ function(add_rpcproxy_files)
|
||||
# Extra pass to generate dlldata
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/proxy.dlldata.c
|
||||
COMMAND native-widl ${INCLUDES} ${DEFINES} ${IDL_FLAGS} --dlldata-only -o ${CMAKE_CURRENT_BINARY_DIR}/proxy.dlldata.c ${IDLS}
|
||||
COMMAND native-widl ${INCLUDES} ${DEFINES} ${IDL_FLAGS} -Oicf --dlldata-only -o ${CMAKE_CURRENT_BINARY_DIR}/proxy.dlldata.c ${IDLS}
|
||||
DEPENDS ${IDL_DEPS} native-widl
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
endfunction()
|
||||
@@ -91,13 +94,13 @@ function(add_rpc_files __type)
|
||||
message(FATAL_ERROR "Please pass either server or client as argument to add_rpc_files")
|
||||
endif()
|
||||
foreach(FILE ${ARGN})
|
||||
get_filename_component(__name ${FILE} NAME_WE)
|
||||
get_filename_component(__name ${FILE} NAME_WLE)
|
||||
set(__name ${__name}${__suffix})
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${__name}.c ${CMAKE_CURRENT_BINARY_DIR}/${__name}.h
|
||||
# We generate the two files in two passes because WIDL accepts only one custom file name as output
|
||||
COMMAND native-widl ${INCLUDES} ${DEFINES} ${IDL_FLAGS} ${__additional_flags} ${__server_client} -o ${CMAKE_CURRENT_BINARY_DIR}/${__name}.c -H ${__name}.h ${FILE}
|
||||
COMMAND native-widl ${INCLUDES} ${DEFINES} ${IDL_FLAGS} ${__additional_flags} -h -o ${CMAKE_CURRENT_BINARY_DIR}/${__name}.h ${FILE}
|
||||
COMMAND native-widl ${INCLUDES} ${DEFINES} ${IDL_FLAGS} -Oicf ${__additional_flags} ${__server_client} -o ${CMAKE_CURRENT_BINARY_DIR}/${__name}.c -H ${__name}.h ${FILE}
|
||||
COMMAND native-widl ${INCLUDES} ${DEFINES} ${IDL_FLAGS} -Oicf ${__additional_flags} -h -o ${CMAKE_CURRENT_BINARY_DIR}/${__name}.h ${FILE}
|
||||
DEPENDS ${FILE} native-widl
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
endforeach()
|
||||
@@ -149,7 +152,7 @@ function(generate_idl_iids)
|
||||
get_filename_component(NAME ${IDL_FILE} NAME_WE)
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${NAME}_i.c
|
||||
COMMAND native-widl ${INCLUDES} ${DEFINES} ${IDL_FLAGS} -u -o ${CMAKE_CURRENT_BINARY_DIR}/${NAME}_i.c ${IDL_FILE}
|
||||
COMMAND native-widl ${INCLUDES} ${DEFINES} ${IDL_FLAGS} -Os -u -o ${CMAKE_CURRENT_BINARY_DIR}/${NAME}_i.c ${IDL_FILE}
|
||||
DEPENDS ${IDL_FILE} native-widl
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
endforeach()
|
||||
@@ -172,7 +175,7 @@ function(add_idl_reg_script IDL_FILE)
|
||||
get_filename_component(NAME ${IDL_FILE} NAME_WE)
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${NAME}_r.res
|
||||
COMMAND native-widl ${INCLUDES} ${DEFINES} ${IDL_FLAGS} -r -o ${CMAKE_CURRENT_BINARY_DIR}/${NAME}_r.res ${IDL_FILE}
|
||||
COMMAND native-widl ${INCLUDES} ${DEFINES} ${IDL_FLAGS} -Oicf -r -o ${CMAKE_CURRENT_BINARY_DIR}/${NAME}_r.res ${IDL_FILE}
|
||||
DEPENDS ${IDL_FILE} native-widl
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/${NAME}_r.res PROPERTIES
|
||||
|
||||
@@ -61,6 +61,68 @@
|
||||
#define IMAGE_REL_I386_REL16 0x0002
|
||||
#define IMAGE_REL_I386_DIR32 0x0006
|
||||
|
||||
/* Helper macro to enable gcc's extension. */
|
||||
#ifndef __GNU_EXTENSION
|
||||
#ifdef __GNUC__
|
||||
#define __GNU_EXTENSION __extension__
|
||||
#else
|
||||
#define __GNU_EXTENSION
|
||||
#endif
|
||||
#endif /* __GNU_EXTENSION */
|
||||
|
||||
|
||||
#ifndef DUMMYUNIONNAME
|
||||
#if defined(NONAMELESSUNION)// || !defined(_MSC_EXTENSIONS)
|
||||
#define _ANONYMOUS_UNION
|
||||
#define _UNION_NAME(x) x
|
||||
#define DUMMYUNIONNAME u
|
||||
#define DUMMYUNIONNAME1 u1
|
||||
#define DUMMYUNIONNAME2 u2
|
||||
#define DUMMYUNIONNAME3 u3
|
||||
#define DUMMYUNIONNAME4 u4
|
||||
#define DUMMYUNIONNAME5 u5
|
||||
#define DUMMYUNIONNAME6 u6
|
||||
#define DUMMYUNIONNAME7 u7
|
||||
#define DUMMYUNIONNAME8 u8
|
||||
#define DUMMYUNIONNAME9 u9
|
||||
#else
|
||||
#define _ANONYMOUS_UNION __GNU_EXTENSION
|
||||
#define _UNION_NAME(x)
|
||||
#define DUMMYUNIONNAME
|
||||
#define DUMMYUNIONNAME1
|
||||
#define DUMMYUNIONNAME2
|
||||
#define DUMMYUNIONNAME3
|
||||
#define DUMMYUNIONNAME4
|
||||
#define DUMMYUNIONNAME5
|
||||
#define DUMMYUNIONNAME6
|
||||
#define DUMMYUNIONNAME7
|
||||
#define DUMMYUNIONNAME8
|
||||
#define DUMMYUNIONNAME9
|
||||
#endif /* NONAMELESSUNION */
|
||||
#endif /* !DUMMYUNIONNAME */
|
||||
|
||||
#ifndef DUMMYSTRUCTNAME
|
||||
#if defined(NONAMELESSUNION)// || !defined(_MSC_EXTENSIONS)
|
||||
#define _ANONYMOUS_STRUCT
|
||||
#define _STRUCT_NAME(x) x
|
||||
#define DUMMYSTRUCTNAME s
|
||||
#define DUMMYSTRUCTNAME1 s1
|
||||
#define DUMMYSTRUCTNAME2 s2
|
||||
#define DUMMYSTRUCTNAME3 s3
|
||||
#define DUMMYSTRUCTNAME4 s4
|
||||
#define DUMMYSTRUCTNAME5 s5
|
||||
#else
|
||||
#define _ANONYMOUS_STRUCT __GNU_EXTENSION
|
||||
#define _STRUCT_NAME(x)
|
||||
#define DUMMYSTRUCTNAME
|
||||
#define DUMMYSTRUCTNAME1
|
||||
#define DUMMYSTRUCTNAME2
|
||||
#define DUMMYSTRUCTNAME3
|
||||
#define DUMMYSTRUCTNAME4
|
||||
#define DUMMYSTRUCTNAME5
|
||||
#endif /* NONAMELESSUNION */
|
||||
#endif /* DUMMYSTRUCTNAME */
|
||||
|
||||
#pragma pack(push,2)
|
||||
typedef struct _IMAGE_DOS_HEADER {
|
||||
WORD e_magic;
|
||||
@@ -102,6 +164,22 @@ typedef struct _IMAGE_DATA_DIRECTORY {
|
||||
DWORD Size;
|
||||
} IMAGE_DATA_DIRECTORY,*PIMAGE_DATA_DIRECTORY;
|
||||
|
||||
#define IMAGE_DIRECTORY_ENTRY_EXPORT 0
|
||||
#define IMAGE_DIRECTORY_ENTRY_IMPORT 1
|
||||
#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2
|
||||
#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3
|
||||
#define IMAGE_DIRECTORY_ENTRY_SECURITY 4
|
||||
#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5
|
||||
#define IMAGE_DIRECTORY_ENTRY_DEBUG 6
|
||||
#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7
|
||||
#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8
|
||||
#define IMAGE_DIRECTORY_ENTRY_TLS 9
|
||||
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10
|
||||
#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11
|
||||
#define IMAGE_DIRECTORY_ENTRY_IAT 12
|
||||
#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13
|
||||
#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14
|
||||
|
||||
typedef struct _IMAGE_OPTIONAL_HEADER32 {
|
||||
WORD Magic;
|
||||
BYTE MajorLinkerVersion;
|
||||
@@ -223,6 +301,48 @@ typedef struct _IMAGE_BASE_RELOCATION {
|
||||
} IMAGE_BASE_RELOCATION,*PIMAGE_BASE_RELOCATION;
|
||||
#pragma pack(pop)
|
||||
|
||||
typedef struct _IMAGE_RESOURCE_DIRECTORY {
|
||||
DWORD Characteristics;
|
||||
DWORD TimeDateStamp;
|
||||
WORD MajorVersion;
|
||||
WORD MinorVersion;
|
||||
WORD NumberOfNamedEntries;
|
||||
WORD NumberOfIdEntries;
|
||||
} IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY;
|
||||
|
||||
#define IMAGE_RESOURCE_NAME_IS_STRING 0x80000000
|
||||
#define IMAGE_RESOURCE_DATA_IS_DIRECTORY 0x80000000
|
||||
|
||||
typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY {
|
||||
_ANONYMOUS_UNION union {
|
||||
_ANONYMOUS_STRUCT struct {
|
||||
DWORD NameOffset:31;
|
||||
DWORD NameIsString:1;
|
||||
} DUMMYSTRUCTNAME;
|
||||
DWORD Name;
|
||||
WORD Id;
|
||||
} DUMMYUNIONNAME;
|
||||
_ANONYMOUS_UNION union {
|
||||
DWORD OffsetToData;
|
||||
_ANONYMOUS_STRUCT struct {
|
||||
DWORD OffsetToDirectory:31;
|
||||
DWORD DataIsDirectory:1;
|
||||
} DUMMYSTRUCTNAME2;
|
||||
} DUMMYUNIONNAME2;
|
||||
} IMAGE_RESOURCE_DIRECTORY_ENTRY, *PIMAGE_RESOURCE_DIRECTORY_ENTRY;
|
||||
|
||||
typedef struct _IMAGE_RESOURCE_DIRECTORY_STRING {
|
||||
USHORT Length;
|
||||
CHAR NameString[ANYSIZE_ARRAY];
|
||||
} IMAGE_RESOURCE_DIRECTORY_STRING, *PIMAGE_RESOURCE_DIRECTORY_STRING;
|
||||
|
||||
typedef struct _IMAGE_RESOURCE_DATA_ENTRY {
|
||||
ULONG OffsetToData;
|
||||
ULONG Size;
|
||||
ULONG CodePage;
|
||||
ULONG Reserved;
|
||||
} IMAGE_RESOURCE_DATA_ENTRY, *PIMAGE_RESOURCE_DATA_ENTRY;
|
||||
|
||||
#ifndef UNALIGNED
|
||||
#define UNALIGNED
|
||||
#endif
|
||||
|
||||
@@ -9284,9 +9284,6 @@ properties:
|
||||
methods:
|
||||
WINE_HTMLDATAELEMENT_DISPINTERFACE_DECL;
|
||||
|
||||
[propget, id(DISPID_IHTMLDOMCONSTRUCTOR_CONSTRUCTOR), hidden]
|
||||
IDispatch* constructor();
|
||||
|
||||
[propput, id(DISPID_IHTMLAREAELEMENT_SHAPE)]
|
||||
void shape(BSTR v);
|
||||
|
||||
|
||||
+22
-1170
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+38
-45
@@ -21,16 +21,6 @@
|
||||
import "basetsd.h";
|
||||
import "guiddef.h";
|
||||
|
||||
cpp_quote("#ifndef __wtypes_h__")
|
||||
cpp_quote("#define __wtypes_h__")
|
||||
cpp_quote("#endif")
|
||||
|
||||
cpp_quote("#ifdef _MSC_VER")
|
||||
cpp_quote("#pragma warning(push)")
|
||||
cpp_quote("#pragma warning(disable:4201)")
|
||||
cpp_quote("#pragma warning(disable:4820)")
|
||||
cpp_quote("#endif")
|
||||
|
||||
[
|
||||
uuid(D3980A60-910C-1068-9341-00DD010F2F1C),
|
||||
version(0.1),
|
||||
@@ -43,7 +33,7 @@ interface IWinTypes
|
||||
/******************** BASIC WIN32 TYPES ********************/
|
||||
cpp_quote("#if 0 /* winnt.h */") /* don't redefine these */
|
||||
|
||||
typedef unsigned char BYTE;
|
||||
typedef byte BYTE;
|
||||
typedef unsigned short WORD;
|
||||
typedef unsigned long DWORD;
|
||||
typedef long BOOL;
|
||||
@@ -120,7 +110,9 @@ typedef struct _SID {
|
||||
UCHAR SubAuthorityCount;
|
||||
SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
|
||||
[size_is(SubAuthorityCount)] ULONG SubAuthority[*];
|
||||
} SID, *PSID;
|
||||
} SID, *PISID;
|
||||
|
||||
typedef void *PSID;
|
||||
|
||||
typedef USHORT SECURITY_DESCRIPTOR_CONTROL, *PSECURITY_DESCRIPTOR_CONTROL;
|
||||
|
||||
@@ -141,12 +133,12 @@ typedef struct _SECURITY_DESCRIPTOR {
|
||||
PSID Group;
|
||||
PACL Sacl;
|
||||
PACL Dacl;
|
||||
} SECURITY_DESCRIPTOR, *PSECURITY_DESCRIPTOR;
|
||||
} SECURITY_DESCRIPTOR, *PISECURITY_DESCRIPTOR;
|
||||
|
||||
typedef struct _SECURITY_ATTRIBUTES
|
||||
{
|
||||
DWORD nLength;
|
||||
LPVOID lpSecurityDescriptor;
|
||||
[size_is(nLength)] LPVOID lpSecurityDescriptor;
|
||||
BOOL bInheritHandle;
|
||||
} SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;
|
||||
|
||||
@@ -297,7 +289,11 @@ typedef WCHAR OLECHAR;
|
||||
typedef [string] OLECHAR *LPOLESTR;
|
||||
typedef [string] const OLECHAR *LPCOLESTR;
|
||||
cpp_quote("#ifndef __WINESRC__")
|
||||
cpp_quote("#define OLESTR(str) L##str")
|
||||
cpp_quote("# ifdef WINE_UNICODE_NATIVE")
|
||||
cpp_quote("# define OLESTR(str) L##str")
|
||||
cpp_quote("# else")
|
||||
cpp_quote("# define OLESTR(str) u##str")
|
||||
cpp_quote("# endif")
|
||||
cpp_quote("#endif")
|
||||
|
||||
typedef LONG SCODE;
|
||||
@@ -342,22 +338,31 @@ cpp_quote("#define ROTFLAGS_ALLOWANYCLIENT 0x2")
|
||||
cpp_quote("#endif")
|
||||
|
||||
typedef enum tagCLSCTX {
|
||||
CLSCTX_INPROC_SERVER = 0x1,
|
||||
CLSCTX_INPROC_HANDLER = 0x2,
|
||||
CLSCTX_LOCAL_SERVER = 0x4,
|
||||
CLSCTX_INPROC_SERVER16 = 0x8,
|
||||
CLSCTX_REMOTE_SERVER = 0x10,
|
||||
CLSCTX_INPROC_HANDLER16 = 0x20,
|
||||
CLSCTX_INPROC_SERVERX86 = 0x40,
|
||||
CLSCTX_INPROC_HANDLERX86 = 0x80,
|
||||
CLSCTX_ESERVER_HANDLER = 0x100,
|
||||
CLSCTX_NO_CODE_DOWNLOAD = 0x400,
|
||||
CLSCTX_NO_CUSTOM_MARSHAL = 0x1000,
|
||||
CLSCTX_ENABLE_CODE_DOWNLOAD = 0x2000,
|
||||
CLSCTX_NO_FAILURE_LOG = 0x4000,
|
||||
CLSCTX_DISABLE_AAA = 0x8000,
|
||||
CLSCTX_ENABLE_AAA = 0x10000,
|
||||
CLSCTX_FROM_DEFAULT_CONTEXT = 0x20000
|
||||
CLSCTX_INPROC_SERVER = 0x00000001,
|
||||
CLSCTX_INPROC_HANDLER = 0x00000002,
|
||||
CLSCTX_LOCAL_SERVER = 0x00000004,
|
||||
CLSCTX_INPROC_SERVER16 = 0x00000008,
|
||||
CLSCTX_REMOTE_SERVER = 0x00000010,
|
||||
CLSCTX_INPROC_HANDLER16 = 0x00000020,
|
||||
CLSCTX_INPROC_SERVERX86 = 0x00000040,
|
||||
CLSCTX_INPROC_HANDLERX86 = 0x00000080,
|
||||
CLSCTX_ESERVER_HANDLER = 0x00000100,
|
||||
CLSCTX_NO_CODE_DOWNLOAD = 0x00000400,
|
||||
CLSCTX_NO_CUSTOM_MARSHAL = 0x00001000,
|
||||
CLSCTX_ENABLE_CODE_DOWNLOAD = 0x00002000,
|
||||
CLSCTX_NO_FAILURE_LOG = 0x00004000,
|
||||
CLSCTX_DISABLE_AAA = 0x00008000,
|
||||
CLSCTX_ENABLE_AAA = 0x00010000,
|
||||
CLSCTX_FROM_DEFAULT_CONTEXT = 0x00020000,
|
||||
CLSCTX_ACTIVATE_X86_SERVER = 0x00040000,
|
||||
CLSCTX_ACTIVATE_32_BIT_SERVER = CLSCTX_ACTIVATE_X86_SERVER,
|
||||
CLSCTX_ACTIVATE_64_BIT_SERVER = 0x00080000,
|
||||
CLSCTX_ENABLE_CLOAKING = 0x00100000,
|
||||
CLSCTX_APPCONTAINER = 0x00400000,
|
||||
CLSCTX_ACTIVATE_AAA_AS_IU = 0x00800000,
|
||||
CLSCTX_RESERVED6 = 0x01000000,
|
||||
CLSCTX_ACTIVATE_ARM32_SERVER = 0x02000000,
|
||||
CLSCTX_PS_DLL = 0x80000000,
|
||||
} CLSCTX;
|
||||
|
||||
cpp_quote("#define CLSCTX_INPROC (CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER)")
|
||||
@@ -560,6 +565,7 @@ typedef [unique] RemotableHandle *wireHFONT;
|
||||
typedef [unique] RemotableHandle *wireHICON;
|
||||
typedef [unique] RemotableHandle *wireHMENU;
|
||||
typedef [unique] RemotableHandle *wireHWND;
|
||||
typedef [unique] RemotableHandle *wireHMONITOR;
|
||||
|
||||
cpp_quote("#if 0") /* for IDL only (C/C++ defs are in windef.h) */
|
||||
DECLARE_WIREM_HANDLE(HACCEL);
|
||||
@@ -569,6 +575,7 @@ DECLARE_WIREM_HANDLE(HFONT);
|
||||
DECLARE_WIREM_HANDLE(HICON);
|
||||
DECLARE_WIREM_HANDLE(HMENU);
|
||||
DECLARE_WIREM_HANDLE(HWND);
|
||||
DECLARE_WIREM_HANDLE(HMONITOR);
|
||||
|
||||
typedef HICON HCURSOR;
|
||||
|
||||
@@ -639,13 +646,8 @@ cpp_quote("#ifndef _tagCY_DEFINED")
|
||||
cpp_quote("#define _tagCY_DEFINED")
|
||||
cpp_quote("typedef union tagCY {")
|
||||
cpp_quote(" struct {")
|
||||
cpp_quote("#ifdef WORDS_BIGENDIAN")
|
||||
cpp_quote(" LONG Hi;")
|
||||
cpp_quote(" ULONG Lo;")
|
||||
cpp_quote("#else")
|
||||
cpp_quote(" ULONG Lo;")
|
||||
cpp_quote(" LONG Hi;")
|
||||
cpp_quote("#endif")
|
||||
cpp_quote(" } DUMMYSTRUCTNAME;")
|
||||
cpp_quote(" LONGLONG int64;")
|
||||
cpp_quote("} CY;")
|
||||
@@ -675,13 +677,8 @@ cpp_quote(" } DUMMYUNIONNAME;")
|
||||
cpp_quote(" ULONG Hi32;")
|
||||
cpp_quote(" union {")
|
||||
cpp_quote(" struct {")
|
||||
cpp_quote("#ifdef WORDS_BIGENDIAN")
|
||||
cpp_quote(" ULONG Mid32;")
|
||||
cpp_quote(" ULONG Lo32;")
|
||||
cpp_quote("#else")
|
||||
cpp_quote(" ULONG Lo32;")
|
||||
cpp_quote(" ULONG Mid32;")
|
||||
cpp_quote("#endif")
|
||||
cpp_quote(" } DUMMYSTRUCTNAME1;")
|
||||
cpp_quote(" ULONGLONG Lo64;")
|
||||
cpp_quote(" } DUMMYUNIONNAME1;")
|
||||
@@ -847,7 +844,3 @@ typedef struct _tagpropertykey
|
||||
cpp_quote("#endif /*PROPERTYKEY_DEFINED*/")
|
||||
|
||||
} /* interface IWinTypes */
|
||||
|
||||
cpp_quote("#ifdef _MSC_VER")
|
||||
cpp_quote("#pragma warning(pop)")
|
||||
cpp_quote("#endif")
|
||||
|
||||
@@ -87,6 +87,7 @@ list(APPEND IDL_SOURCES
|
||||
# netprov.idl
|
||||
oaidl.idl
|
||||
objidl.idl
|
||||
objidlbase.idl
|
||||
objsafe.idl
|
||||
ocidl.idl
|
||||
ocmm.idl
|
||||
|
||||
@@ -0,0 +1,969 @@
|
||||
/*
|
||||
* Helper functions for the Wine tools
|
||||
*
|
||||
* Copyright 2021 Alexandre Julliard
|
||||
*
|
||||
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_TOOLS_H
|
||||
#define __WINE_TOOLS_H
|
||||
|
||||
#ifndef __WINE_CONFIG_H
|
||||
# error You must include config.h to use this header
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#ifdef HAVE_SYS_SYSCTL_H
|
||||
# include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <direct.h>
|
||||
# include <io.h>
|
||||
# include <process.h>
|
||||
# define mkdir(path,mode) mkdir(path)
|
||||
# ifndef S_ISREG
|
||||
# define S_ISREG(mod) (((mod) & _S_IFMT) == _S_IFREG)
|
||||
# endif
|
||||
# ifdef _MSC_VER
|
||||
# define popen _popen
|
||||
# define pclose _pclose
|
||||
# define strtoll _strtoi64
|
||||
# define strtoull _strtoui64
|
||||
# define strncasecmp _strnicmp
|
||||
# define strcasecmp _stricmp
|
||||
# endif
|
||||
#ifdef __REACTOS__
|
||||
#define MAX_PATH 260
|
||||
#define ARRAYSIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
#else
|
||||
# include <windef.h>
|
||||
# include <winbase.h>
|
||||
#endif
|
||||
#else
|
||||
extern char **environ;
|
||||
# include <spawn.h>
|
||||
# include <sys/wait.h>
|
||||
# include <unistd.h>
|
||||
# ifndef O_BINARY
|
||||
# define O_BINARY 0
|
||||
# endif
|
||||
# ifndef __int64
|
||||
# if defined(__x86_64__) || defined(__aarch64__) || defined(__powerpc64__)
|
||||
# define __int64 long
|
||||
# else
|
||||
# define __int64 long long
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined(__GNUC__) && !defined(__attribute__)
|
||||
#define __attribute__(x)
|
||||
#endif
|
||||
|
||||
#ifndef max
|
||||
#define max(a,b) (((a) > (b)) ? (a) : (b))
|
||||
#endif
|
||||
#ifndef min
|
||||
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
#endif
|
||||
|
||||
struct target
|
||||
{
|
||||
enum { CPU_i386, CPU_x86_64, CPU_ARM, CPU_ARM64, CPU_ARM64EC } cpu;
|
||||
|
||||
enum
|
||||
{
|
||||
PLATFORM_UNSPECIFIED,
|
||||
PLATFORM_APPLE,
|
||||
PLATFORM_ANDROID,
|
||||
PLATFORM_LINUX,
|
||||
PLATFORM_FREEBSD,
|
||||
PLATFORM_SOLARIS,
|
||||
PLATFORM_WINDOWS,
|
||||
PLATFORM_MINGW,
|
||||
PLATFORM_CYGWIN
|
||||
} platform;
|
||||
};
|
||||
|
||||
static inline void *xmalloc( size_t size )
|
||||
{
|
||||
void *res = malloc( size ? size : 1 );
|
||||
|
||||
if (res == NULL)
|
||||
{
|
||||
fprintf( stderr, "Virtual memory exhausted.\n" );
|
||||
exit(1);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline void *xrealloc (void *ptr, size_t size)
|
||||
{
|
||||
void *res = realloc( ptr, size );
|
||||
|
||||
if (size && res == NULL)
|
||||
{
|
||||
fprintf( stderr, "Virtual memory exhausted.\n" );
|
||||
exit(1);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline char *xstrdup( const char *str )
|
||||
{
|
||||
return strcpy( xmalloc( strlen(str)+1 ), str );
|
||||
}
|
||||
|
||||
static inline int strendswith( const char *str, const char *end )
|
||||
{
|
||||
int l = strlen( str );
|
||||
int m = strlen( end );
|
||||
return l >= m && !strcmp( str + l - m, end );
|
||||
}
|
||||
|
||||
static char *strmake( const char* fmt, ... ) __attribute__ ((__format__ (__printf__, 1, 2)));
|
||||
static inline char *strmake( const char* fmt, ... )
|
||||
{
|
||||
int n;
|
||||
size_t size = 100;
|
||||
va_list ap;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
char *p = xmalloc( size );
|
||||
va_start( ap, fmt );
|
||||
n = vsnprintf( p, size, fmt, ap );
|
||||
va_end( ap );
|
||||
if (n == -1) size *= 2;
|
||||
else if ((size_t)n >= size) size = n + 1;
|
||||
else return p;
|
||||
free( p );
|
||||
}
|
||||
}
|
||||
|
||||
/* string array functions */
|
||||
|
||||
struct strarray
|
||||
{
|
||||
unsigned int count; /* strings in use */
|
||||
unsigned int size; /* total allocated size */
|
||||
const char **str;
|
||||
};
|
||||
|
||||
static const struct strarray empty_strarray;
|
||||
|
||||
static inline void strarray_add( struct strarray *array, const char *str )
|
||||
{
|
||||
if (array->count == array->size)
|
||||
{
|
||||
if (array->size) array->size *= 2;
|
||||
else array->size = 16;
|
||||
array->str = xrealloc( array->str, sizeof(array->str[0]) * array->size );
|
||||
}
|
||||
array->str[array->count++] = str;
|
||||
}
|
||||
|
||||
static inline void strarray_addall( struct strarray *array, struct strarray added )
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < added.count; i++) strarray_add( array, added.str[i] );
|
||||
}
|
||||
|
||||
static inline int strarray_exists( const struct strarray *array, const char *str )
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < array->count; i++) if (!strcmp( array->str[i], str )) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void strarray_add_uniq( struct strarray *array, const char *str )
|
||||
{
|
||||
if (!strarray_exists( array, str )) strarray_add( array, str );
|
||||
}
|
||||
|
||||
static inline void strarray_addall_uniq( struct strarray *array, struct strarray added )
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < added.count; i++) strarray_add_uniq( array, added.str[i] );
|
||||
}
|
||||
|
||||
static inline struct strarray strarray_fromstring( const char *str, const char *delim )
|
||||
{
|
||||
struct strarray array = empty_strarray;
|
||||
char *buf = xstrdup( str );
|
||||
const char *tok;
|
||||
|
||||
for (tok = strtok( buf, delim ); tok; tok = strtok( NULL, delim ))
|
||||
strarray_add( &array, xstrdup( tok ));
|
||||
free( buf );
|
||||
return array;
|
||||
}
|
||||
|
||||
static inline struct strarray strarray_frompath( const char *path )
|
||||
{
|
||||
if (!path) return empty_strarray;
|
||||
#ifdef _WIN32
|
||||
return strarray_fromstring( path, ";" );
|
||||
#else
|
||||
return strarray_fromstring( path, ":" );
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline char *strarray_tostring( struct strarray array, const char *sep )
|
||||
{
|
||||
char *str;
|
||||
unsigned int i, len = 1 + (array.count - 1) * strlen(sep);
|
||||
|
||||
if (!array.count) return xstrdup("");
|
||||
for (i = 0; i < array.count; i++) len += strlen( array.str[i] );
|
||||
str = xmalloc( len );
|
||||
strcpy( str, array.str[0] );
|
||||
for (i = 1; i < array.count; i++)
|
||||
{
|
||||
strcat( str, sep );
|
||||
strcat( str, array.str[i] );
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
static inline void strarray_qsort( struct strarray *array, int (*func)(const char **, const char **) )
|
||||
{
|
||||
if (array->count) qsort( array->str, array->count, sizeof(*array->str), (void *)func );
|
||||
}
|
||||
|
||||
static inline const char *strarray_bsearch( const struct strarray *array, const char *str,
|
||||
int (*func)(const char **, const char **) )
|
||||
{
|
||||
char **res = NULL;
|
||||
|
||||
if (array->count) res = bsearch( &str, array->str, array->count, sizeof(*array->str), (void *)func );
|
||||
return res ? *res : NULL;
|
||||
}
|
||||
|
||||
static inline void strarray_trace( struct strarray args )
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < args.count; i++)
|
||||
{
|
||||
if (strpbrk( args.str[i], " \t\n\r")) printf( "\"%s\"", args.str[i] );
|
||||
else printf( "%s", args.str[i] );
|
||||
putchar( i < args.count - 1 ? ' ' : '\n' );
|
||||
}
|
||||
}
|
||||
|
||||
static inline int strarray_spawn( struct strarray args )
|
||||
{
|
||||
#ifdef _WIN32
|
||||
strarray_add( &args, NULL );
|
||||
return _spawnvp( _P_WAIT, args.str[0], args.str );
|
||||
#else
|
||||
pid_t pid, wret;
|
||||
int status;
|
||||
|
||||
strarray_add( &args, NULL );
|
||||
if (posix_spawnp( &pid, args.str[0], NULL, NULL, (char **)args.str, environ ))
|
||||
return -1;
|
||||
|
||||
while (pid != (wret = waitpid( pid, &status, 0 )))
|
||||
if (wret == -1 && errno != EINTR) break;
|
||||
|
||||
if (pid == wret && WIFEXITED(status)) return WEXITSTATUS(status);
|
||||
return 255; /* abnormal exit with an abort or an interrupt */
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline char *get_basename( const char *file )
|
||||
{
|
||||
const char *ret = strrchr( file, '/' );
|
||||
return xstrdup( ret ? ret + 1 : file );
|
||||
}
|
||||
|
||||
static inline char *get_basename_noext( const char *file )
|
||||
{
|
||||
char *ext, *ret = get_basename( file );
|
||||
if ((ext = strrchr( ret, '.' ))) *ext = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline char *get_dirname( const char *file )
|
||||
{
|
||||
const char *end = strrchr( file, '/' );
|
||||
if (!end) return xstrdup( "." );
|
||||
if (end == file) end++;
|
||||
return strmake( "%.*s", (int)(end - file), file );
|
||||
}
|
||||
|
||||
static inline char *replace_extension( const char *name, const char *old_ext, const char *new_ext )
|
||||
{
|
||||
int name_len = strlen( name );
|
||||
|
||||
if (strendswith( name, old_ext )) name_len -= strlen( old_ext );
|
||||
return strmake( "%.*s%s", name_len, name, new_ext );
|
||||
}
|
||||
|
||||
/* build a path with the relative dir from 'from' to 'dest' appended to base */
|
||||
static inline char *build_relative_path( const char *base, const char *from, const char *dest )
|
||||
{
|
||||
const char *start;
|
||||
char *ret;
|
||||
unsigned int dotdots = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
while (*from == '/') from++;
|
||||
while (*dest == '/') dest++;
|
||||
start = dest; /* save start of next path element */
|
||||
if (!*from) break;
|
||||
|
||||
while (*from && *from != '/' && *from == *dest) { from++; dest++; }
|
||||
if ((!*from || *from == '/') && (!*dest || *dest == '/')) continue;
|
||||
|
||||
do /* count remaining elements in 'from' */
|
||||
{
|
||||
dotdots++;
|
||||
while (*from && *from != '/') from++;
|
||||
while (*from == '/') from++;
|
||||
}
|
||||
while (*from);
|
||||
break;
|
||||
}
|
||||
|
||||
ret = xmalloc( strlen(base) + 3 * dotdots + strlen(start) + 2 );
|
||||
strcpy( ret, base );
|
||||
while (dotdots--) strcat( ret, "/.." );
|
||||
|
||||
if (!start[0]) return ret;
|
||||
strcat( ret, "/" );
|
||||
strcat( ret, start );
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* temp files management */
|
||||
|
||||
extern const char *temp_dir;
|
||||
extern struct strarray temp_files;
|
||||
|
||||
static inline char *make_temp_dir(void)
|
||||
{
|
||||
unsigned int value = time(NULL) + getpid();
|
||||
int count;
|
||||
char *name;
|
||||
const char *tmpdir = NULL;
|
||||
|
||||
#ifdef __REACTOS__
|
||||
#ifdef _WIN32
|
||||
if (!(tmpdir = getenv("TEMP"))) tmpdir = "temp";
|
||||
#else
|
||||
if (!(tmpdir = getenv("TMPDIR"))) tmpdir = "/tmp";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
for (count = 0; count < 0x8000; count++)
|
||||
{
|
||||
if (tmpdir)
|
||||
name = strmake( "%s/tmp%08x", tmpdir, value );
|
||||
else
|
||||
name = strmake( "tmp%08x", value );
|
||||
if (!mkdir( name, 0700 )) return name;
|
||||
value += 7777;
|
||||
if (errno == EACCES && !tmpdir)
|
||||
{
|
||||
if (!(tmpdir = getenv("TMPDIR"))) tmpdir = "/tmp";
|
||||
}
|
||||
free( name );
|
||||
}
|
||||
fprintf( stderr, "failed to create directory for temp files\n" );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static inline char *make_temp_file( const char *prefix, const char *suffix )
|
||||
{
|
||||
static unsigned int value;
|
||||
int fd, count;
|
||||
char *name;
|
||||
|
||||
if (!temp_dir) temp_dir = make_temp_dir();
|
||||
if (!suffix) suffix = "";
|
||||
if (!prefix) prefix = "tmp";
|
||||
else prefix = get_basename_noext( prefix );
|
||||
|
||||
for (count = 0; count < 0x8000; count++)
|
||||
{
|
||||
name = strmake( "%s/%s-%08x%s", temp_dir, prefix, value++, suffix );
|
||||
fd = open( name, O_RDWR | O_CREAT | O_EXCL, 0600 );
|
||||
if (fd >= 0)
|
||||
{
|
||||
#ifdef HAVE_SIGPROCMASK /* block signals while manipulating the temp files list */
|
||||
sigset_t mask_set, old_set;
|
||||
|
||||
sigemptyset( &mask_set );
|
||||
sigaddset( &mask_set, SIGHUP );
|
||||
sigaddset( &mask_set, SIGTERM );
|
||||
sigaddset( &mask_set, SIGINT );
|
||||
sigprocmask( SIG_BLOCK, &mask_set, &old_set );
|
||||
strarray_add( &temp_files, name );
|
||||
sigprocmask( SIG_SETMASK, &old_set, NULL );
|
||||
#else
|
||||
strarray_add( &temp_files, name );
|
||||
#endif
|
||||
close( fd );
|
||||
return name;
|
||||
}
|
||||
free( name );
|
||||
}
|
||||
fprintf( stderr, "failed to create temp file for %s%s in %s\n", prefix, suffix, temp_dir );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static inline void remove_temp_files(void)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < temp_files.count; i++) if (temp_files.str[i]) unlink( temp_files.str[i] );
|
||||
if (temp_dir) rmdir( temp_dir );
|
||||
}
|
||||
|
||||
|
||||
static inline void init_signals( void (*cleanup)(int) )
|
||||
{
|
||||
signal( SIGTERM, cleanup );
|
||||
signal( SIGINT, cleanup );
|
||||
#ifdef SIGHUP
|
||||
signal( SIGHUP, cleanup );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static inline void *read_file( const char *name, size_t *size )
|
||||
{
|
||||
struct stat st;
|
||||
int res, fd;
|
||||
void *data;
|
||||
|
||||
if ((fd = open( name, O_RDONLY | O_BINARY )) == -1) return NULL;
|
||||
fstat( fd, &st );
|
||||
data = xmalloc( st.st_size );
|
||||
res = read( fd, data, st.st_size );
|
||||
if (res == -1)
|
||||
{
|
||||
free( data );
|
||||
data = NULL;
|
||||
*size = 0;
|
||||
}
|
||||
else *size = res;
|
||||
close( fd );
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
static inline struct target get_default_target(void)
|
||||
{
|
||||
struct target target;
|
||||
#ifdef __i386__
|
||||
target.cpu = CPU_i386;
|
||||
#elif defined(__x86_64__)
|
||||
target.cpu = CPU_x86_64;
|
||||
#elif defined(__arm__)
|
||||
target.cpu = CPU_ARM;
|
||||
#elif defined(__aarch64__)
|
||||
target.cpu = CPU_ARM64;
|
||||
#else
|
||||
#error Unsupported CPU
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
target.platform = PLATFORM_APPLE;
|
||||
#elif defined(__ANDROID__)
|
||||
target.platform = PLATFORM_ANDROID;
|
||||
#elif defined(__linux__)
|
||||
target.platform = PLATFORM_LINUX;
|
||||
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
target.platform = PLATFORM_FREEBSD;
|
||||
#elif defined(__sun)
|
||||
target.platform = PLATFORM_SOLARIS;
|
||||
#elif defined(__CYGWIN__)
|
||||
target.platform = PLATFORM_CYGWIN;
|
||||
#elif defined(_WIN32)
|
||||
target.platform = PLATFORM_MINGW;
|
||||
#else
|
||||
target.platform = PLATFORM_UNSPECIFIED;
|
||||
#endif
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
|
||||
static inline unsigned int get_target_ptr_size( struct target target )
|
||||
{
|
||||
static const unsigned int sizes[] =
|
||||
{
|
||||
[CPU_i386] = 4,
|
||||
[CPU_x86_64] = 8,
|
||||
[CPU_ARM] = 4,
|
||||
[CPU_ARM64] = 8,
|
||||
[CPU_ARM64EC] = 8,
|
||||
};
|
||||
return sizes[target.cpu];
|
||||
}
|
||||
|
||||
|
||||
static inline void set_target_ptr_size( struct target *target, unsigned int size )
|
||||
{
|
||||
switch (target->cpu)
|
||||
{
|
||||
case CPU_i386:
|
||||
if (size == 8) target->cpu = CPU_x86_64;
|
||||
break;
|
||||
case CPU_x86_64:
|
||||
if (size == 4) target->cpu = CPU_i386;
|
||||
break;
|
||||
case CPU_ARM:
|
||||
if (size == 8) target->cpu = CPU_ARM64;
|
||||
break;
|
||||
case CPU_ARM64:
|
||||
case CPU_ARM64EC:
|
||||
if (size == 4) target->cpu = CPU_ARM;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static inline int get_cpu_from_name( const char *name )
|
||||
{
|
||||
static const struct
|
||||
{
|
||||
const char *name;
|
||||
int cpu;
|
||||
} cpu_names[] =
|
||||
{
|
||||
{ "i386", CPU_i386 },
|
||||
{ "i486", CPU_i386 },
|
||||
{ "i586", CPU_i386 },
|
||||
{ "i686", CPU_i386 },
|
||||
{ "i786", CPU_i386 },
|
||||
{ "x86_64", CPU_x86_64 },
|
||||
{ "amd64", CPU_x86_64 },
|
||||
{ "aarch64", CPU_ARM64 },
|
||||
{ "arm64ec", CPU_ARM64EC },
|
||||
{ "arm64", CPU_ARM64 },
|
||||
{ "arm", CPU_ARM },
|
||||
};
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cpu_names); i++)
|
||||
if (!strncmp( cpu_names[i].name, name, strlen(cpu_names[i].name) )) return cpu_names[i].cpu;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static inline int get_platform_from_name( const char *name )
|
||||
{
|
||||
static const struct
|
||||
{
|
||||
const char *name;
|
||||
int platform;
|
||||
} platform_names[] =
|
||||
{
|
||||
{ "macos", PLATFORM_APPLE },
|
||||
{ "darwin", PLATFORM_APPLE },
|
||||
{ "android", PLATFORM_ANDROID },
|
||||
{ "linux", PLATFORM_LINUX },
|
||||
{ "freebsd", PLATFORM_FREEBSD },
|
||||
{ "solaris", PLATFORM_SOLARIS },
|
||||
{ "mingw32", PLATFORM_MINGW },
|
||||
{ "windows-gnu", PLATFORM_MINGW },
|
||||
{ "winnt", PLATFORM_MINGW },
|
||||
{ "windows", PLATFORM_WINDOWS },
|
||||
{ "cygwin", PLATFORM_CYGWIN },
|
||||
};
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(platform_names); i++)
|
||||
if (!strncmp( platform_names[i].name, name, strlen(platform_names[i].name) ))
|
||||
return platform_names[i].platform;
|
||||
return -1;
|
||||
};
|
||||
|
||||
|
||||
static inline const char *get_arch_dir( struct target target )
|
||||
{
|
||||
static const char *cpu_names[] =
|
||||
{
|
||||
[CPU_i386] = "i386",
|
||||
[CPU_x86_64] = "x86_64",
|
||||
[CPU_ARM] = "arm",
|
||||
[CPU_ARM64] = "aarch64",
|
||||
[CPU_ARM64EC] = "aarch64",
|
||||
};
|
||||
|
||||
if (!cpu_names[target.cpu]) return "";
|
||||
|
||||
switch (target.platform)
|
||||
{
|
||||
case PLATFORM_WINDOWS:
|
||||
case PLATFORM_CYGWIN:
|
||||
case PLATFORM_MINGW:
|
||||
return strmake( "/%s-windows", cpu_names[target.cpu] );
|
||||
default:
|
||||
return strmake( "/%s-unix", cpu_names[target.cpu] );
|
||||
}
|
||||
}
|
||||
|
||||
static inline int parse_target( const char *name, struct target *target )
|
||||
{
|
||||
int res;
|
||||
char *p, *spec = xstrdup( name );
|
||||
|
||||
/* target specification is in the form CPU-MANUFACTURER-OS or CPU-MANUFACTURER-KERNEL-OS */
|
||||
|
||||
/* get the CPU part */
|
||||
|
||||
if ((p = strchr( spec, '-' )))
|
||||
{
|
||||
*p++ = 0;
|
||||
if ((res = get_cpu_from_name( spec )) == -1)
|
||||
{
|
||||
free( spec );
|
||||
return 0;
|
||||
}
|
||||
target->cpu = res;
|
||||
}
|
||||
else if (!strcmp( spec, "mingw32" ))
|
||||
{
|
||||
target->cpu = CPU_i386;
|
||||
p = spec;
|
||||
}
|
||||
else
|
||||
{
|
||||
free( spec );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* get the OS part */
|
||||
|
||||
target->platform = PLATFORM_UNSPECIFIED; /* default value */
|
||||
for (;;)
|
||||
{
|
||||
if ((res = get_platform_from_name( p )) != -1)
|
||||
{
|
||||
target->platform = res;
|
||||
break;
|
||||
}
|
||||
if (!(p = strchr( p, '-' ))) break;
|
||||
p++;
|
||||
}
|
||||
|
||||
free( spec );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static inline struct target init_argv0_target( const char *argv0 )
|
||||
{
|
||||
char *name = get_basename( argv0 );
|
||||
struct target target;
|
||||
|
||||
if (!strchr( name, '-' ) || !parse_target( name, &target ))
|
||||
target = get_default_target();
|
||||
|
||||
free( name );
|
||||
return target;
|
||||
}
|
||||
|
||||
|
||||
static inline char *get_bindir( const char *argv0 )
|
||||
{
|
||||
#ifdef __REACTOS__
|
||||
return NULL;
|
||||
#else
|
||||
#ifndef _WIN32
|
||||
char *dir = NULL;
|
||||
|
||||
#if defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) \
|
||||
|| defined(__CYGWIN__) || defined(__MSYS__)
|
||||
dir = realpath( "/proc/self/exe", NULL );
|
||||
#elif defined (__FreeBSD__) || defined(__DragonFly__)
|
||||
static int pathname[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
|
||||
size_t path_size = PATH_MAX;
|
||||
char *path = xmalloc( path_size );
|
||||
if (!sysctl( pathname, ARRAY_SIZE(pathname), path, &path_size, NULL, 0 ))
|
||||
dir = realpath( path, NULL );
|
||||
free( path );
|
||||
#endif
|
||||
if (!dir && !(dir = realpath( argv0, NULL ))) return NULL;
|
||||
return get_dirname( dir );
|
||||
#else
|
||||
char path[MAX_PATH], *p;
|
||||
GetModuleFileNameA( NULL, path, ARRAYSIZE(path) );
|
||||
for (p = path; *p; p++) if (*p == '\\') *p = '/';
|
||||
return get_dirname( path );
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef LIBDIR
|
||||
static inline const char *get_libdir( const char *bindir )
|
||||
{
|
||||
#ifdef BINDIR
|
||||
if (bindir) return build_relative_path( bindir, BINDIR, LIBDIR );
|
||||
#endif
|
||||
return LIBDIR;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DATADIR
|
||||
static inline const char *get_datadir( const char *bindir )
|
||||
{
|
||||
#ifdef BINDIR
|
||||
if (bindir) return build_relative_path( bindir, BINDIR, DATADIR );
|
||||
#endif
|
||||
return DATADIR;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDEDIR
|
||||
static inline const char *get_includedir( const char *bindir )
|
||||
{
|
||||
#ifdef BINDIR
|
||||
if (bindir) return build_relative_path( bindir, BINDIR, INCLUDEDIR );
|
||||
#endif
|
||||
return INCLUDEDIR;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline const char *get_nlsdir( const char *bindir, const char *srcdir )
|
||||
{
|
||||
if (bindir && strendswith( bindir, srcdir )) return strmake( "%s/../../nls", bindir );
|
||||
#ifdef DATADIR
|
||||
else
|
||||
{
|
||||
const char *datadir = get_datadir( bindir );
|
||||
if (datadir) return strmake( "%s/wine/nls", datadir );
|
||||
}
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* output buffer management */
|
||||
|
||||
extern unsigned char *output_buffer;
|
||||
extern size_t output_buffer_pos;
|
||||
extern size_t output_buffer_size;
|
||||
|
||||
static inline void check_output_buffer_space( size_t size )
|
||||
{
|
||||
if (output_buffer_pos + size >= output_buffer_size)
|
||||
{
|
||||
output_buffer_size = max( output_buffer_size * 2, output_buffer_pos + size );
|
||||
output_buffer = xrealloc( output_buffer, output_buffer_size );
|
||||
}
|
||||
}
|
||||
|
||||
static inline void init_output_buffer(void)
|
||||
{
|
||||
output_buffer_size = 1024;
|
||||
output_buffer_pos = 0;
|
||||
output_buffer = xmalloc( output_buffer_size );
|
||||
}
|
||||
|
||||
static inline void put_data( const void *data, size_t size )
|
||||
{
|
||||
check_output_buffer_space( size );
|
||||
memcpy( output_buffer + output_buffer_pos, data, size );
|
||||
output_buffer_pos += size;
|
||||
}
|
||||
|
||||
static inline void put_byte( unsigned char val )
|
||||
{
|
||||
check_output_buffer_space( 1 );
|
||||
output_buffer[output_buffer_pos++] = val;
|
||||
}
|
||||
|
||||
static inline void put_word( unsigned short val )
|
||||
{
|
||||
check_output_buffer_space( 2 );
|
||||
output_buffer[output_buffer_pos++] = val;
|
||||
output_buffer[output_buffer_pos++] = val >> 8;
|
||||
}
|
||||
|
||||
static inline void put_dword( unsigned int val )
|
||||
{
|
||||
check_output_buffer_space( 4 );
|
||||
output_buffer[output_buffer_pos++] = val;
|
||||
output_buffer[output_buffer_pos++] = val >> 8;
|
||||
output_buffer[output_buffer_pos++] = val >> 16;
|
||||
output_buffer[output_buffer_pos++] = val >> 24;
|
||||
}
|
||||
|
||||
static inline void put_qword( unsigned int val )
|
||||
{
|
||||
put_dword( val );
|
||||
put_dword( 0 );
|
||||
}
|
||||
|
||||
static inline void align_output( unsigned int align )
|
||||
{
|
||||
size_t size = align - (output_buffer_pos % align);
|
||||
|
||||
if (size == align) return;
|
||||
check_output_buffer_space( size );
|
||||
memset( output_buffer + output_buffer_pos, 0, size );
|
||||
output_buffer_pos += size;
|
||||
}
|
||||
|
||||
static inline void flush_output_buffer( const char *name )
|
||||
{
|
||||
int fd = open( name, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666 );
|
||||
|
||||
if (fd == -1 || write( fd, output_buffer, output_buffer_pos ) != output_buffer_pos)
|
||||
{
|
||||
perror( name );
|
||||
exit(1);
|
||||
}
|
||||
close( fd );
|
||||
free( output_buffer );
|
||||
}
|
||||
|
||||
/* command-line option parsing */
|
||||
/* partly based on the Glibc getopt() implementation */
|
||||
|
||||
struct long_option
|
||||
{
|
||||
const char *name;
|
||||
int has_arg;
|
||||
int val;
|
||||
};
|
||||
|
||||
static inline struct strarray parse_options( int argc, char **argv, const char *short_opts,
|
||||
const struct long_option *long_opts, int long_only,
|
||||
void (*callback)( int, char* ) )
|
||||
{
|
||||
struct strarray ret = empty_strarray;
|
||||
const char *flag;
|
||||
char *start, *end;
|
||||
int i;
|
||||
|
||||
#define OPT_ERR(fmt) { callback( '?', strmake( fmt, argv[i] )); continue; }
|
||||
|
||||
for (i = 1; i < argc; i++)
|
||||
{
|
||||
if (argv[i][0] != '-' || !argv[i][1]) /* not an option */
|
||||
{
|
||||
strarray_add( &ret, argv[i] );
|
||||
continue;
|
||||
}
|
||||
if (!strcmp( argv[i], "--" ))
|
||||
{
|
||||
/* add remaining args */
|
||||
while (++i < argc) strarray_add( &ret, argv[i] );
|
||||
break;
|
||||
}
|
||||
start = argv[i] + 1 + (argv[i][1] == '-');
|
||||
|
||||
if (argv[i][1] == '-' || (long_only && (argv[i][2] || !strchr( short_opts, argv[i][1] ))))
|
||||
{
|
||||
/* handle long option */
|
||||
const struct long_option *opt, *found = NULL;
|
||||
int count = 0;
|
||||
|
||||
if (!(end = strchr( start, '=' ))) end = start + strlen(start);
|
||||
for (opt = long_opts; opt && opt->name; opt++)
|
||||
{
|
||||
if (strncmp( opt->name, start, end - start )) continue;
|
||||
if (!opt->name[end - start]) /* exact match */
|
||||
{
|
||||
found = opt;
|
||||
count = 1;
|
||||
break;
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
found = opt;
|
||||
count++;
|
||||
}
|
||||
else if (long_only || found->has_arg != opt->has_arg || found->val != opt->val)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (count > 1) OPT_ERR( "option '%s' is ambiguous" );
|
||||
|
||||
if (found)
|
||||
{
|
||||
if (*end)
|
||||
{
|
||||
if (!found->has_arg) OPT_ERR( "argument not allowed in '%s'" );
|
||||
end++; /* skip '=' */
|
||||
}
|
||||
else if (found->has_arg == 1)
|
||||
{
|
||||
if (i == argc - 1) OPT_ERR( "option '%s' requires an argument" );
|
||||
end = argv[++i];
|
||||
}
|
||||
else end = NULL;
|
||||
|
||||
callback( found->val, end );
|
||||
continue;
|
||||
}
|
||||
if (argv[i][1] == '-' || !long_only || !strchr( short_opts, argv[i][1] ))
|
||||
OPT_ERR( "unrecognized option '%s'" );
|
||||
}
|
||||
|
||||
/* handle short option */
|
||||
for ( ; *start; start++)
|
||||
{
|
||||
if (!(flag = strchr( short_opts, *start ))) OPT_ERR( "invalid option '%s'" );
|
||||
if (flag[1] == ':')
|
||||
{
|
||||
end = start + 1;
|
||||
if (!*end) end = NULL;
|
||||
if (flag[2] != ':' && !end)
|
||||
{
|
||||
if (i == argc - 1) OPT_ERR( "option '%s' requires an argument" );
|
||||
end = argv[++i];
|
||||
}
|
||||
callback( *start, end );
|
||||
break;
|
||||
}
|
||||
callback( *start, NULL );
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
#undef OPT_ERR
|
||||
}
|
||||
|
||||
#endif /* __WINE_TOOLS_H */
|
||||
@@ -11,10 +11,11 @@ if(MSVC)
|
||||
endif()
|
||||
|
||||
FLEX_TARGET(p_scanner parser.l ${CMAKE_CURRENT_BINARY_DIR}/parser.yy.c)
|
||||
BISON_TARGET(p_parser parser.y ${CMAKE_CURRENT_BINARY_DIR}/parser.tab.c COMPILE_FLAGS "-p parser_")
|
||||
BISON_TARGET(p_parser parser.y ${CMAKE_CURRENT_BINARY_DIR}/parser.tab.c)
|
||||
ADD_FLEX_BISON_DEPENDENCY(p_scanner p_parser)
|
||||
|
||||
list(APPEND SOURCE
|
||||
attribute.c
|
||||
client.c
|
||||
expr.c
|
||||
hash.c
|
||||
@@ -35,7 +36,8 @@ list(APPEND SOURCE
|
||||
../port/getopt1.c
|
||||
../port/mkstemps.c)
|
||||
|
||||
add_definitions(-DINT16=SHORT -DLANG_SCOTTISH_GAELIC=0x91)
|
||||
add_definitions(-DINT16=SHORT -DLANG_SCOTTISH_GAELIC=0x91 -DINCLUDEDIR="unused" -DLIBDIR="unused")
|
||||
include_directories(${REACTOS_SOURCE_DIR}/sdk/tools/wpp/)
|
||||
add_host_tool(widl ${SOURCE})
|
||||
target_link_libraries(widl PRIVATE host_includes wpphost)
|
||||
|
||||
@@ -49,5 +51,8 @@ if(MSVC)
|
||||
# Disable warning "'=': conversion from 'a' to 'b', possible loss of data"
|
||||
target_compile_options(widl PRIVATE "/wd4244")
|
||||
|
||||
# Disable warning "warning C4090: 'function': different 'const' qualifiers"
|
||||
target_compile_options(widl PRIVATE "/wd4090")
|
||||
|
||||
target_compile_options(widl PRIVATE "-WX")
|
||||
endif()
|
||||
|
||||
@@ -0,0 +1,540 @@
|
||||
/*
|
||||
* Copyright 2002 Ove Kaaven
|
||||
* Copyright 2006-2008 Robert Shearman
|
||||
*
|
||||
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "widl.h"
|
||||
#include "typetree.h"
|
||||
|
||||
#include "parser.tab.h"
|
||||
|
||||
attr_t *attr_int( struct location where, enum attr_type attr_type, unsigned int val )
|
||||
{
|
||||
attr_t *a = xmalloc( sizeof(attr_t) );
|
||||
a->where = where;
|
||||
a->type = attr_type;
|
||||
a->u.ival = val;
|
||||
return a;
|
||||
}
|
||||
|
||||
attr_t *attr_ptr( struct location where, enum attr_type attr_type, void *val )
|
||||
{
|
||||
attr_t *a = xmalloc( sizeof(attr_t) );
|
||||
a->where = where;
|
||||
a->type = attr_type;
|
||||
a->u.pval = val;
|
||||
return a;
|
||||
}
|
||||
|
||||
int is_attr( const attr_list_t *list, enum attr_type attr_type )
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!list) return 0;
|
||||
LIST_FOR_EACH_ENTRY( attr, list, const attr_t, entry )
|
||||
if (attr->type == attr_type) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int is_ptrchain_attr( const var_t *var, enum attr_type attr_type )
|
||||
{
|
||||
type_t *type = var->declspec.type;
|
||||
if (is_attr( var->attrs, attr_type )) return 1;
|
||||
for (;;)
|
||||
{
|
||||
if (is_attr( type->attrs, attr_type )) return 1;
|
||||
else if (type_is_alias( type )) type = type_alias_get_aliasee_type( type );
|
||||
else if (type_is_ptr( type )) type = type_pointer_get_ref_type( type );
|
||||
else return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int is_aliaschain_attr( const type_t *type, enum attr_type attr_type )
|
||||
{
|
||||
const type_t *t = type;
|
||||
for (;;)
|
||||
{
|
||||
if (is_attr( t->attrs, attr_type )) return 1;
|
||||
else if (type_is_alias( t )) t = type_alias_get_aliasee_type( t );
|
||||
else return 0;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int get_attrv( const attr_list_t *list, enum attr_type attr_type )
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!list) return 0;
|
||||
LIST_FOR_EACH_ENTRY( attr, list, const attr_t, entry )
|
||||
if (attr->type == attr_type) return attr->u.ival;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *get_attrp( const attr_list_t *list, enum attr_type attr_type )
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!list) return NULL;
|
||||
LIST_FOR_EACH_ENTRY( attr, list, const attr_t, entry )
|
||||
if (attr->type == attr_type) return attr->u.pval;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *get_aliaschain_attrp( const type_t *type, enum attr_type attr_type )
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if (is_attr( type->attrs, attr_type )) return get_attrp( type->attrs, attr_type );
|
||||
if (!type_is_alias( type )) return NULL;
|
||||
type = type_alias_get_aliasee_type( type );
|
||||
}
|
||||
}
|
||||
|
||||
struct allowed_attr
|
||||
{
|
||||
unsigned int dce_compatible : 1;
|
||||
unsigned int acf : 1;
|
||||
unsigned int multiple : 1;
|
||||
|
||||
unsigned int on_interface : 1;
|
||||
unsigned int on_function : 1;
|
||||
unsigned int on_arg : 1;
|
||||
unsigned int on_type : 1;
|
||||
unsigned int on_enum : 1;
|
||||
unsigned int on_enum_member : 1;
|
||||
unsigned int on_struct : 2;
|
||||
unsigned int on_union : 1;
|
||||
unsigned int on_field : 1;
|
||||
unsigned int on_library : 1;
|
||||
unsigned int on_dispinterface : 1;
|
||||
unsigned int on_module : 1;
|
||||
unsigned int on_coclass : 1;
|
||||
unsigned int on_apicontract : 1;
|
||||
unsigned int on_runtimeclass : 1;
|
||||
const char *display_name;
|
||||
};
|
||||
|
||||
struct allowed_attr allowed_attr[] =
|
||||
{
|
||||
/* attr { D ACF M I Fn ARG T En Enm St Un Fi L DI M C AC R <display name> } */
|
||||
/* ATTR_ACTIVATABLE */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "activatable" },
|
||||
/* ATTR_AGGREGATABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "aggregatable" },
|
||||
/* ATTR_ALLOCATE */ { 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "allocate" },
|
||||
/* ATTR_ANNOTATION */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "annotation" },
|
||||
/* ATTR_APPOBJECT */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "appobject" },
|
||||
/* ATTR_ASYNC */ { 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "async" },
|
||||
/* ATTR_ASYNCUUID */ { 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, "async_uuid" },
|
||||
/* ATTR_AUTO_HANDLE */ { 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "auto_handle" },
|
||||
/* ATTR_BINDABLE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "bindable" },
|
||||
/* ATTR_BROADCAST */ { 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "broadcast" },
|
||||
/* ATTR_CALLAS */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "call_as" },
|
||||
/* ATTR_CALLCONV */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL },
|
||||
/* ATTR_CASE */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "case" },
|
||||
/* ATTR_CODE */ { 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "code" },
|
||||
/* ATTR_COMMSTATUS */ { 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "comm_status" },
|
||||
/* ATTR_COMPOSABLE */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "composable" },
|
||||
/* ATTR_CONTEXTHANDLE */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "context_handle" },
|
||||
/* ATTR_CONTRACT */ { 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, "contract" },
|
||||
/* ATTR_CONTRACTVERSION */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "contractversion" },
|
||||
/* ATTR_CONTROL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, "control" },
|
||||
/* ATTR_CUSTOM */ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, "custom" },
|
||||
/* ATTR_DECODE */ { 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "decode" },
|
||||
/* ATTR_DEFAULT */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, "default" },
|
||||
/* ATTR_DEFAULT_OVERLOAD */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "default_overload" },
|
||||
/* ATTR_DEFAULTBIND */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultbind" },
|
||||
/* ATTR_DEFAULTCOLLELEM */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultcollelem" },
|
||||
/* ATTR_DEFAULTVALUE */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultvalue" },
|
||||
/* ATTR_DEFAULTVTABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "defaultvtable" },
|
||||
/* ATTR_DEPRECATED */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "deprecated" },
|
||||
/* ATTR_DISABLECONSISTENCYCHECK */{ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "disable_consistency_check" },
|
||||
/* ATTR_DISPINTERFACE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, NULL },
|
||||
/* ATTR_DISPLAYBIND */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "displaybind" },
|
||||
/* ATTR_DLLNAME */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "dllname" },
|
||||
/* ATTR_DUAL */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "dual" },
|
||||
/* ATTR_ENABLEALLOCATE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "enable_allocate" },
|
||||
/* ATTR_ENCODE */ { 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "encode" },
|
||||
/* ATTR_ENDPOINT */ { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "endpoint" },
|
||||
/* ATTR_ENTRY */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "entry" },
|
||||
/* ATTR_EVENTADD */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "eventadd" },
|
||||
/* ATTR_EVENTREMOVE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "eventremove" },
|
||||
/* ATTR_EXCLUSIVETO */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "exclusive_to" },
|
||||
/* ATTR_EXPLICIT_HANDLE */ { 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "explicit_handle" },
|
||||
/* ATTR_FAULTSTATUS */ { 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "fault_status" },
|
||||
/* ATTR_FLAGS */ { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "flags" },
|
||||
/* ATTR_FORCEALLOCATE */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "force_allocate" },
|
||||
/* ATTR_HANDLE */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "handle" },
|
||||
/* ATTR_HELPCONTEXT */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, "helpcontext" },
|
||||
/* ATTR_HELPFILE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "helpfile" },
|
||||
/* ATTR_HELPSTRING */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, "helpstring" },
|
||||
/* ATTR_HELPSTRINGCONTEXT */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, "helpstringcontext" },
|
||||
/* ATTR_HELPSTRINGDLL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "helpstringdll" },
|
||||
/* ATTR_HIDDEN */ { 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, "hidden" },
|
||||
/* ATTR_ID */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, "id" },
|
||||
/* ATTR_IDEMPOTENT */ { 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "idempotent" },
|
||||
/* ATTR_IGNORE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "ignore" },
|
||||
/* ATTR_IIDIS */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "iid_is" },
|
||||
/* ATTR_IMMEDIATEBIND */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "immediatebind" },
|
||||
/* ATTR_IMPLICIT_HANDLE */ { 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "implicit_handle" },
|
||||
/* ATTR_IN */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "in" },
|
||||
/* ATTR_INPUTSYNC */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "inputsync" },
|
||||
/* ATTR_LENGTHIS */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "length_is" },
|
||||
/* ATTR_LIBLCID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "lcid" },
|
||||
/* ATTR_LICENSED */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "licensed" },
|
||||
/* ATTR_LOCAL */ { 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "local" },
|
||||
/* ATTR_MARSHALING_BEHAVIOR */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "marshaling_behavior" },
|
||||
/* ATTR_MAYBE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "maybe" },
|
||||
/* ATTR_MESSAGE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "message" },
|
||||
/* ATTR_NOCODE */ { 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nocode" },
|
||||
/* ATTR_NONBROWSABLE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nonbrowsable" },
|
||||
/* ATTR_NONCREATABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "noncreatable" },
|
||||
/* ATTR_NONEXTENSIBLE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nonextensible" },
|
||||
/* ATTR_NOTIFY */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "notify" },
|
||||
/* ATTR_NOTIFYFLAG */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "notify_flag" },
|
||||
/* ATTR_OBJECT */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "object" },
|
||||
/* ATTR_ODL */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "odl" },
|
||||
/* ATTR_OLEAUTOMATION */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "oleautomation" },
|
||||
/* ATTR_OPTIMIZE */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "optimize" },
|
||||
/* ATTR_OPTIONAL */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "optional" },
|
||||
/* ATTR_OUT */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "out" },
|
||||
/* ATTR_OVERLOAD */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "overload" },
|
||||
/* ATTR_PARAMLCID */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "lcid" },
|
||||
/* ATTR_PARTIALIGNORE */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "partial_ignore" },
|
||||
/* ATTR_POINTERDEFAULT */ { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "pointer_default" },
|
||||
/* ATTR_POINTERTYPE */ { 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "ref, unique or ptr" },
|
||||
/* ATTR_PROGID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "progid" },
|
||||
/* ATTR_PROPGET */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propget" },
|
||||
/* ATTR_PROPPUT */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propput" },
|
||||
/* ATTR_PROPPUTREF */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propputref" },
|
||||
/* ATTR_PROTECTED */ { 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "protected" },
|
||||
/* ATTR_PROXY */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "proxy" },
|
||||
/* ATTR_PUBLIC */ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "public" },
|
||||
/* ATTR_RANGE */ { 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "range" },
|
||||
/* ATTR_READONLY */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "readonly" },
|
||||
/* ATTR_REPRESENTAS */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "represent_as" },
|
||||
/* ATTR_REQUESTEDIT */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "requestedit" },
|
||||
/* ATTR_RESTRICTED */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, "restricted" },
|
||||
/* ATTR_RETVAL */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "retval" },
|
||||
/* ATTR_SIZEIS */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "size_is" },
|
||||
/* ATTR_SOURCE */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "source" },
|
||||
/* ATTR_STATIC */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "static" },
|
||||
/* ATTR_STRICTCONTEXTHANDLE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "strict_context_handle" },
|
||||
/* ATTR_STRING */ { 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "string" },
|
||||
/* ATTR_SWITCHIS */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "switch_is" },
|
||||
/* ATTR_SWITCHTYPE */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "switch_type" },
|
||||
/* ATTR_THREADING */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, "threading" },
|
||||
/* ATTR_TRANSMITAS */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "transmit_as" },
|
||||
/* ATTR_UIDEFAULT */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "uidefault" },
|
||||
/* ATTR_USESGETLASTERROR */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "usesgetlasterror" },
|
||||
/* ATTR_USERMARSHAL */ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "user_marshal" },
|
||||
/* ATTR_UUID */ { 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, "uuid" },
|
||||
/* ATTR_V1ENUM */ { 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "v1_enum" },
|
||||
/* ATTR_VARARG */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "vararg" },
|
||||
/* ATTR_VERSION */ { 1, 0, 0, 1, 0, 0, 1, 1, 0, 2, 0, 0, 1, 0, 1, 1, 0, 1, "version" },
|
||||
/* ATTR_VIPROGID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "vi_progid" },
|
||||
/* ATTR_WIREMARSHAL */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "wire_marshal" },
|
||||
};
|
||||
|
||||
static const char *get_attr_display_name( enum attr_type attr_type )
|
||||
{
|
||||
return allowed_attr[attr_type].display_name;
|
||||
}
|
||||
|
||||
attr_list_t *append_attr( attr_list_t *list, attr_t *attr )
|
||||
{
|
||||
attr_t *attr_existing;
|
||||
if (!attr) return list;
|
||||
if (!list)
|
||||
{
|
||||
list = xmalloc( sizeof(*list) );
|
||||
list_init( list );
|
||||
}
|
||||
if (!allowed_attr[attr->type].multiple)
|
||||
{
|
||||
LIST_FOR_EACH_ENTRY( attr_existing, list, attr_t, entry )
|
||||
{
|
||||
if (attr_existing->type != attr->type) continue;
|
||||
warning_at( &attr->where, "duplicate attribute %s\n", get_attr_display_name( attr->type ) );
|
||||
/* use the last attribute, like MIDL does */
|
||||
list_remove( &attr_existing->entry );
|
||||
break;
|
||||
}
|
||||
}
|
||||
list_add_tail( list, &attr->entry );
|
||||
return list;
|
||||
}
|
||||
|
||||
attr_list_t *append_attr_list( attr_list_t *new_list, attr_list_t *old_list )
|
||||
{
|
||||
struct list *entry;
|
||||
|
||||
if (!old_list) return new_list;
|
||||
|
||||
while ((entry = list_head( old_list )))
|
||||
{
|
||||
attr_t *attr = LIST_ENTRY( entry, attr_t, entry );
|
||||
list_remove( entry );
|
||||
new_list = append_attr( new_list, attr );
|
||||
}
|
||||
return new_list;
|
||||
}
|
||||
|
||||
attr_list_t *append_attribs( attr_list_t *l1, attr_list_t *l2 )
|
||||
{
|
||||
if (!l2) return l1;
|
||||
if (!l1 || l1 == l2) return l2;
|
||||
list_move_tail( l1, l2 );
|
||||
return l1;
|
||||
}
|
||||
|
||||
attr_list_t *map_attrs( const attr_list_t *list, map_attrs_filter_t filter )
|
||||
{
|
||||
attr_list_t *new_list;
|
||||
const attr_t *attr;
|
||||
attr_t *new_attr;
|
||||
|
||||
if (!list) return NULL;
|
||||
|
||||
new_list = xmalloc( sizeof(*list) );
|
||||
list_init( new_list );
|
||||
LIST_FOR_EACH_ENTRY( attr, list, const attr_t, entry )
|
||||
{
|
||||
if (filter && !filter( new_list, attr )) continue;
|
||||
new_attr = xmalloc( sizeof(*new_attr) );
|
||||
*new_attr = *attr;
|
||||
list_add_tail( new_list, &new_attr->entry );
|
||||
}
|
||||
return new_list;
|
||||
}
|
||||
|
||||
attr_list_t *move_attr( attr_list_t *dst, attr_list_t *src, enum attr_type type )
|
||||
{
|
||||
attr_t *attr;
|
||||
if (!src) return dst;
|
||||
LIST_FOR_EACH_ENTRY( attr, src, attr_t, entry )
|
||||
{
|
||||
if (attr->type == type)
|
||||
{
|
||||
list_remove( &attr->entry );
|
||||
return append_attr( dst, attr );
|
||||
}
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
attr_list_t *check_apicontract_attrs( const char *name, attr_list_t *attrs )
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return NULL;
|
||||
LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
|
||||
{
|
||||
if (!allowed_attr[attr->type].on_apicontract)
|
||||
error_at( &attr->where, "inapplicable attribute %s for apicontract %s\n",
|
||||
allowed_attr[attr->type].display_name, name );
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
attr_list_t *check_coclass_attrs( const char *name, attr_list_t *attrs )
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return NULL;
|
||||
LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
|
||||
{
|
||||
if (!allowed_attr[attr->type].on_coclass)
|
||||
error_at( &attr->where, "inapplicable attribute %s for coclass %s\n",
|
||||
allowed_attr[attr->type].display_name, name );
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
attr_list_t *check_dispiface_attrs( const char *name, attr_list_t *attrs )
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return NULL;
|
||||
LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
|
||||
{
|
||||
if (!allowed_attr[attr->type].on_dispinterface)
|
||||
error_at( &attr->where, "inapplicable attribute %s for dispinterface %s\n",
|
||||
allowed_attr[attr->type].display_name, name );
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
attr_list_t *check_enum_attrs( attr_list_t *attrs )
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return NULL;
|
||||
LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
|
||||
{
|
||||
if (!allowed_attr[attr->type].on_enum)
|
||||
error_at( &attr->where, "inapplicable attribute %s for enum\n",
|
||||
allowed_attr[attr->type].display_name );
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
attr_list_t *check_enum_member_attrs( attr_list_t *attrs )
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return NULL;
|
||||
LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
|
||||
{
|
||||
if (!allowed_attr[attr->type].on_enum_member)
|
||||
error_at( &attr->where, "inapplicable attribute %s for enum member\n",
|
||||
allowed_attr[attr->type].display_name );
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
attr_list_t *check_field_attrs( const char *name, attr_list_t *attrs )
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return NULL;
|
||||
LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
|
||||
{
|
||||
if (!allowed_attr[attr->type].on_field)
|
||||
error_at( &attr->where, "inapplicable attribute %s for field %s\n",
|
||||
allowed_attr[attr->type].display_name, name );
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
attr_list_t *check_function_attrs( const char *name, attr_list_t *attrs )
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return NULL;
|
||||
LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
|
||||
{
|
||||
if (!allowed_attr[attr->type].on_function)
|
||||
error_at( &attr->where, "inapplicable attribute %s for function %s\n",
|
||||
allowed_attr[attr->type].display_name, name );
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
attr_list_t *check_interface_attrs( const char *name, attr_list_t *attrs )
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return NULL;
|
||||
LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
|
||||
{
|
||||
if (!allowed_attr[attr->type].on_interface)
|
||||
error_at( &attr->where, "inapplicable attribute %s for interface %s\n",
|
||||
allowed_attr[attr->type].display_name, name );
|
||||
if (attr->type == ATTR_IMPLICIT_HANDLE)
|
||||
{
|
||||
const var_t *var = attr->u.pval;
|
||||
if (type_get_type( var->declspec.type ) == TYPE_BASIC &&
|
||||
type_basic_get_type( var->declspec.type ) == TYPE_BASIC_HANDLE)
|
||||
continue;
|
||||
if (is_aliaschain_attr( var->declspec.type, ATTR_HANDLE )) continue;
|
||||
error_at( &attr->where, "attribute %s requires a handle type in interface %s\n",
|
||||
allowed_attr[attr->type].display_name, name );
|
||||
}
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
attr_list_t *check_library_attrs( const char *name, attr_list_t *attrs )
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return NULL;
|
||||
LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
|
||||
{
|
||||
if (!allowed_attr[attr->type].on_library)
|
||||
error_at( &attr->where, "inapplicable attribute %s for library %s\n",
|
||||
allowed_attr[attr->type].display_name, name );
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
attr_list_t *check_module_attrs( const char *name, attr_list_t *attrs )
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return NULL;
|
||||
LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
|
||||
{
|
||||
if (!allowed_attr[attr->type].on_module)
|
||||
error_at( &attr->where, "inapplicable attribute %s for module %s\n",
|
||||
allowed_attr[attr->type].display_name, name );
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
attr_list_t *check_runtimeclass_attrs( const char *name, attr_list_t *attrs )
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return NULL;
|
||||
LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
|
||||
{
|
||||
if (!allowed_attr[attr->type].on_runtimeclass)
|
||||
error_at( &attr->where, "inapplicable attribute %s for runtimeclass %s\n",
|
||||
allowed_attr[attr->type].display_name, name );
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
attr_list_t *check_struct_attrs( attr_list_t *attrs )
|
||||
{
|
||||
int mask = winrt_mode ? 3 : 1;
|
||||
const attr_t *attr;
|
||||
if (!attrs) return NULL;
|
||||
LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
|
||||
{
|
||||
if (!(allowed_attr[attr->type].on_struct & mask))
|
||||
error_at( &attr->where, "inapplicable attribute %s for struct\n",
|
||||
allowed_attr[attr->type].display_name );
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
attr_list_t *check_typedef_attrs( attr_list_t *attrs )
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return NULL;
|
||||
LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
|
||||
{
|
||||
if (!allowed_attr[attr->type].on_type)
|
||||
error_at( &attr->where, "inapplicable attribute %s for typedef\n",
|
||||
allowed_attr[attr->type].display_name );
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
attr_list_t *check_union_attrs( attr_list_t *attrs )
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return NULL;
|
||||
LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
|
||||
{
|
||||
if (!allowed_attr[attr->type].on_union)
|
||||
error_at( &attr->where, "inapplicable attribute %s for union\n",
|
||||
allowed_attr[attr->type].display_name );
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
void check_arg_attrs( const var_t *arg )
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!arg->attrs) return;
|
||||
LIST_FOR_EACH_ENTRY( attr, arg->attrs, const attr_t, entry )
|
||||
{
|
||||
if (!allowed_attr[attr->type].on_arg)
|
||||
error_at( &attr->where, "inapplicable attribute %s for argument %s\n",
|
||||
allowed_attr[attr->type].display_name, arg->name );
|
||||
}
|
||||
}
|
||||
+39
-45
@@ -19,13 +19,9 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "wine/port.h"
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
@@ -52,17 +48,16 @@ static void print_client( const char *format, ... )
|
||||
|
||||
static void write_client_func_decl( const type_t *iface, const var_t *func )
|
||||
{
|
||||
const char *callconv = get_attrp(func->type->attrs, ATTR_CALLCONV);
|
||||
const var_list_t *args = type_get_function_args(func->type);
|
||||
type_t *rettype = type_function_get_rettype(func->type);
|
||||
const char *callconv = get_attrp(func->declspec.type->attrs, ATTR_CALLCONV);
|
||||
const var_list_t *args = type_function_get_args(func->declspec.type);
|
||||
const decl_spec_t *rettype = type_function_get_ret(func->declspec.type);
|
||||
|
||||
if (!callconv) callconv = "__cdecl";
|
||||
write_type_decl_left(client, rettype);
|
||||
fprintf(client, " %s ", callconv);
|
||||
fprintf(client, "%s%s(\n", prefix_client, get_name(func));
|
||||
indent++;
|
||||
if (args)
|
||||
write_args(client, args, iface->name, 0, TRUE);
|
||||
if (args) write_args(client, args, iface->name, 0, TRUE, NAME_DEFAULT);
|
||||
else
|
||||
print_client("void");
|
||||
fprintf(client, ")\n");
|
||||
@@ -74,9 +69,9 @@ static void write_function_stub( const type_t *iface, const var_t *func,
|
||||
{
|
||||
unsigned char explicit_fc, implicit_fc;
|
||||
int has_full_pointer = is_full_pointer_function(func);
|
||||
var_t *retval = type_function_get_retval(func->type);
|
||||
var_t *retval = type_function_get_retval(func->declspec.type);
|
||||
const var_t *handle_var = get_func_handle_var( iface, func, &explicit_fc, &implicit_fc );
|
||||
int has_ret = !is_void(retval->type);
|
||||
int has_ret = !is_void(retval->declspec.type);
|
||||
|
||||
if (is_interpreted_func( iface, func ))
|
||||
{
|
||||
@@ -97,7 +92,7 @@ static void write_function_stub( const type_t *iface, const var_t *func,
|
||||
print_client("RPC_BINDING_HANDLE _Handle;\n");
|
||||
}
|
||||
|
||||
if (has_ret && decl_indirect(retval->type))
|
||||
if (has_ret && decl_indirect(retval->declspec.type))
|
||||
{
|
||||
print_client("void *_p_%s;\n", retval->name);
|
||||
}
|
||||
@@ -111,6 +106,7 @@ static void write_function_stub( const type_t *iface, const var_t *func,
|
||||
if (has_full_pointer)
|
||||
write_full_pointer_free(client, indent, func);
|
||||
|
||||
if (interpreted_mode) print_client("NdrCorrelationFree(&__frame->_StubMsg);\n");
|
||||
print_client("NdrFreeBuffer(&__frame->_StubMsg);\n");
|
||||
|
||||
if (explicit_fc == FC_BIND_GENERIC)
|
||||
@@ -136,9 +132,10 @@ static void write_function_stub( const type_t *iface, const var_t *func,
|
||||
if (has_ret)
|
||||
{
|
||||
print_client("%s", "");
|
||||
write_type_decl(client, retval->type, retval->name);
|
||||
write_type_decl(client, &retval->declspec, retval->name);
|
||||
fprintf(client, ";\n");
|
||||
}
|
||||
if (interpreted_mode) print_client("ULONG _NdrCorrCache[256];\n");
|
||||
print_client("RPC_MESSAGE _RpcMessage;\n");
|
||||
|
||||
if (handle_var)
|
||||
@@ -147,7 +144,7 @@ static void write_function_stub( const type_t *iface, const var_t *func,
|
||||
if (explicit_fc == FC_BIND_GENERIC)
|
||||
print_client("__frame->%s = %s;\n", handle_var->name, handle_var->name );
|
||||
}
|
||||
if (has_ret && decl_indirect(retval->type))
|
||||
if (has_ret && decl_indirect(retval->declspec.type))
|
||||
{
|
||||
print_client("__frame->_p_%s = &%s;\n", retval->name, retval->name);
|
||||
}
|
||||
@@ -194,7 +191,7 @@ static void write_function_stub( const type_t *iface, const var_t *func,
|
||||
/* if the context_handle attribute appears in the chain of types
|
||||
* without pointers being followed, then the context handle must
|
||||
* be direct, otherwise it is a pointer */
|
||||
int is_ch_ptr = !is_aliaschain_attr(handle_var->type, ATTR_CONTEXTHANDLE);
|
||||
int is_ch_ptr = !is_aliaschain_attr(handle_var->declspec.type, ATTR_CONTEXTHANDLE);
|
||||
print_client("if (%s%s != 0)\n", is_ch_ptr ? "*" : "", handle_var->name);
|
||||
indent++;
|
||||
print_client("__frame->_Handle = NDRCContextBinding(%s%s);\n",
|
||||
@@ -218,6 +215,8 @@ static void write_function_stub( const type_t *iface, const var_t *func,
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (interpreted_mode)
|
||||
print_client( "NdrCorrelationInitialize(&__frame->_StubMsg, _NdrCorrCache, sizeof(_NdrCorrCache), 0);\n" );
|
||||
|
||||
write_remoting_arguments(client, indent, func, "", PASS_IN, PHASE_BUFFERSIZE);
|
||||
|
||||
@@ -257,9 +256,9 @@ static void write_function_stub( const type_t *iface, const var_t *func,
|
||||
/* unmarshal return value */
|
||||
if (has_ret)
|
||||
{
|
||||
if (decl_indirect(retval->type))
|
||||
if (decl_indirect(retval->declspec.type))
|
||||
print_client("MIDL_memset(&%s, 0, sizeof(%s));\n", retval->name, retval->name);
|
||||
else if (is_ptr(retval->type) || is_array(retval->type))
|
||||
else if (is_ptr(retval->declspec.type) || is_array(retval->declspec.type))
|
||||
print_client("%s = 0;\n", retval->name);
|
||||
write_remoting_arguments(client, indent, func, "", PASS_RETURN, PHASE_UNMARSHAL);
|
||||
}
|
||||
@@ -290,8 +289,7 @@ static void write_function_stub( const type_t *iface, const var_t *func,
|
||||
static void write_serialize_function(FILE *file, const type_t *type, const type_t *iface,
|
||||
const char *func_name, const char *ret_type)
|
||||
{
|
||||
enum stub_mode mode = get_stub_mode();
|
||||
static int emited_pickling_info;
|
||||
static int emitted_pickling_info;
|
||||
|
||||
if (iface && !type->typestring_offset)
|
||||
{
|
||||
@@ -301,7 +299,7 @@ static void write_serialize_function(FILE *file, const type_t *type, const type_
|
||||
return;
|
||||
}
|
||||
|
||||
if (!emited_pickling_info && iface && mode != MODE_Os)
|
||||
if (!emitted_pickling_info && iface && interpreted_mode)
|
||||
{
|
||||
fprintf(file, "static const MIDL_TYPE_PICKLING_INFO __MIDL_TypePicklingInfo =\n");
|
||||
fprintf(file, "{\n");
|
||||
@@ -312,7 +310,7 @@ static void write_serialize_function(FILE *file, const type_t *type, const type_
|
||||
fprintf(file, " 0\n");
|
||||
fprintf(file, "};\n");
|
||||
fprintf(file, "\n");
|
||||
emited_pickling_info = 1;
|
||||
emitted_pickling_info = 1;
|
||||
}
|
||||
|
||||
/* FIXME: Assuming explicit handle */
|
||||
@@ -323,9 +321,9 @@ static void write_serialize_function(FILE *file, const type_t *type, const type_
|
||||
|
||||
fprintf(file, "{\n");
|
||||
fprintf(file, " %sNdrMesType%s%s(\n", ret_type ? "return " : "", func_name,
|
||||
mode != MODE_Os ? "2" : "");
|
||||
interpreted_mode ? "2" : "");
|
||||
fprintf(file, " IDL_handle,\n");
|
||||
if (mode != MODE_Os)
|
||||
if (interpreted_mode)
|
||||
fprintf(file, " (MIDL_TYPE_PICKLING_INFO*)&__MIDL_TypePicklingInfo,\n");
|
||||
fprintf(file, " &%s_StubDesc,\n", iface->name);
|
||||
fprintf(file, " (PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u],\n",
|
||||
@@ -365,8 +363,8 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
|
||||
case STMT_DECLARATION:
|
||||
{
|
||||
const var_t *func = stmt->u.var;
|
||||
if (stmt->u.var->stgclass != STG_NONE
|
||||
|| type_get_type_detect_alias(stmt->u.var->type) != TYPE_FUNCTION)
|
||||
if (stmt->u.var->declspec.stgclass != STG_NONE
|
||||
|| type_get_type_detect_alias(stmt->u.var->declspec.type) != TYPE_FUNCTION)
|
||||
continue;
|
||||
write_function_stub( iface, func, method_count++, *proc_offset );
|
||||
*proc_offset += get_size_procformatstring_func( iface, func );
|
||||
@@ -374,9 +372,9 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
|
||||
}
|
||||
case STMT_TYPEDEF:
|
||||
{
|
||||
const type_list_t *type_entry;
|
||||
for (type_entry = stmt->u.type_list; type_entry; type_entry = type_entry->next)
|
||||
write_serialize_functions(client, type_entry->type, iface);
|
||||
typeref_t *ref;
|
||||
if (stmt->u.type_list) LIST_FOR_EACH_ENTRY(ref, stmt->u.type_list, typeref_t, entry)
|
||||
write_serialize_functions(client, ref->type, iface);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -423,9 +421,9 @@ static void write_stubdescriptor(type_t *iface, int expr_eval_routines)
|
||||
print_client("0,\n");
|
||||
print_client("__MIDL_TypeFormatString.Format,\n");
|
||||
print_client("1, /* -error bounds_check flag */\n");
|
||||
print_client("0x%x, /* Ndr library version */\n", get_stub_mode() == MODE_Oif ? 0x50002 : 0x10001);
|
||||
print_client("0x%x, /* Ndr library version */\n", interpreted_mode ? 0x50002 : 0x10001);
|
||||
print_client("0,\n");
|
||||
print_client("0x50100a4, /* MIDL Version 5.1.164 */\n");
|
||||
print_client("0x50200ca, /* MIDL Version 5.2.202 */\n");
|
||||
print_client("0,\n");
|
||||
print_client("%s,\n", list_empty(&user_type_list) ? "0" : "UserMarshalRoutines");
|
||||
print_client("0, /* notify & notify_flag routine table */\n");
|
||||
@@ -442,7 +440,7 @@ static void write_stubdescriptor(type_t *iface, int expr_eval_routines)
|
||||
static void write_clientinterfacedecl(type_t *iface)
|
||||
{
|
||||
unsigned int ver = get_attrv(iface->attrs, ATTR_VERSION);
|
||||
const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID);
|
||||
const struct uuid *uuid = get_attrp(iface->attrs, ATTR_UUID);
|
||||
const str_list_t *endpoints = get_attrp(iface->attrs, ATTR_ENDPOINT);
|
||||
|
||||
if (endpoints) write_endpoints( client, iface->name, endpoints );
|
||||
@@ -473,10 +471,10 @@ static void write_clientinterfacedecl(type_t *iface)
|
||||
indent--;
|
||||
print_client("};\n");
|
||||
if (old_names)
|
||||
print_client("RPC_IF_HANDLE %s_ClientIfHandle DECLSPEC_HIDDEN = (RPC_IF_HANDLE)& %s___RpcClientInterface;\n",
|
||||
print_client("RPC_IF_HANDLE %s_ClientIfHandle = (RPC_IF_HANDLE)& %s___RpcClientInterface;\n",
|
||||
iface->name, iface->name);
|
||||
else
|
||||
print_client("RPC_IF_HANDLE %s%s_v%d_%d_c_ifspec DECLSPEC_HIDDEN = (RPC_IF_HANDLE)& %s___RpcClientInterface;\n",
|
||||
print_client("RPC_IF_HANDLE %s%s_v%d_%d_c_ifspec = (RPC_IF_HANDLE)& %s___RpcClientInterface;\n",
|
||||
prefix_client, iface->name, MAJORVERSION(ver), MINORVERSION(ver), iface->name);
|
||||
fprintf(client, "\n");
|
||||
}
|
||||
@@ -488,7 +486,7 @@ static void write_implicithandledecl(type_t *iface)
|
||||
|
||||
if (implicit_handle)
|
||||
{
|
||||
write_type_decl( client, implicit_handle->type, implicit_handle->name );
|
||||
write_type_decl(client, &implicit_handle->declspec, implicit_handle->name);
|
||||
fprintf(client, ";\n\n");
|
||||
}
|
||||
}
|
||||
@@ -505,10 +503,6 @@ static void init_client(void)
|
||||
print_client( "\n");
|
||||
print_client("#include \"%s\"\n", header_name);
|
||||
print_client( "\n");
|
||||
print_client( "#ifndef DECLSPEC_HIDDEN\n");
|
||||
print_client( "#define DECLSPEC_HIDDEN\n");
|
||||
print_client( "#endif\n");
|
||||
print_client( "\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -532,19 +526,19 @@ static void write_client_ifaces(const statement_list_t *stmts, int expr_eval_rou
|
||||
|
||||
LIST_FOR_EACH_ENTRY(stmt2, type_iface_get_stmts(iface), const statement_t, entry)
|
||||
{
|
||||
if (stmt2->type == STMT_DECLARATION && stmt2->u.var->stgclass == STG_NONE &&
|
||||
type_get_type_detect_alias(stmt2->u.var->type) == TYPE_FUNCTION)
|
||||
if (stmt2->type == STMT_DECLARATION && stmt2->u.var->declspec.stgclass == STG_NONE &&
|
||||
type_get_type_detect_alias(stmt2->u.var->declspec.type) == TYPE_FUNCTION)
|
||||
{
|
||||
needs_stub = 1;
|
||||
break;
|
||||
}
|
||||
if (stmt2->type == STMT_TYPEDEF)
|
||||
{
|
||||
const type_list_t *type_entry;
|
||||
for (type_entry = stmt2->u.type_list; type_entry; type_entry = type_entry->next)
|
||||
typeref_t *ref;
|
||||
if (stmt2->u.type_list) LIST_FOR_EACH_ENTRY(ref, stmt2->u.type_list, typeref_t, entry)
|
||||
{
|
||||
if (is_attr(type_entry->type->attrs, ATTR_ENCODE)
|
||||
|| is_attr(type_entry->type->attrs, ATTR_DECODE))
|
||||
if (is_attr(ref->type->attrs, ATTR_ENCODE)
|
||||
|| is_attr(ref->type->attrs, ATTR_DECODE))
|
||||
{
|
||||
needs_stub = 1;
|
||||
break;
|
||||
|
||||
+66
-74
@@ -112,28 +112,24 @@ static int is_float_type(const type_t *type)
|
||||
expr_t *make_expr(enum expr_type type)
|
||||
{
|
||||
expr_t *e = xmalloc(sizeof(expr_t));
|
||||
memset(e, 0, sizeof(*e));
|
||||
e->type = type;
|
||||
e->ref = NULL;
|
||||
e->u.lval = 0;
|
||||
e->is_const = FALSE;
|
||||
e->cval = 0;
|
||||
return e;
|
||||
}
|
||||
|
||||
expr_t *make_exprl(enum expr_type type, int val)
|
||||
expr_t *make_exprl(enum expr_type type, const struct integer *integer)
|
||||
{
|
||||
expr_t *e = xmalloc(sizeof(expr_t));
|
||||
memset(e, 0, sizeof(*e));
|
||||
e->type = type;
|
||||
e->ref = NULL;
|
||||
e->u.lval = val;
|
||||
e->is_const = FALSE;
|
||||
e->u.integer = *integer;
|
||||
/* check for numeric constant */
|
||||
if (type == EXPR_NUM || type == EXPR_HEXNUM || type == EXPR_TRUEFALSE)
|
||||
if (type == EXPR_NUM || type == EXPR_TRUEFALSE)
|
||||
{
|
||||
/* make sure true/false value is valid */
|
||||
assert(type != EXPR_TRUEFALSE || val == 0 || val == 1);
|
||||
assert(type != EXPR_TRUEFALSE || integer->value == 0 || integer->value == 1);
|
||||
e->is_const = TRUE;
|
||||
e->cval = val;
|
||||
e->cval = integer->value;
|
||||
}
|
||||
return e;
|
||||
}
|
||||
@@ -194,15 +190,15 @@ expr_t *make_exprt(enum expr_type type, var_t *var, expr_t *expr)
|
||||
expr_t *e;
|
||||
type_t *tref;
|
||||
|
||||
if (var->stgclass != STG_NONE && var->stgclass != STG_REGISTER)
|
||||
if (var->declspec.stgclass != STG_NONE && var->declspec.stgclass != STG_REGISTER)
|
||||
error_loc("invalid storage class for type expression\n");
|
||||
|
||||
tref = var->type;
|
||||
tref = var->declspec.type;
|
||||
|
||||
e = xmalloc(sizeof(expr_t));
|
||||
e->type = type;
|
||||
e->ref = expr;
|
||||
e->u.tref = tref;
|
||||
e->u.tref = var->declspec;
|
||||
e->is_const = FALSE;
|
||||
if (type == EXPR_SIZEOF)
|
||||
{
|
||||
@@ -252,10 +248,9 @@ expr_t *make_expr1(enum expr_type type, expr_t *expr)
|
||||
{
|
||||
expr_t *e;
|
||||
e = xmalloc(sizeof(expr_t));
|
||||
memset(e, 0, sizeof(*e));
|
||||
e->type = type;
|
||||
e->ref = expr;
|
||||
e->u.lval = 0;
|
||||
e->is_const = FALSE;
|
||||
/* check for compile-time optimization */
|
||||
if (expr->is_const)
|
||||
{
|
||||
@@ -406,29 +401,25 @@ struct expression_type
|
||||
static void check_scalar_type(const struct expr_loc *expr_loc,
|
||||
const type_t *cont_type, const type_t *type)
|
||||
{
|
||||
if (!cont_type || (!is_integer_type(type) && !is_ptr(type) &&
|
||||
!is_float_type(type)))
|
||||
error_loc_info(&expr_loc->v->loc_info, "scalar type required in expression%s%s\n",
|
||||
expr_loc->attr ? " for attribute " : "",
|
||||
expr_loc->attr ? expr_loc->attr : "");
|
||||
if (!cont_type || (!is_integer_type( type ) && !is_ptr( type ) && !is_float_type( type )))
|
||||
error_at( &expr_loc->v->where, "scalar type required in expression%s%s\n",
|
||||
expr_loc->attr ? " for attribute " : "", expr_loc->attr ? expr_loc->attr : "" );
|
||||
}
|
||||
|
||||
static void check_arithmetic_type(const struct expr_loc *expr_loc,
|
||||
const type_t *cont_type, const type_t *type)
|
||||
{
|
||||
if (!cont_type || (!is_integer_type(type) && !is_float_type(type)))
|
||||
error_loc_info(&expr_loc->v->loc_info, "arithmetic type required in expression%s%s\n",
|
||||
expr_loc->attr ? " for attribute " : "",
|
||||
expr_loc->attr ? expr_loc->attr : "");
|
||||
if (!cont_type || (!is_integer_type( type ) && !is_float_type( type )))
|
||||
error_at( &expr_loc->v->where, "arithmetic type required in expression%s%s\n",
|
||||
expr_loc->attr ? " for attribute " : "", expr_loc->attr ? expr_loc->attr : "" );
|
||||
}
|
||||
|
||||
static void check_integer_type(const struct expr_loc *expr_loc,
|
||||
const type_t *cont_type, const type_t *type)
|
||||
{
|
||||
if (!cont_type || !is_integer_type(type))
|
||||
error_loc_info(&expr_loc->v->loc_info, "integer type required in expression%s%s\n",
|
||||
expr_loc->attr ? " for attribute " : "",
|
||||
expr_loc->attr ? expr_loc->attr : "");
|
||||
if (!cont_type || !is_integer_type( type ))
|
||||
error_at( &expr_loc->v->where, "integer type required in expression%s%s\n",
|
||||
expr_loc->attr ? " for attribute " : "", expr_loc->attr ? expr_loc->attr : "" );
|
||||
}
|
||||
|
||||
static type_t *find_identifier(const char *identifier, const type_t *cont_type, int *found_in_cont_type)
|
||||
@@ -462,6 +453,11 @@ static type_t *find_identifier(const char *identifier, const type_t *cont_type,
|
||||
case TYPE_POINTER:
|
||||
case TYPE_ARRAY:
|
||||
case TYPE_BITFIELD:
|
||||
case TYPE_APICONTRACT:
|
||||
case TYPE_RUNTIMECLASS:
|
||||
case TYPE_PARAMETERIZED_TYPE:
|
||||
case TYPE_PARAMETER:
|
||||
case TYPE_DELEGATE:
|
||||
/* nothing to do */
|
||||
break;
|
||||
case TYPE_ALIAS:
|
||||
@@ -474,7 +470,7 @@ static type_t *find_identifier(const char *identifier, const type_t *cont_type,
|
||||
if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
|
||||
if (field->name && !strcmp(identifier, field->name))
|
||||
{
|
||||
type = field->type;
|
||||
type = field->declspec.type;
|
||||
*found_in_cont_type = 1;
|
||||
break;
|
||||
}
|
||||
@@ -482,7 +478,7 @@ static type_t *find_identifier(const char *identifier, const type_t *cont_type,
|
||||
if (!type)
|
||||
{
|
||||
var_t *const_var = find_const(identifier, 0);
|
||||
if (const_var) type = const_var->type;
|
||||
if (const_var) type = const_var->declspec.type;
|
||||
}
|
||||
|
||||
return type;
|
||||
@@ -513,19 +509,18 @@ static struct expression_type resolve_expression(const struct expr_loc *expr_loc
|
||||
{
|
||||
case EXPR_VOID:
|
||||
break;
|
||||
case EXPR_HEXNUM:
|
||||
case EXPR_NUM:
|
||||
case EXPR_TRUEFALSE:
|
||||
result.is_temporary = FALSE;
|
||||
result.type = type_new_int(TYPE_BASIC_INT, 0);
|
||||
result.type = type_new_int(e->u.integer.is_long ? TYPE_BASIC_LONG : TYPE_BASIC_INT, e->u.integer.is_unsigned);
|
||||
break;
|
||||
case EXPR_STRLIT:
|
||||
result.is_temporary = TRUE;
|
||||
result.type = type_new_pointer(FC_UP, type_new_int(TYPE_BASIC_CHAR, 0), NULL);
|
||||
result.type = type_new_pointer(type_new_int(TYPE_BASIC_CHAR, 0));
|
||||
break;
|
||||
case EXPR_WSTRLIT:
|
||||
result.is_temporary = TRUE;
|
||||
result.type = type_new_pointer(FC_UP, type_new_int(TYPE_BASIC_WCHAR, 0), NULL);
|
||||
result.type = type_new_pointer(type_new_int(TYPE_BASIC_WCHAR, 0));
|
||||
break;
|
||||
case EXPR_CHARCONST:
|
||||
result.is_temporary = TRUE;
|
||||
@@ -542,11 +537,8 @@ static struct expression_type resolve_expression(const struct expr_loc *expr_loc
|
||||
result.is_temporary = FALSE;
|
||||
result.type = find_identifier(e->u.sval, cont_type, &found_in_cont_type);
|
||||
if (!result.type)
|
||||
{
|
||||
error_loc_info(&expr_loc->v->loc_info, "identifier %s cannot be resolved in expression%s%s\n",
|
||||
e->u.sval, expr_loc->attr ? " for attribute " : "",
|
||||
expr_loc->attr ? expr_loc->attr : "");
|
||||
}
|
||||
error_at( &expr_loc->v->where, "identifier %s cannot be resolved in expression%s%s\n", e->u.sval,
|
||||
expr_loc->attr ? " for attribute " : "", expr_loc->attr ? expr_loc->attr : "" );
|
||||
break;
|
||||
}
|
||||
case EXPR_LOGNOT:
|
||||
@@ -570,28 +562,26 @@ static struct expression_type resolve_expression(const struct expr_loc *expr_loc
|
||||
case EXPR_ADDRESSOF:
|
||||
result = resolve_expression(expr_loc, cont_type, e->ref);
|
||||
if (!result.is_variable)
|
||||
error_loc_info(&expr_loc->v->loc_info, "address-of operator applied to non-variable type in expression%s%s\n",
|
||||
expr_loc->attr ? " for attribute " : "",
|
||||
expr_loc->attr ? expr_loc->attr : "");
|
||||
error_at( &expr_loc->v->where, "address-of operator applied to non-variable type in expression%s%s\n",
|
||||
expr_loc->attr ? " for attribute " : "", expr_loc->attr ? expr_loc->attr : "" );
|
||||
result.is_variable = FALSE;
|
||||
result.is_temporary = TRUE;
|
||||
result.type = type_new_pointer(FC_UP, result.type, NULL);
|
||||
result.type = type_new_pointer(result.type);
|
||||
break;
|
||||
case EXPR_PPTR:
|
||||
result = resolve_expression(expr_loc, cont_type, e->ref);
|
||||
if (result.type && is_ptr(result.type))
|
||||
result.type = type_pointer_get_ref(result.type);
|
||||
result.type = type_pointer_get_ref_type(result.type);
|
||||
else if(result.type && is_array(result.type)
|
||||
&& type_array_is_decl_as_ptr(result.type))
|
||||
result.type = type_array_get_element(result.type);
|
||||
result.type = type_array_get_element_type(result.type);
|
||||
else
|
||||
error_loc_info(&expr_loc->v->loc_info, "dereference operator applied to non-pointer type in expression%s%s\n",
|
||||
expr_loc->attr ? " for attribute " : "",
|
||||
expr_loc->attr ? expr_loc->attr : "");
|
||||
error_at( &expr_loc->v->where, "dereference operator applied to non-pointer type in expression%s%s\n",
|
||||
expr_loc->attr ? " for attribute " : "", expr_loc->attr ? expr_loc->attr : "" );
|
||||
break;
|
||||
case EXPR_CAST:
|
||||
result = resolve_expression(expr_loc, cont_type, e->ref);
|
||||
result.type = e->u.tref;
|
||||
result.type = e->u.tref.type;
|
||||
break;
|
||||
case EXPR_SIZEOF:
|
||||
result.is_temporary = FALSE;
|
||||
@@ -640,9 +630,8 @@ static struct expression_type resolve_expression(const struct expr_loc *expr_loc
|
||||
if (result.type && is_valid_member_operand(result.type))
|
||||
result = resolve_expression(expr_loc, result.type, e->u.ext);
|
||||
else
|
||||
error_loc_info(&expr_loc->v->loc_info, "'.' or '->' operator applied to a type that isn't a structure, union or enumeration in expression%s%s\n",
|
||||
expr_loc->attr ? " for attribute " : "",
|
||||
expr_loc->attr ? expr_loc->attr : "");
|
||||
error_at( &expr_loc->v->where, "'.' or '->' operator applied to a type that isn't a structure, union or enumeration in expression%s%s\n",
|
||||
expr_loc->attr ? " for attribute " : "", expr_loc->attr ? expr_loc->attr : "" );
|
||||
break;
|
||||
case EXPR_COND:
|
||||
{
|
||||
@@ -653,8 +642,8 @@ static struct expression_type resolve_expression(const struct expr_loc *expr_loc
|
||||
result_third = resolve_expression(expr_loc, cont_type, e->ext2);
|
||||
check_scalar_type(expr_loc, cont_type, result_second.type);
|
||||
check_scalar_type(expr_loc, cont_type, result_third.type);
|
||||
if (!is_ptr(result_second.type) ^ !is_ptr(result_third.type))
|
||||
error_loc_info(&expr_loc->v->loc_info, "type mismatch in ?: expression\n" );
|
||||
if (!is_ptr( result_second.type ) ^ !is_ptr( result_third.type ))
|
||||
error_at( &expr_loc->v->where, "type mismatch in ?: expression\n" );
|
||||
/* FIXME: determine the correct return type */
|
||||
result = result_second;
|
||||
result.is_variable = FALSE;
|
||||
@@ -665,17 +654,17 @@ static struct expression_type resolve_expression(const struct expr_loc *expr_loc
|
||||
if (result.type && is_array(result.type))
|
||||
{
|
||||
struct expression_type index_result;
|
||||
result.type = type_array_get_element(result.type);
|
||||
result.type = type_array_get_element_type(result.type);
|
||||
index_result = resolve_expression(expr_loc, cont_type /* FIXME */, e->u.ext);
|
||||
if (!index_result.type || !is_integer_type(index_result.type))
|
||||
error_loc_info(&expr_loc->v->loc_info, "array subscript not of integral type in expression%s%s\n",
|
||||
expr_loc->attr ? " for attribute " : "",
|
||||
expr_loc->attr ? expr_loc->attr : "");
|
||||
if (!index_result.type || !is_integer_type( index_result.type ))
|
||||
error_at( &expr_loc->v->where, "array subscript not of integral type in expression%s%s\n",
|
||||
expr_loc->attr ? " for attribute " : "", expr_loc->attr ? expr_loc->attr : "" );
|
||||
}
|
||||
else
|
||||
error_loc_info(&expr_loc->v->loc_info, "array subscript operator applied to non-array type in expression%s%s\n",
|
||||
expr_loc->attr ? " for attribute " : "",
|
||||
expr_loc->attr ? expr_loc->attr : "");
|
||||
{
|
||||
error_at( &expr_loc->v->where, "array subscript operator applied to non-array type in expression%s%s\n",
|
||||
expr_loc->attr ? " for attribute " : "", expr_loc->attr ? expr_loc->attr : "" );
|
||||
}
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
@@ -697,16 +686,20 @@ void write_expr(FILE *h, const expr_t *e, int brackets,
|
||||
case EXPR_VOID:
|
||||
break;
|
||||
case EXPR_NUM:
|
||||
fprintf(h, "%u", e->u.lval);
|
||||
break;
|
||||
case EXPR_HEXNUM:
|
||||
fprintf(h, "0x%x", e->u.lval);
|
||||
if (e->u.integer.is_hex)
|
||||
fprintf(h, "0x%x", e->u.integer.value);
|
||||
else
|
||||
fprintf(h, "%u", e->u.integer.value);
|
||||
if (e->u.integer.is_unsigned)
|
||||
fprintf(h, "u");
|
||||
if (e->u.integer.is_long)
|
||||
fprintf(h, "l");
|
||||
break;
|
||||
case EXPR_DOUBLE:
|
||||
fprintf(h, "%#.15g", e->u.dval);
|
||||
break;
|
||||
case EXPR_TRUEFALSE:
|
||||
if (e->u.lval == 0)
|
||||
if (e->u.integer.value == 0)
|
||||
fprintf(h, "FALSE");
|
||||
else
|
||||
fprintf(h, "TRUE");
|
||||
@@ -759,13 +752,13 @@ void write_expr(FILE *h, const expr_t *e, int brackets,
|
||||
break;
|
||||
case EXPR_CAST:
|
||||
fprintf(h, "(");
|
||||
write_type_decl(h, e->u.tref, NULL);
|
||||
write_type_decl(h, &e->u.tref, NULL);
|
||||
fprintf(h, ")");
|
||||
write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
|
||||
break;
|
||||
case EXPR_SIZEOF:
|
||||
fprintf(h, "sizeof(");
|
||||
write_type_decl(h, e->u.tref, NULL);
|
||||
write_type_decl(h, &e->u.tref, NULL);
|
||||
fprintf(h, ")");
|
||||
break;
|
||||
case EXPR_SHL:
|
||||
@@ -874,9 +867,8 @@ int compare_expr(const expr_t *a, const expr_t *b)
|
||||
switch (a->type)
|
||||
{
|
||||
case EXPR_NUM:
|
||||
case EXPR_HEXNUM:
|
||||
case EXPR_TRUEFALSE:
|
||||
return a->u.lval - b->u.lval;
|
||||
return a->u.integer.value - b->u.integer.value;
|
||||
case EXPR_DOUBLE:
|
||||
return a->u.dval - b->u.dval;
|
||||
case EXPR_IDENTIFIER:
|
||||
@@ -917,7 +909,7 @@ int compare_expr(const expr_t *a, const expr_t *b)
|
||||
return ret;
|
||||
return compare_expr(a->u.ext, b->u.ext);
|
||||
case EXPR_CAST:
|
||||
ret = compare_type(a->u.tref, b->u.tref);
|
||||
ret = compare_type(a->u.tref.type, b->u.tref.type);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
/* Fall through. */
|
||||
@@ -929,7 +921,7 @@ int compare_expr(const expr_t *a, const expr_t *b)
|
||||
case EXPR_POS:
|
||||
return compare_expr(a->ref, b->ref);
|
||||
case EXPR_SIZEOF:
|
||||
return compare_type(a->u.tref, b->u.tref);
|
||||
return compare_type(a->u.tref.type, b->u.tref.type);
|
||||
case EXPR_VOID:
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ struct expr_loc
|
||||
};
|
||||
|
||||
extern expr_t *make_expr(enum expr_type type);
|
||||
extern expr_t *make_exprl(enum expr_type type, int val);
|
||||
extern expr_t *make_exprl(enum expr_type type, const struct integer *integer);
|
||||
extern expr_t *make_exprd(enum expr_type type, double val);
|
||||
extern expr_t *make_exprs(enum expr_type type, char *val);
|
||||
extern expr_t *make_exprt(enum expr_type type, var_t *var, expr_t *expr);
|
||||
|
||||
+137
-56
@@ -23,6 +23,7 @@
|
||||
|
||||
#ifdef __REACTOS__
|
||||
#include <nls.h>
|
||||
#include <string.h>
|
||||
#else
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
@@ -507,10 +508,10 @@ static const unsigned char Lookup_224[128 * 3] = {
|
||||
* skind and lcid, while the low word is based on a repeated string
|
||||
* hash of skind/str.
|
||||
*/
|
||||
unsigned int lhash_val_of_name_sys( syskind_t skind, LCID lcid, LPCSTR lpStr)
|
||||
unsigned int lhash_val_of_name_sys( syskind_t skind, int lcid, const char *lpStr)
|
||||
{
|
||||
ULONG nOffset, nMask = skind == SYS_MAC ? 1 : 0;
|
||||
ULONG nHiWord, nLoWord = 0x0deadbee;
|
||||
unsigned int nOffset, nMask = skind == SYS_MAC ? 1 : 0;
|
||||
unsigned int nHiWord, nLoWord = 0x0deadbee;
|
||||
const unsigned char *str = (const unsigned char *)lpStr, *pnLookup = NULL;
|
||||
|
||||
if (!str)
|
||||
@@ -519,59 +520,6 @@ unsigned int lhash_val_of_name_sys( syskind_t skind, LCID lcid, LPCSTR lpStr)
|
||||
switch (PRIMARYLANGID(LANGIDFROMLCID(lcid)))
|
||||
{
|
||||
default:
|
||||
fprintf(stderr, "Unknown lcid %x, treating as latin-based, please report\n", lcid);
|
||||
/* .. Fall Through .. */
|
||||
case LANG_AFRIKAANS: case LANG_ALBANIAN: case LANG_ARMENIAN:
|
||||
case LANG_ASSAMESE: case LANG_AZERI: case LANG_BASQUE:
|
||||
case LANG_BELARUSIAN: case LANG_BENGALI: case LANG_BULGARIAN:
|
||||
case LANG_CATALAN: case LANG_DANISH: case LANG_DIVEHI:
|
||||
case LANG_DUTCH: case LANG_ENGLISH: case LANG_ESTONIAN:
|
||||
case LANG_FAEROESE: case LANG_FINNISH: case LANG_FRENCH:
|
||||
case LANG_GALICIAN: case LANG_GEORGIAN: case LANG_GERMAN:
|
||||
case LANG_GUJARATI: case LANG_HINDI: case LANG_INDONESIAN:
|
||||
case LANG_ITALIAN: case LANG_KANNADA: case LANG_KASHMIRI:
|
||||
case LANG_KAZAK: case LANG_KONKANI: case LANG_KYRGYZ:
|
||||
case LANG_LATVIAN: case LANG_LITHUANIAN: case LANG_MACEDONIAN:
|
||||
case LANG_MALAY: case LANG_MALAYALAM: case LANG_MANIPURI:
|
||||
case LANG_MARATHI: case LANG_MONGOLIAN: case LANG_NEPALI:
|
||||
case LANG_ORIYA: case LANG_PORTUGUESE: case LANG_PUNJABI:
|
||||
case LANG_ROMANIAN: case LANG_SANSKRIT: case LANG_SERBIAN:
|
||||
case LANG_SINDHI: case LANG_SLOVENIAN: case LANG_SWAHILI:
|
||||
case LANG_SWEDISH: case LANG_SYRIAC: case LANG_TAMIL:
|
||||
case LANG_TATAR: case LANG_TELUGU: case LANG_THAI:
|
||||
case LANG_UKRAINIAN: case LANG_URDU: case LANG_UZBEK:
|
||||
case LANG_VIETNAMESE: case LANG_MALTESE: case LANG_IRISH:
|
||||
case LANG_SAMI: case LANG_UPPER_SORBIAN: case LANG_TSWANA:
|
||||
case LANG_XHOSA: case LANG_ZULU: case LANG_WELSH:
|
||||
case LANG_BRETON: case LANG_SCOTTISH_GAELIC: case LANG_NEUTRAL:
|
||||
/* some languages not in all windows versions or ReactOS */
|
||||
#ifdef LANG_MANX_GAELIC
|
||||
case LANG_MANX_GAELIC:
|
||||
#endif
|
||||
#ifdef LANG_TAJIK
|
||||
case LANG_TAJIK:
|
||||
#endif
|
||||
#ifdef LANG_ROMANSH
|
||||
case LANG_ROMANSH:
|
||||
#endif
|
||||
#ifdef LANG_SUTU
|
||||
case LANG_SUTU:
|
||||
#endif
|
||||
#ifdef LANG_TSONGA
|
||||
case LANG_TSONGA:
|
||||
#endif
|
||||
#ifdef LANG_VENDA
|
||||
case LANG_VENDA:
|
||||
#endif
|
||||
#ifdef LANG_ESPERANTO
|
||||
case LANG_ESPERANTO:
|
||||
#endif
|
||||
#ifdef LANG_WALON
|
||||
case LANG_WALON:
|
||||
#endif
|
||||
#ifdef LANG_CORNISH
|
||||
case LANG_CORNISH:
|
||||
#endif
|
||||
nOffset = 16;
|
||||
pnLookup = Lookup_16;
|
||||
break;
|
||||
@@ -643,3 +591,136 @@ unsigned int lhash_val_of_name_sys( syskind_t skind, LCID lcid, LPCSTR lpStr)
|
||||
|
||||
return nHiWord | nLoWord;
|
||||
}
|
||||
|
||||
/* SHA1 algorithm
|
||||
*
|
||||
* Based on public domain SHA code by Steve Reid <[email protected]>
|
||||
* Copied and adapted from ntdll.A_SHAInit / ntdll.A_SHAUpdate / ntdll.A_SHAFinal
|
||||
*/
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#define DWORD2BE(x) (x)
|
||||
#else
|
||||
#define DWORD2BE(x) ((((x) >> 24) & 0xff) | (((x) >> 8) & 0xff00) | (((x) << 8) & 0xff0000) | (((x) << 24) & 0xff000000))
|
||||
#endif
|
||||
|
||||
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
|
||||
#define blk0(i) (block[i] = DWORD2BE(block[i]))
|
||||
#define blk1(i) (block[i&15] = rol(block[(i+13)&15]^block[(i+8)&15]^block[(i+2)&15]^block[i&15],1))
|
||||
#define f1(x,y,z) (z^(x&(y^z)))
|
||||
#define f2(x,y,z) (x^y^z)
|
||||
#define f3(x,y,z) ((x&y)|(z&(x|y)))
|
||||
#define f4(x,y,z) (x^y^z)
|
||||
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
|
||||
#define R0(v,w,x,y,z,i) z+=f1(w,x,y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
|
||||
#define R1(v,w,x,y,z,i) z+=f1(w,x,y)+blk1(i)+0x5A827999+rol(v,5);w=rol(w,30);
|
||||
#define R2(v,w,x,y,z,i) z+=f2(w,x,y)+blk1(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
|
||||
#define R3(v,w,x,y,z,i) z+=f3(w,x,y)+blk1(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
|
||||
#define R4(v,w,x,y,z,i) z+=f4(w,x,y)+blk1(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
|
||||
|
||||
/* Hash a single 512-bit block. This is the core of the algorithm. */
|
||||
static void sha1_transform(struct sha1_context *ctx)
|
||||
{
|
||||
unsigned int a, b, c, d, e, *block = (unsigned int *)ctx->buffer;
|
||||
|
||||
/* Copy ctx->state[] to working variables */
|
||||
a = ctx->state[0];
|
||||
b = ctx->state[1];
|
||||
c = ctx->state[2];
|
||||
d = ctx->state[3];
|
||||
e = ctx->state[4];
|
||||
|
||||
/* 4 rounds of 20 operations each. Loop unrolled. */
|
||||
R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
|
||||
R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
|
||||
R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
|
||||
R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
|
||||
R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
|
||||
R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
|
||||
R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
|
||||
R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
|
||||
R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
|
||||
R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
|
||||
R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
|
||||
R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
|
||||
R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
|
||||
R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
|
||||
R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
|
||||
R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
|
||||
R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
|
||||
R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
|
||||
R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
|
||||
R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
|
||||
|
||||
/* Add the working variables back into ctx->state[] */
|
||||
ctx->state[0] += a;
|
||||
ctx->state[1] += b;
|
||||
ctx->state[2] += c;
|
||||
ctx->state[3] += d;
|
||||
ctx->state[4] += e;
|
||||
|
||||
/* Wipe variables */
|
||||
a = b = c = d = e = 0;
|
||||
}
|
||||
|
||||
void sha1_init(struct sha1_context *ctx)
|
||||
{
|
||||
/* SHA1 initialization constants */
|
||||
ctx->state[0] = 0x67452301;
|
||||
ctx->state[1] = 0xEFCDAB89;
|
||||
ctx->state[2] = 0x98BADCFE;
|
||||
ctx->state[3] = 0x10325476;
|
||||
ctx->state[4] = 0xC3D2E1F0;
|
||||
ctx->count[0] = 0;
|
||||
ctx->count[1] = 0;
|
||||
}
|
||||
|
||||
void sha1_update(struct sha1_context *ctx, const char *data, size_t data_size)
|
||||
{
|
||||
size_t buffer_size;
|
||||
|
||||
buffer_size = ctx->count[1] & 63;
|
||||
ctx->count[1] += data_size;
|
||||
if (ctx->count[1] < data_size) ctx->count[0]++;
|
||||
ctx->count[0] += (data_size >> 29);
|
||||
|
||||
if (buffer_size + data_size < 64)
|
||||
memcpy(&ctx->buffer[buffer_size], data, data_size);
|
||||
else
|
||||
{
|
||||
while (buffer_size + data_size >= 64)
|
||||
{
|
||||
memcpy(ctx->buffer + buffer_size, data, 64 - buffer_size);
|
||||
data += 64 - buffer_size;
|
||||
data_size -= 64 - buffer_size;
|
||||
sha1_transform(ctx);
|
||||
buffer_size = 0;
|
||||
}
|
||||
memcpy(ctx->buffer + buffer_size, data, data_size);
|
||||
}
|
||||
}
|
||||
|
||||
void sha1_finalize(struct sha1_context *ctx, unsigned int result[5])
|
||||
{
|
||||
unsigned int *count, length_hi, length_lo, i;
|
||||
size_t pad_size, buffer_size;
|
||||
char pad[72];
|
||||
|
||||
buffer_size = ctx->count[1] & 63;
|
||||
if (buffer_size >= 56) pad_size = 56 + 64 - buffer_size;
|
||||
else pad_size = 56 - buffer_size;
|
||||
|
||||
length_hi = (ctx->count[0] << 3) | (ctx->count[1] >> (32 - 3));
|
||||
length_lo = (ctx->count[1] << 3);
|
||||
|
||||
memset(pad + 1, 0, pad_size - 1);
|
||||
pad[0] = 0x80;
|
||||
count = (unsigned int*)(pad + pad_size);
|
||||
count[0] = DWORD2BE(length_hi);
|
||||
count[1] = DWORD2BE(length_lo);
|
||||
sha1_update(ctx, pad, pad_size + 8);
|
||||
|
||||
for (i = 0; i < 5; i++) result[i] = DWORD2BE(ctx->state[i]);
|
||||
|
||||
sha1_init(ctx);
|
||||
}
|
||||
|
||||
+12
-1
@@ -22,6 +22,17 @@
|
||||
#ifndef __WIDL_HASH_H
|
||||
#define __WIDL_HASH_H
|
||||
|
||||
extern unsigned int lhash_val_of_name_sys( syskind_t skind, LCID lcid, LPCSTR lpStr);
|
||||
extern unsigned int lhash_val_of_name_sys( syskind_t skind, int lcid, const char *lpStr);
|
||||
|
||||
struct sha1_context
|
||||
{
|
||||
unsigned int state[5];
|
||||
unsigned int count[2];
|
||||
char buffer[64];
|
||||
};
|
||||
|
||||
void sha1_init(struct sha1_context *ctx);
|
||||
void sha1_update(struct sha1_context *ctx, const char *data, size_t data_size);
|
||||
void sha1_finalize(struct sha1_context *ctx, unsigned int hash[5]);
|
||||
|
||||
#endif
|
||||
|
||||
+644
-348
File diff suppressed because it is too large
Load Diff
+13
-12
@@ -23,22 +23,18 @@
|
||||
|
||||
#include "typetree.h"
|
||||
|
||||
extern int is_ptrchain_attr(const var_t *var, enum attr_type t);
|
||||
extern int is_aliaschain_attr(const type_t *var, enum attr_type t);
|
||||
extern int is_attr(const attr_list_t *list, enum attr_type t);
|
||||
extern void *get_attrp(const attr_list_t *list, enum attr_type t);
|
||||
extern unsigned int get_attrv(const attr_list_t *list, enum attr_type t);
|
||||
extern const char* get_name(const var_t *v);
|
||||
extern void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly);
|
||||
extern void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, bool define, int write_callconv);
|
||||
extern void write_type_right(FILE *h, type_t *t, int is_field);
|
||||
extern void write_type_decl(FILE *f, type_t *t, const char *name);
|
||||
extern void write_type_decl_left(FILE *f, type_t *t);
|
||||
extern void write_type_decl(FILE *f, const decl_spec_t *t, const char *name);
|
||||
extern void write_type_decl_left(FILE *f, const decl_spec_t *ds);
|
||||
extern unsigned int get_context_handle_offset( const type_t *type );
|
||||
extern unsigned int get_generic_handle_offset( const type_t *type );
|
||||
extern int needs_space_after(type_t *t);
|
||||
extern int is_object(const type_t *iface);
|
||||
extern int is_local(const attr_list_t *list);
|
||||
extern int count_methods(const type_t *iface);
|
||||
extern const statement_t * get_callas_source(const type_t *iface, const var_t *def);
|
||||
extern int need_stub(const type_t *iface);
|
||||
extern int need_proxy(const type_t *iface);
|
||||
extern int need_inline_stubs(const type_t *iface);
|
||||
@@ -47,7 +43,7 @@ extern int need_proxy_file(const statement_list_t *stmts);
|
||||
extern int need_proxy_delegation(const statement_list_t *stmts);
|
||||
extern int need_inline_stubs_file(const statement_list_t *stmts);
|
||||
extern const var_t *is_callas(const attr_list_t *list);
|
||||
extern void write_args(FILE *h, const var_list_t *arg, const char *name, int obj, int do_indent);
|
||||
extern void write_args(FILE *h, const var_list_t *arg, const char *name, int obj, int do_indent, enum name_type name_type);
|
||||
extern const type_t* get_explicit_generic_handle_type(const var_t* var);
|
||||
extern const var_t *get_func_handle_var( const type_t *iface, const var_t *func,
|
||||
unsigned char *explicit_fc, unsigned char *implicit_fc );
|
||||
@@ -66,6 +62,11 @@ static inline int is_array(const type_t *t)
|
||||
return type_get_type(t) == TYPE_ARRAY;
|
||||
}
|
||||
|
||||
static inline int is_func(const type_t *t)
|
||||
{
|
||||
return type_get_type(t) == TYPE_FUNCTION;
|
||||
}
|
||||
|
||||
static inline int is_void(const type_t *t)
|
||||
{
|
||||
return type_get_type(t) == TYPE_VOID;
|
||||
@@ -83,12 +84,12 @@ static inline int is_conformant_array(const type_t *t)
|
||||
|
||||
static inline int last_ptr(const type_t *type)
|
||||
{
|
||||
return is_ptr(type) && !is_declptr(type_pointer_get_ref(type));
|
||||
return is_ptr(type) && !is_declptr(type_pointer_get_ref_type(type));
|
||||
}
|
||||
|
||||
static inline int last_array(const type_t *type)
|
||||
{
|
||||
return is_array(type) && !is_array(type_array_get_element(type));
|
||||
return is_array(type) && !is_array(type_array_get_element_type(type));
|
||||
}
|
||||
|
||||
static inline int is_string_type(const attr_list_t *attrs, const type_t *type)
|
||||
@@ -102,7 +103,7 @@ static inline int is_context_handle(const type_t *type)
|
||||
const type_t *t;
|
||||
for (t = type;
|
||||
is_ptr(t) || type_is_alias(t);
|
||||
t = type_is_alias(t) ? type_alias_get_aliasee(t) : type_pointer_get_ref(t))
|
||||
t = type_is_alias(t) ? type_alias_get_aliasee_type(t) : type_pointer_get_ref_type(t))
|
||||
if (is_attr(t->attrs, ATTR_CONTEXTHANDLE))
|
||||
return 1;
|
||||
return 0;
|
||||
|
||||
+10
-16
@@ -21,33 +21,27 @@
|
||||
#ifndef __WIDL_PARSER_H
|
||||
#define __WIDL_PARSER_H
|
||||
|
||||
typedef struct
|
||||
{
|
||||
type_t *interface;
|
||||
unsigned char old_pointer_default;
|
||||
} interface_info_t;
|
||||
#include "widltypes.h"
|
||||
|
||||
int parser_parse(void);
|
||||
|
||||
extern void parser_warning( const struct location *where, const char *message );
|
||||
extern void parser_error( const struct location *where, const char *message );
|
||||
extern void init_location( struct location *copy, const struct location *begin, const struct location *end );
|
||||
|
||||
extern FILE *parser_in;
|
||||
extern char *parser_text;
|
||||
extern int parser_debug;
|
||||
extern int yy_flex_debug;
|
||||
|
||||
int parser_lex(void);
|
||||
|
||||
extern int import_stack_ptr;
|
||||
int do_import(char *fname);
|
||||
void abort_import(void);
|
||||
void pop_import(void);
|
||||
|
||||
#define parse_only import_stack_ptr
|
||||
extern int parse_only;
|
||||
|
||||
int is_type(const char *name);
|
||||
|
||||
int do_warning(char *toggle, warning_list_t *wnum);
|
||||
int do_warning(const char *toggle, warning_list_t *wnum);
|
||||
int is_warning_enabled(int warning);
|
||||
|
||||
extern char *temp_name;
|
||||
extern char *find_input_file( const char *name, const char *parent );
|
||||
extern FILE *open_input_file( const char *path );
|
||||
extern void close_all_inputs(void);
|
||||
|
||||
#endif
|
||||
|
||||
+517
-486
File diff suppressed because it is too large
Load Diff
+1020
-1146
File diff suppressed because it is too large
Load Diff
+59
-64
@@ -20,13 +20,9 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "wine/port.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
@@ -65,9 +61,9 @@ static void write_stubdesc(int expr_eval_routines)
|
||||
print_proxy( "{0}, 0, 0, %s, 0,\n", expr_eval_routines ? "ExprEvalRoutines" : "0");
|
||||
print_proxy( "__MIDL_TypeFormatString.Format,\n");
|
||||
print_proxy( "1, /* -error bounds_check flag */\n");
|
||||
print_proxy( "0x%x, /* Ndr library version */\n", get_stub_mode() == MODE_Oif ? 0x50002 : 0x10001);
|
||||
print_proxy( "0x%x, /* Ndr library version */\n", interpreted_mode ? 0x50002 : 0x10001);
|
||||
print_proxy( "0,\n");
|
||||
print_proxy( "0x50100a4, /* MIDL Version 5.1.164 */\n");
|
||||
print_proxy( "0x50200ca, /* MIDL Version 5.2.202 */\n");
|
||||
print_proxy( "0,\n");
|
||||
print_proxy("%s,\n", list_empty(&user_type_list) ? "0" : "UserMarshalRoutines");
|
||||
print_proxy( "0, /* notify & notify_flag routine table */\n");
|
||||
@@ -87,19 +83,17 @@ static void init_proxy(const statement_list_t *stmts)
|
||||
error("Could not open %s for output\n", proxy_name);
|
||||
print_proxy( "/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n", PACKAGE_VERSION, input_name);
|
||||
print_proxy( "\n");
|
||||
#ifdef __REACTOS__
|
||||
print_proxy( "#define __midl_proxy\n\n");
|
||||
|
||||
print_proxy( "#ifdef __REACTOS__\n");
|
||||
print_proxy( "#define WIN32_NO_STATUS\n");
|
||||
print_proxy( "#define WIN32_LEAN_AND_MEAN\n");
|
||||
print_proxy( "#endif\n\n");
|
||||
|
||||
#else
|
||||
print_proxy( "#define __midl_proxy\n");
|
||||
#endif
|
||||
print_proxy( "#include \"objbase.h\"\n");
|
||||
print_proxy( "\n");
|
||||
print_proxy( "#ifndef DECLSPEC_HIDDEN\n");
|
||||
print_proxy( "#define DECLSPEC_HIDDEN\n");
|
||||
print_proxy( "#endif\n");
|
||||
print_proxy( "\n");
|
||||
}
|
||||
|
||||
static void clear_output_vars( const var_list_t *args )
|
||||
@@ -111,15 +105,15 @@ static void clear_output_vars( const var_list_t *args )
|
||||
{
|
||||
if (is_attr(arg->attrs, ATTR_IN)) continue;
|
||||
if (!is_attr(arg->attrs, ATTR_OUT)) continue;
|
||||
if (is_ptr(arg->type))
|
||||
if (is_ptr(arg->declspec.type))
|
||||
{
|
||||
if (type_get_type(type_pointer_get_ref(arg->type)) == TYPE_BASIC) continue;
|
||||
if (type_get_type(type_pointer_get_ref(arg->type)) == TYPE_ENUM) continue;
|
||||
if (type_get_type(type_pointer_get_ref_type(arg->declspec.type)) == TYPE_BASIC) continue;
|
||||
if (type_get_type(type_pointer_get_ref_type(arg->declspec.type)) == TYPE_ENUM) continue;
|
||||
}
|
||||
print_proxy( "if (%s) MIDL_memset( %s, 0, ", arg->name, arg->name );
|
||||
if (is_array(arg->type) && type_array_has_conformance(arg->type))
|
||||
if (is_array(arg->declspec.type) && type_array_has_conformance(arg->declspec.type))
|
||||
{
|
||||
write_expr( proxy, type_array_get_conformance(arg->type), 1, 1, NULL, NULL, "" );
|
||||
write_expr( proxy, type_array_get_conformance(arg->declspec.type), 1, 1, NULL, NULL, "" );
|
||||
fprintf( proxy, " * " );
|
||||
}
|
||||
fprintf( proxy, "sizeof( *%s ));\n", arg->name );
|
||||
@@ -153,7 +147,7 @@ static int need_delegation_indirect(const type_t *iface)
|
||||
static void free_variable( const var_t *arg, const char *local_var_prefix )
|
||||
{
|
||||
unsigned int type_offset = arg->typestring_offset;
|
||||
type_t *type = arg->type;
|
||||
type_t *type = arg->declspec.type;
|
||||
|
||||
write_parameter_conf_or_var_exprs(proxy, indent, local_var_prefix, PHASE_FREE, arg, FALSE);
|
||||
|
||||
@@ -197,20 +191,20 @@ static void proxy_free_variables( var_list_t *args, const char *local_var_prefix
|
||||
static void gen_proxy(type_t *iface, const var_t *func, int idx,
|
||||
unsigned int proc_offset)
|
||||
{
|
||||
var_t *retval = type_function_get_retval(func->type);
|
||||
int has_ret = !is_void(retval->type);
|
||||
var_t *retval = type_function_get_retval(func->declspec.type);
|
||||
int has_ret = !is_void(retval->declspec.type);
|
||||
int has_full_pointer = is_full_pointer_function(func);
|
||||
const char *callconv = get_attrp(func->type->attrs, ATTR_CALLCONV);
|
||||
const var_list_t *args = type_get_function_args(func->type);
|
||||
const char *callconv = get_attrp(func->declspec.type->attrs, ATTR_CALLCONV);
|
||||
const var_list_t *args = type_function_get_args(func->declspec.type);
|
||||
if (!callconv) callconv = "STDMETHODCALLTYPE";
|
||||
|
||||
indent = 0;
|
||||
if (is_interpreted_func( iface, func ))
|
||||
{
|
||||
if (get_stub_mode() == MODE_Oif && !is_callas( func->attrs )) return;
|
||||
write_type_decl_left(proxy, retval->type);
|
||||
if (!is_callas( func->attrs )) return;
|
||||
write_type_decl_left(proxy, &retval->declspec);
|
||||
print_proxy( " %s %s_%s_Proxy(\n", callconv, iface->name, get_name(func));
|
||||
write_args(proxy, args, iface->name, 1, TRUE);
|
||||
write_args(proxy, args, iface->name, 1, TRUE, NAME_DEFAULT);
|
||||
print_proxy( ")\n");
|
||||
write_client_call_routine( proxy, iface, func, "Object", proc_offset );
|
||||
return;
|
||||
@@ -225,9 +219,9 @@ static void gen_proxy(type_t *iface, const var_t *func, int idx,
|
||||
print_proxy( "}\n");
|
||||
print_proxy( "\n");
|
||||
|
||||
write_type_decl_left(proxy, retval->type);
|
||||
write_type_decl_left(proxy, &retval->declspec);
|
||||
print_proxy( " %s %s_%s_Proxy(\n", callconv, iface->name, get_name(func));
|
||||
write_args(proxy, args, iface->name, 1, TRUE);
|
||||
write_args(proxy, args, iface->name, 1, TRUE, NAME_DEFAULT);
|
||||
print_proxy( ")\n");
|
||||
print_proxy( "{\n");
|
||||
indent ++;
|
||||
@@ -235,12 +229,12 @@ static void gen_proxy(type_t *iface, const var_t *func, int idx,
|
||||
/* local variables */
|
||||
if (has_ret) {
|
||||
print_proxy( "%s", "" );
|
||||
write_type_decl(proxy, retval->type, retval->name);
|
||||
write_type_decl(proxy, &retval->declspec, retval->name);
|
||||
fprintf( proxy, ";\n" );
|
||||
}
|
||||
print_proxy( "RPC_MESSAGE _RpcMessage;\n" );
|
||||
if (has_ret) {
|
||||
if (decl_indirect(retval->type))
|
||||
if (decl_indirect(retval->declspec.type))
|
||||
print_proxy("void *_p_%s = &%s;\n", retval->name, retval->name);
|
||||
}
|
||||
print_proxy( "\n");
|
||||
@@ -252,7 +246,7 @@ static void gen_proxy(type_t *iface, const var_t *func, int idx,
|
||||
write_full_pointer_init(proxy, indent, func, FALSE);
|
||||
|
||||
/* FIXME: trace */
|
||||
clear_output_vars( type_get_function_args(func->type) );
|
||||
clear_output_vars( type_function_get_args(func->declspec.type) );
|
||||
|
||||
print_proxy( "RpcTryExcept\n" );
|
||||
print_proxy( "{\n" );
|
||||
@@ -285,9 +279,9 @@ static void gen_proxy(type_t *iface, const var_t *func, int idx,
|
||||
|
||||
if (has_ret)
|
||||
{
|
||||
if (decl_indirect(retval->type))
|
||||
if (decl_indirect(retval->declspec.type))
|
||||
print_proxy("MIDL_memset(&%s, 0, sizeof(%s));\n", retval->name, retval->name);
|
||||
else if (is_ptr(retval->type) || is_array(retval->type))
|
||||
else if (is_ptr(retval->declspec.type) || is_array(retval->declspec.type))
|
||||
print_proxy("%s = 0;\n", retval->name);
|
||||
write_remoting_arguments(proxy, indent, func, "", PASS_RETURN, PHASE_UNMARSHAL);
|
||||
}
|
||||
@@ -307,7 +301,8 @@ static void gen_proxy(type_t *iface, const var_t *func, int idx,
|
||||
print_proxy( "{\n" );
|
||||
if (has_ret) {
|
||||
indent++;
|
||||
proxy_free_variables( type_get_function_args(func->type), "" );
|
||||
proxy_free_variables( type_function_get_args(func->declspec.type), "" );
|
||||
print_proxy( "/* coverity[uninit_use_in_call:SUPPRESS] */\n" );
|
||||
print_proxy( "_RetVal = NdrProxyErrorHandler(RpcExceptionCode());\n" );
|
||||
indent--;
|
||||
}
|
||||
@@ -326,7 +321,7 @@ static void gen_stub(type_t *iface, const var_t *func, const char *cas,
|
||||
unsigned int proc_offset)
|
||||
{
|
||||
const var_t *arg;
|
||||
int has_ret = !is_void(type_function_get_rettype(func->type));
|
||||
int has_ret = !is_void(type_function_get_rettype(func->declspec.type));
|
||||
int has_full_pointer = is_full_pointer_function(func);
|
||||
|
||||
if (is_interpreted_func( iface, func )) return;
|
||||
@@ -395,10 +390,10 @@ static void gen_stub(type_t *iface, const var_t *func, const char *cas,
|
||||
else fprintf(proxy, "__frame->_This->lpVtbl->%s", get_name(func));
|
||||
fprintf(proxy, "(__frame->_This");
|
||||
|
||||
if (type_get_function_args(func->type))
|
||||
if (type_function_get_args(func->declspec.type))
|
||||
{
|
||||
LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->type), const var_t, entry )
|
||||
fprintf(proxy, ", %s__frame->%s", is_array(arg->type) && !type_array_is_decl_as_ptr(arg->type) ? "*" :"" , arg->name);
|
||||
LIST_FOR_EACH_ENTRY( arg, type_function_get_args(func->declspec.type), const var_t, entry )
|
||||
fprintf(proxy, ", %s__frame->%s", is_array(arg->declspec.type) && !type_array_is_decl_as_ptr(arg->declspec.type) ? "*" :"" , arg->name);
|
||||
}
|
||||
fprintf(proxy, ");\n");
|
||||
fprintf(proxy, "\n");
|
||||
@@ -407,7 +402,7 @@ static void gen_stub(type_t *iface, const var_t *func, const char *cas,
|
||||
|
||||
write_remoting_arguments(proxy, indent, func, "__frame->", PASS_OUT, PHASE_BUFFERSIZE);
|
||||
|
||||
if (!is_void(type_function_get_rettype(func->type)))
|
||||
if (!is_void(type_function_get_rettype(func->declspec.type)))
|
||||
write_remoting_arguments(proxy, indent, func, "__frame->", PASS_RETURN, PHASE_BUFFERSIZE);
|
||||
|
||||
print_proxy("NdrStubGetBuffer(This, _pRpcChannelBuffer, &__frame->_StubMsg);\n");
|
||||
@@ -416,7 +411,7 @@ static void gen_stub(type_t *iface, const var_t *func, const char *cas,
|
||||
fprintf(proxy, "\n");
|
||||
|
||||
/* marshall the return value */
|
||||
if (!is_void(type_function_get_rettype(func->type)))
|
||||
if (!is_void(type_function_get_rettype(func->declspec.type)))
|
||||
write_remoting_arguments(proxy, indent, func, "__frame->", PASS_RETURN, PHASE_MARSHAL);
|
||||
|
||||
indent--;
|
||||
@@ -438,16 +433,16 @@ static void gen_stub(type_t *iface, const var_t *func, const char *cas,
|
||||
|
||||
static void gen_stub_thunk( type_t *iface, const var_t *func, unsigned int proc_offset )
|
||||
{
|
||||
int has_ret = !is_void( type_function_get_rettype( func->type ));
|
||||
int has_ret = !is_void( type_function_get_rettype( func->declspec.type ));
|
||||
const var_t *arg, *callas = is_callas( func->attrs );
|
||||
const var_list_t *args = type_get_function_args( func->type );
|
||||
const var_list_t *args = type_function_get_args( func->declspec.type );
|
||||
|
||||
indent = 0;
|
||||
print_proxy( "void __RPC_API %s_%s_Thunk( PMIDL_STUB_MESSAGE pStubMsg )\n",
|
||||
iface->name, get_name(func) );
|
||||
print_proxy( "{\n");
|
||||
indent++;
|
||||
write_func_param_struct( proxy, iface, func->type,
|
||||
write_func_param_struct( proxy, iface, func->declspec.type,
|
||||
"*pParamStruct = (struct _PARAM_STRUCT *)pStubMsg->StackTop", has_ret );
|
||||
print_proxy( "%s%s_%s_Stub( pParamStruct->This",
|
||||
has_ret ? "pParamStruct->_RetVal = " : "", iface->name, callas->name );
|
||||
@@ -477,7 +472,7 @@ int count_methods(const type_t *iface)
|
||||
return count;
|
||||
}
|
||||
|
||||
static const statement_t * get_callas_source(const type_t * iface, const var_t * def)
|
||||
const statement_t *get_callas_source(const type_t *iface, const var_t *def)
|
||||
{
|
||||
const statement_t * source;
|
||||
STATEMENTS_FOR_EACH_FUNC( source, type_iface_get_stmts(iface)) {
|
||||
@@ -577,7 +572,7 @@ static int write_stub_methods(type_t *iface, int skip)
|
||||
if (i) fprintf(proxy,",\n");
|
||||
if (skip || missing) print_proxy("STUB_FORWARDING_FUNCTION");
|
||||
else if (is_interpreted_func( iface, func ))
|
||||
print_proxy( "(PRPC_STUB_FUNCTION)%s", get_stub_mode() == MODE_Oif ? "NdrStubCall2" : "NdrStubCall" );
|
||||
print_proxy( "(PRPC_STUB_FUNCTION)%s", interpreted_mode ? "NdrStubCall2" : "NdrStubCall" );
|
||||
else print_proxy( "%s_%s_Stub", iface->name, fname);
|
||||
i++;
|
||||
}
|
||||
@@ -628,14 +623,14 @@ static void write_proxy(type_t *iface, unsigned int *proc_offset)
|
||||
if (!is_local(func->attrs)) {
|
||||
const var_t *cas = is_callas(func->attrs);
|
||||
const char *cname = cas ? cas->name : NULL;
|
||||
int idx = func->type->details.function->idx;
|
||||
int idx = func->func_idx;
|
||||
if (cname) {
|
||||
const statement_t *stmt2;
|
||||
STATEMENTS_FOR_EACH_FUNC(stmt2, type_iface_get_stmts(iface)) {
|
||||
const var_t *m = stmt2->u.var;
|
||||
if (!strcmp(m->name, cname))
|
||||
{
|
||||
idx = m->type->details.function->idx;
|
||||
idx = m->func_idx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -669,7 +664,7 @@ static void write_proxy(type_t *iface, unsigned int *proc_offset)
|
||||
print_proxy( "};\n\n" );
|
||||
|
||||
/* proxy info */
|
||||
if (get_stub_mode() == MODE_Oif)
|
||||
if (interpreted_mode)
|
||||
{
|
||||
print_proxy( "static const MIDL_STUBLESS_PROXY_INFO %s_ProxyInfo =\n", iface->name );
|
||||
print_proxy( "{\n" );
|
||||
@@ -686,13 +681,13 @@ static void write_proxy(type_t *iface, unsigned int *proc_offset)
|
||||
|
||||
/* proxy vtable */
|
||||
print_proxy( "static %sCINTERFACE_PROXY_VTABLE(%d) _%sProxyVtbl =\n",
|
||||
(get_stub_mode() != MODE_Os || need_delegation_indirect(iface)) ? "" : "const ",
|
||||
(interpreted_mode || need_delegation_indirect(iface)) ? "" : "const ",
|
||||
count, iface->name);
|
||||
print_proxy( "{\n");
|
||||
indent++;
|
||||
print_proxy( "{\n");
|
||||
indent++;
|
||||
if (get_stub_mode() == MODE_Oif) print_proxy( "&%s_ProxyInfo,\n", iface->name );
|
||||
if (interpreted_mode) print_proxy( "&%s_ProxyInfo,\n", iface->name );
|
||||
print_proxy( "&IID_%s,\n", iface->name);
|
||||
indent--;
|
||||
print_proxy( "},\n");
|
||||
@@ -767,7 +762,7 @@ static void write_proxy(type_t *iface, unsigned int *proc_offset)
|
||||
print_proxy( "{\n");
|
||||
indent++;
|
||||
print_proxy( "%s_%s\n",
|
||||
iface->details.iface->async_iface == iface ? "CStdAsyncStubBuffer" : "CStdStubBuffer",
|
||||
type_iface_get_async_iface(iface) == iface ? "CStdAsyncStubBuffer" : "CStdStubBuffer",
|
||||
need_delegation_indirect(iface) ? "DELEGATING_METHODS" : "METHODS");
|
||||
indent--;
|
||||
print_proxy( "}\n");
|
||||
@@ -820,7 +815,7 @@ int need_inline_stubs(const type_t *iface)
|
||||
{
|
||||
const statement_t *stmt;
|
||||
|
||||
if (get_stub_mode() == MODE_Os) return 1;
|
||||
if (!interpreted_mode) return 1;
|
||||
|
||||
STATEMENTS_FOR_EACH_FUNC( stmt, type_iface_get_stmts(iface) )
|
||||
{
|
||||
@@ -836,7 +831,7 @@ static int need_proxy_and_inline_stubs(const type_t *iface)
|
||||
const statement_t *stmt;
|
||||
|
||||
if (!need_proxy( iface )) return 0;
|
||||
if (get_stub_mode() == MODE_Os) return 1;
|
||||
if (!interpreted_mode) return 1;
|
||||
|
||||
STATEMENTS_FOR_EACH_FUNC( stmt, type_iface_get_stmts(iface) )
|
||||
{
|
||||
@@ -868,8 +863,8 @@ static void write_proxy_stmts(const statement_list_t *stmts, unsigned int *proc_
|
||||
if (need_proxy(iface))
|
||||
{
|
||||
write_proxy(iface, proc_offset);
|
||||
if (iface->details.iface->async_iface)
|
||||
write_proxy(iface->details.iface->async_iface, proc_offset);
|
||||
if (type_iface_get_async_iface(iface))
|
||||
write_proxy(type_iface_get_async_iface(iface), proc_offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -879,9 +874,9 @@ static int cmp_iid( const void *ptr1, const void *ptr2 )
|
||||
{
|
||||
const type_t * const *iface1 = ptr1;
|
||||
const type_t * const *iface2 = ptr2;
|
||||
const UUID *uuid1 = get_attrp( (*iface1)->attrs, ATTR_UUID );
|
||||
const UUID *uuid2 = get_attrp( (*iface2)->attrs, ATTR_UUID );
|
||||
return memcmp( uuid1, uuid2, sizeof(UUID) );
|
||||
const struct uuid *uuid1 = get_attrp( (*iface1)->attrs, ATTR_UUID );
|
||||
const struct uuid *uuid2 = get_attrp( (*iface2)->attrs, ATTR_UUID );
|
||||
return memcmp( uuid1, uuid2, sizeof(*uuid1) );
|
||||
}
|
||||
|
||||
static void build_iface_list( const statement_list_t *stmts, type_t **ifaces[], int *count )
|
||||
@@ -898,9 +893,9 @@ static void build_iface_list( const statement_list_t *stmts, type_t **ifaces[],
|
||||
{
|
||||
*ifaces = xrealloc( *ifaces, (*count + 1) * sizeof(**ifaces) );
|
||||
(*ifaces)[(*count)++] = iface;
|
||||
if (iface->details.iface->async_iface)
|
||||
if (type_iface_get_async_iface(iface))
|
||||
{
|
||||
iface = iface->details.iface->async_iface;
|
||||
iface = type_iface_get_async_iface(iface);
|
||||
*ifaces = xrealloc( *ifaces, (*count + 1) * sizeof(**ifaces) );
|
||||
(*ifaces)[(*count)++] = iface;
|
||||
}
|
||||
@@ -930,10 +925,10 @@ static void write_proxy_routines(const statement_list_t *stmts)
|
||||
const type_t * delegate_to;
|
||||
|
||||
print_proxy( "#ifndef __REDQ_RPCPROXY_H_VERSION__\n");
|
||||
print_proxy( "#define __REQUIRED_RPCPROXY_H_VERSION__ %u\n", get_stub_mode() == MODE_Oif ? 475 : 440);
|
||||
print_proxy( "#define __REQUIRED_RPCPROXY_H_VERSION__ %u\n", interpreted_mode ? 475 : 440);
|
||||
print_proxy( "#endif\n");
|
||||
print_proxy( "\n");
|
||||
if (get_stub_mode() == MODE_Oif) print_proxy( "#define USE_STUBLESS_PROXY\n");
|
||||
if (interpreted_mode) print_proxy( "#define USE_STUBLESS_PROXY\n");
|
||||
print_proxy( "#include \"rpcproxy.h\"\n");
|
||||
print_proxy( "#ifndef __RPCPROXY_H_VERSION__\n");
|
||||
print_proxy( "#error This code needs a newer version of rpcproxy.h\n");
|
||||
@@ -1037,10 +1032,10 @@ static void write_proxy_routines(const statement_list_t *stmts)
|
||||
fprintf(proxy, "}\n");
|
||||
fprintf(proxy, "\n");
|
||||
|
||||
table_version = get_stub_mode() == MODE_Oif ? 2 : 1;
|
||||
table_version = interpreted_mode ? 2 : 1;
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if (interfaces[i]->details.iface->async_iface != interfaces[i]) continue;
|
||||
if (type_iface_get_async_iface(interfaces[i]) != interfaces[i]) continue;
|
||||
if (table_version != 6)
|
||||
{
|
||||
fprintf(proxy, "static const IID *_AsyncInterfaceTable[] =\n");
|
||||
@@ -1057,7 +1052,7 @@ static void write_proxy_routines(const statement_list_t *stmts)
|
||||
fprintf(proxy, "\n");
|
||||
}
|
||||
|
||||
fprintf(proxy, "const ExtendedProxyFileInfo %s_ProxyFileInfo DECLSPEC_HIDDEN =\n", file_id);
|
||||
fprintf(proxy, "const ExtendedProxyFileInfo %s_ProxyFileInfo =\n", file_id);
|
||||
fprintf(proxy, "{\n");
|
||||
fprintf(proxy, " (const PCInterfaceProxyVtblList*)_%s_ProxyVtblList,\n", file_id);
|
||||
fprintf(proxy, " (const PCInterfaceStubVtblList*)_%s_StubVtblList,\n", file_id);
|
||||
|
||||
+80
-44
@@ -19,13 +19,9 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "wine/port.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
@@ -38,13 +34,14 @@
|
||||
|
||||
static int indent;
|
||||
|
||||
static const char *format_uuid( const UUID *uuid )
|
||||
static const char *format_uuid( const struct uuid *uuid )
|
||||
{
|
||||
static char buffer[40];
|
||||
sprintf( buffer, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
|
||||
uuid->Data1, uuid->Data2, uuid->Data3,
|
||||
uuid->Data4[0], uuid->Data4[1], uuid->Data4[2], uuid->Data4[3],
|
||||
uuid->Data4[4], uuid->Data4[5], uuid->Data4[6], uuid->Data4[7] );
|
||||
snprintf( buffer, sizeof(buffer),
|
||||
"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
|
||||
uuid->Data1, uuid->Data2, uuid->Data3,
|
||||
uuid->Data4[0], uuid->Data4[1], uuid->Data4[2], uuid->Data4[3],
|
||||
uuid->Data4[4], uuid->Data4[5], uuid->Data4[6], uuid->Data4[7] );
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@@ -80,8 +77,8 @@ static const type_t *find_ps_factory( const statement_list_t *stmts )
|
||||
|
||||
static void write_interface( const type_t *iface, const type_t *ps_factory )
|
||||
{
|
||||
const UUID *uuid = get_attrp( iface->attrs, ATTR_UUID );
|
||||
const UUID *ps_uuid = get_attrp( ps_factory->attrs, ATTR_UUID );
|
||||
const struct uuid *uuid = get_attrp( iface->attrs, ATTR_UUID );
|
||||
const struct uuid *ps_uuid = get_attrp( ps_factory->attrs, ATTR_UUID );
|
||||
|
||||
if (!uuid) return;
|
||||
if (!is_object( iface )) return;
|
||||
@@ -113,14 +110,12 @@ static void write_interfaces( const statement_list_t *stmts, const type_t *ps_fa
|
||||
|
||||
static void write_typelib_interface( const type_t *iface, const typelib_t *typelib )
|
||||
{
|
||||
const UUID *typelib_uuid = get_attrp( typelib->attrs, ATTR_UUID );
|
||||
const UUID *uuid = get_attrp( iface->attrs, ATTR_UUID );
|
||||
const struct uuid *typelib_uuid = get_attrp( typelib->attrs, ATTR_UUID );
|
||||
const struct uuid *uuid = get_attrp( iface->attrs, ATTR_UUID );
|
||||
unsigned int version = get_attrv( typelib->attrs, ATTR_VERSION );
|
||||
|
||||
if (!uuid) return;
|
||||
if (!is_object( iface )) return;
|
||||
if (!is_attr( iface->attrs, ATTR_OLEAUTOMATION ) && !is_attr( iface->attrs, ATTR_DISPINTERFACE ))
|
||||
return;
|
||||
put_str( indent, "'%s' = s '%s'\n", format_uuid( uuid ), iface->name );
|
||||
put_str( indent, "{\n" );
|
||||
indent++;
|
||||
@@ -137,18 +132,15 @@ static void write_typelib_interface( const type_t *iface, const typelib_t *typel
|
||||
|
||||
static void write_typelib_interfaces( const typelib_t *typelib )
|
||||
{
|
||||
const statement_t *stmt;
|
||||
unsigned int i;
|
||||
|
||||
if (typelib->stmts) LIST_FOR_EACH_ENTRY( stmt, typelib->stmts, const statement_t, entry )
|
||||
{
|
||||
if (stmt->type == STMT_TYPE && type_get_type( stmt->u.type ) == TYPE_INTERFACE)
|
||||
write_typelib_interface( stmt->u.type, typelib );
|
||||
}
|
||||
for (i = 0; i < typelib->reg_iface_count; ++i)
|
||||
write_typelib_interface( typelib->reg_ifaces[i], typelib );
|
||||
}
|
||||
|
||||
static int write_coclass( const type_t *class, const typelib_t *typelib )
|
||||
{
|
||||
const UUID *uuid = get_attrp( class->attrs, ATTR_UUID );
|
||||
const struct uuid *uuid = get_attrp( class->attrs, ATTR_UUID );
|
||||
const char *descr = get_attrp( class->attrs, ATTR_HELPSTRING );
|
||||
const char *progid = get_attrp( class->attrs, ATTR_PROGID );
|
||||
const char *vi_progid = get_attrp( class->attrs, ATTR_VIPROGID );
|
||||
@@ -166,7 +158,7 @@ static int write_coclass( const type_t *class, const typelib_t *typelib )
|
||||
if (progid) put_str( indent, "ProgId = s '%s'\n", progid );
|
||||
if (typelib)
|
||||
{
|
||||
const UUID *typelib_uuid = get_attrp( typelib->attrs, ATTR_UUID );
|
||||
const struct uuid *typelib_uuid = get_attrp( typelib->attrs, ATTR_UUID );
|
||||
put_str( indent, "TypeLib = s '%s'\n", format_uuid( typelib_uuid ));
|
||||
if (!version) version = get_attrv( typelib->attrs, ATTR_VERSION );
|
||||
}
|
||||
@@ -190,9 +182,26 @@ static void write_coclasses( const statement_list_t *stmts, const typelib_t *typ
|
||||
}
|
||||
}
|
||||
|
||||
static void write_runtimeclasses_registry( const statement_list_t *stmts )
|
||||
{
|
||||
const statement_t *stmt;
|
||||
const type_t *type;
|
||||
|
||||
if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
|
||||
{
|
||||
if (stmt->type != STMT_TYPE) continue;
|
||||
if (type_get_type((type = stmt->u.type)) != TYPE_RUNTIMECLASS) continue;
|
||||
if (!get_attrp(type->attrs, ATTR_ACTIVATABLE) && !get_attrp(type->attrs, ATTR_STATIC)) continue;
|
||||
put_str( indent, "ForceRemove %s\n", format_namespace( type->namespace, "", ".", type->name, NULL ) );
|
||||
put_str( indent++, "{\n" );
|
||||
put_str( indent, "val 'DllPath' = s '%%MODULE%%'\n" );
|
||||
put_str( --indent, "}\n" );
|
||||
}
|
||||
}
|
||||
|
||||
static int write_progid( const type_t *class )
|
||||
{
|
||||
const UUID *uuid = get_attrp( class->attrs, ATTR_UUID );
|
||||
const struct uuid *uuid = get_attrp( class->attrs, ATTR_UUID );
|
||||
const char *descr = get_attrp( class->attrs, ATTR_HELPSTRING );
|
||||
const char *progid = get_attrp( class->attrs, ATTR_PROGID );
|
||||
const char *vi_progid = get_attrp( class->attrs, ATTR_VIPROGID );
|
||||
@@ -241,22 +250,47 @@ void write_regscript( const statement_list_t *stmts )
|
||||
|
||||
init_output_buffer();
|
||||
|
||||
put_str( indent, "HKCR\n" );
|
||||
put_str( indent++, "{\n" );
|
||||
if (winrt_mode)
|
||||
{
|
||||
put_str( indent, "HKLM\n" );
|
||||
put_str( indent++, "{\n" );
|
||||
put_str( indent, "NoRemove Software\n" );
|
||||
put_str( indent++, "{\n" );
|
||||
put_str( indent, "NoRemove Microsoft\n" );
|
||||
put_str( indent++, "{\n" );
|
||||
put_str( indent, "NoRemove WindowsRuntime\n" );
|
||||
put_str( indent++, "{\n" );
|
||||
put_str( indent, "NoRemove ActivatableClassId\n" );
|
||||
put_str( indent++, "{\n" );
|
||||
write_runtimeclasses_registry( stmts );
|
||||
put_str( --indent, "}\n" );
|
||||
put_str( --indent, "}\n" );
|
||||
put_str( --indent, "}\n" );
|
||||
put_str( --indent, "}\n" );
|
||||
put_str( --indent, "}\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
put_str( indent, "HKCR\n" );
|
||||
put_str( indent++, "{\n" );
|
||||
|
||||
put_str( indent, "NoRemove Interface\n" );
|
||||
put_str( indent++, "{\n" );
|
||||
ps_factory = find_ps_factory( stmts );
|
||||
if (ps_factory) write_interfaces( stmts, ps_factory );
|
||||
put_str( --indent, "}\n" );
|
||||
ps_factory = find_ps_factory( stmts );
|
||||
if (ps_factory)
|
||||
{
|
||||
put_str( indent, "NoRemove Interface\n" );
|
||||
put_str( indent++, "{\n" );
|
||||
write_interfaces( stmts, ps_factory );
|
||||
put_str( --indent, "}\n" );
|
||||
}
|
||||
|
||||
put_str( indent, "NoRemove CLSID\n" );
|
||||
put_str( indent++, "{\n" );
|
||||
write_coclasses( stmts, NULL );
|
||||
put_str( --indent, "}\n" );
|
||||
put_str( indent, "NoRemove CLSID\n" );
|
||||
put_str( indent++, "{\n" );
|
||||
write_coclasses( stmts, NULL );
|
||||
put_str( --indent, "}\n" );
|
||||
|
||||
write_progids( stmts );
|
||||
put_str( --indent, "}\n" );
|
||||
write_progids( stmts );
|
||||
put_str( --indent, "}\n" );
|
||||
}
|
||||
|
||||
if (strendswith( regscript_name, ".res" )) /* create a binary resource file */
|
||||
{
|
||||
@@ -286,7 +320,12 @@ void write_typelib_regscript( const statement_list_t *stmts )
|
||||
if (count && !strendswith( typelib_name, ".res" ))
|
||||
error( "Cannot store multiple typelibs into %s\n", typelib_name );
|
||||
else
|
||||
create_msft_typelib( stmt->u.lib );
|
||||
{
|
||||
if (old_typelib)
|
||||
create_sltg_typelib( stmt->u.lib );
|
||||
else
|
||||
create_msft_typelib( stmt->u.lib );
|
||||
}
|
||||
count++;
|
||||
}
|
||||
if (count && strendswith( typelib_name, ".res" )) flush_output_resources( typelib_name );
|
||||
@@ -294,7 +333,7 @@ void write_typelib_regscript( const statement_list_t *stmts )
|
||||
|
||||
void output_typelib_regscript( const typelib_t *typelib )
|
||||
{
|
||||
const UUID *typelib_uuid = get_attrp( typelib->attrs, ATTR_UUID );
|
||||
const struct uuid *typelib_uuid = get_attrp( typelib->attrs, ATTR_UUID );
|
||||
const char *descr = get_attrp( typelib->attrs, ATTR_HELPSTRING );
|
||||
const expr_t *lcid_expr = get_attrp( typelib->attrs, ATTR_LIBLCID );
|
||||
unsigned int version = get_attrv( typelib->attrs, ATTR_VERSION );
|
||||
@@ -320,11 +359,8 @@ void output_typelib_regscript( const typelib_t *typelib )
|
||||
expr = get_attrp( typelib->attrs, ATTR_ID );
|
||||
if (expr)
|
||||
{
|
||||
sprintf(id_part, "\\%d", expr->cval);
|
||||
#ifndef __REACTOS__
|
||||
resname = xmalloc( strlen(typelib_name) + 20 );
|
||||
sprintf(resname, "%s\\%d", typelib_name, expr->cval);
|
||||
#endif
|
||||
snprintf(id_part, sizeof(id_part), "\\%d", expr->cval);
|
||||
resname = strmake("%s\\%d", typelib_name, expr->cval);
|
||||
}
|
||||
put_str( indent, "'%x' { %s = s '%%MODULE%%%s' }\n",
|
||||
lcid_expr ? lcid_expr->cval : 0, pointer_size == 8 ? "win64" : "win32", id_part );
|
||||
|
||||
+33
-28
@@ -19,13 +19,9 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "wine/port.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
@@ -55,6 +51,7 @@ static void write_function_stub(const type_t *iface, const var_t *func, unsigned
|
||||
unsigned char explicit_fc, implicit_fc;
|
||||
int has_full_pointer = is_full_pointer_function(func);
|
||||
const var_t *handle_var = get_func_handle_var( iface, func, &explicit_fc, &implicit_fc );
|
||||
type_t *ret_type = type_function_get_rettype(func->declspec.type);
|
||||
|
||||
if (is_interpreted_func( iface, func )) return;
|
||||
|
||||
@@ -72,10 +69,12 @@ static void write_function_stub(const type_t *iface, const var_t *func, unsigned
|
||||
print_server("static void __finally_%s_%s(", iface->name, get_name(func));
|
||||
fprintf(server," struct __frame_%s_%s *__frame )\n{\n", iface->name, get_name(func));
|
||||
|
||||
if (interpreted_mode) print_server("NdrCorrelationFree(&__frame->_StubMsg);\n");
|
||||
|
||||
indent++;
|
||||
write_remoting_arguments(server, indent, func, "__frame->", PASS_OUT, PHASE_FREE);
|
||||
|
||||
if (!is_void(type_function_get_rettype(func->type)))
|
||||
if (!is_void(ret_type))
|
||||
write_remoting_arguments(server, indent, func, "__frame->", PASS_RETURN, PHASE_FREE);
|
||||
|
||||
if (has_full_pointer)
|
||||
@@ -90,6 +89,7 @@ static void write_function_stub(const type_t *iface, const var_t *func, unsigned
|
||||
fprintf(server, "{\n");
|
||||
indent++;
|
||||
print_server("struct __frame_%s_%s __f, * const __frame = &__f;\n", iface->name, get_name(func));
|
||||
if (interpreted_mode) print_server("ULONG _NdrCorrCache[256];\n");
|
||||
if (has_out_arg_or_return(func)) print_server("RPC_STATUS _Status;\n");
|
||||
fprintf(server, "\n");
|
||||
|
||||
@@ -116,11 +116,13 @@ static void write_function_stub(const type_t *iface, const var_t *func, unsigned
|
||||
print_server("RpcTryExcept\n");
|
||||
print_server("{\n");
|
||||
indent++;
|
||||
if (interpreted_mode)
|
||||
print_server("NdrCorrelationInitialize(&__frame->_StubMsg, _NdrCorrCache, sizeof(_NdrCorrCache), 0);\n" );
|
||||
|
||||
if (has_full_pointer)
|
||||
write_full_pointer_init(server, indent, func, TRUE);
|
||||
|
||||
if (type_get_function_args(func->type))
|
||||
if (type_function_get_args(func->declspec.type))
|
||||
{
|
||||
print_server("if ((_pRpcMessage->DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION)\n");
|
||||
indent++;
|
||||
@@ -154,35 +156,42 @@ static void write_function_stub(const type_t *iface, const var_t *func, unsigned
|
||||
assign_stub_out_args(server, indent, func, "__frame->");
|
||||
|
||||
/* Call the real server function */
|
||||
print_server("%s%s%s",
|
||||
is_void(type_function_get_rettype(func->type)) ? "" : "__frame->_RetVal = ",
|
||||
prefix_server, get_name(func));
|
||||
if (is_context_handle(ret_type))
|
||||
{
|
||||
print_server("__frame->_RetVal = NDRSContextUnmarshall((char*)0, _pRpcMessage->DataRepresentation);\n");
|
||||
print_server("*((");
|
||||
write_type_decl(server, type_function_get_ret(func->declspec.type), NULL);
|
||||
fprintf(server, "*)NDRSContextValue(__frame->_RetVal)) = ");
|
||||
}
|
||||
else
|
||||
print_server("%s", is_void(ret_type) ? "" : "__frame->_RetVal = ");
|
||||
fprintf(server, "%s%s", prefix_server, get_name(func));
|
||||
|
||||
if (type_get_function_args(func->type))
|
||||
if (type_function_get_args(func->declspec.type))
|
||||
{
|
||||
int first_arg = 1;
|
||||
|
||||
fprintf(server, "(\n");
|
||||
indent++;
|
||||
LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry )
|
||||
LIST_FOR_EACH_ENTRY( var, type_function_get_args(func->declspec.type), const var_t, entry )
|
||||
{
|
||||
if (first_arg)
|
||||
first_arg = 0;
|
||||
else
|
||||
fprintf(server, ",\n");
|
||||
if (is_context_handle(var->type))
|
||||
if (is_context_handle(var->declspec.type))
|
||||
{
|
||||
/* if the context_handle attribute appears in the chain of types
|
||||
* without pointers being followed, then the context handle must
|
||||
* be direct, otherwise it is a pointer */
|
||||
const char *ch_ptr = is_aliaschain_attr(var->type, ATTR_CONTEXTHANDLE) ? "*" : "";
|
||||
const char *ch_ptr = is_aliaschain_attr(var->declspec.type, ATTR_CONTEXTHANDLE) ? "*" : "";
|
||||
print_server("(");
|
||||
write_type_decl_left(server, var->type);
|
||||
write_type_decl_left(server, &var->declspec);
|
||||
fprintf(server, ")%sNDRSContextValue(__frame->%s)", ch_ptr, var->name);
|
||||
}
|
||||
else
|
||||
{
|
||||
print_server("%s__frame->%s", is_array(var->type) && !type_array_is_decl_as_ptr(var->type) ? "*" : "", var->name);
|
||||
print_server("%s__frame->%s", is_array(var->declspec.type) && !type_array_is_decl_as_ptr(var->declspec.type) ? "*" : "", var->name);
|
||||
}
|
||||
}
|
||||
fprintf(server, ");\n");
|
||||
@@ -197,7 +206,7 @@ static void write_function_stub(const type_t *iface, const var_t *func, unsigned
|
||||
{
|
||||
write_remoting_arguments(server, indent, func, "__frame->", PASS_OUT, PHASE_BUFFERSIZE);
|
||||
|
||||
if (!is_void(type_function_get_rettype(func->type)))
|
||||
if (!is_void(ret_type))
|
||||
write_remoting_arguments(server, indent, func, "__frame->", PASS_RETURN, PHASE_BUFFERSIZE);
|
||||
|
||||
print_server("_pRpcMessage->BufferLength = __frame->_StubMsg.BufferLength;\n");
|
||||
@@ -216,7 +225,7 @@ static void write_function_stub(const type_t *iface, const var_t *func, unsigned
|
||||
write_remoting_arguments(server, indent, func, "__frame->", PASS_OUT, PHASE_MARSHAL);
|
||||
|
||||
/* marshall the return value */
|
||||
if (!is_void(type_function_get_rettype(func->type)))
|
||||
if (!is_void(ret_type))
|
||||
write_remoting_arguments(server, indent, func, "__frame->", PASS_RETURN, PHASE_MARSHAL);
|
||||
|
||||
indent--;
|
||||
@@ -269,7 +278,7 @@ static void write_dispatchtable(type_t *iface)
|
||||
{
|
||||
var_t *func = stmt->u.var;
|
||||
if (is_interpreted_func( iface, func ))
|
||||
print_server("%s,\n", get_stub_mode() == MODE_Oif ? "NdrServerCall2" : "NdrServerCall");
|
||||
print_server("NdrServerCall2,\n");
|
||||
else
|
||||
print_server("%s_%s,\n", iface->name, get_name(func));
|
||||
method_count++;
|
||||
@@ -299,7 +308,7 @@ static void write_routinetable(type_t *iface)
|
||||
{
|
||||
var_t *func = stmt->u.var;
|
||||
if (is_local( func->attrs )) continue;
|
||||
print_server( "(SERVER_ROUTINE)%s%s,\n", prefix_server, get_name(func));
|
||||
print_server( "(void *)%s%s,\n", prefix_server, get_name(func));
|
||||
}
|
||||
indent--;
|
||||
print_server( "};\n\n" );
|
||||
@@ -376,9 +385,9 @@ static void write_stubdescriptor(type_t *iface, int expr_eval_routines)
|
||||
print_server("0,\n");
|
||||
print_server("__MIDL_TypeFormatString.Format,\n");
|
||||
print_server("1, /* -error bounds_check flag */\n");
|
||||
print_server("0x%x, /* Ndr library version */\n", get_stub_mode() == MODE_Oif ? 0x50002 : 0x10001);
|
||||
print_server("0x%x, /* Ndr library version */\n", interpreted_mode ? 0x50002 : 0x10001);
|
||||
print_server("0,\n");
|
||||
print_server("0x50100a4, /* MIDL Version 5.1.164 */\n");
|
||||
print_server("0x50200ca, /* MIDL Version 5.2.202 */\n");
|
||||
print_server("0,\n");
|
||||
print_server("%s,\n", list_empty(&user_type_list) ? "0" : "UserMarshalRoutines");
|
||||
print_server("0, /* notify & notify_flag routine table */\n");
|
||||
@@ -395,7 +404,7 @@ static void write_stubdescriptor(type_t *iface, int expr_eval_routines)
|
||||
static void write_serverinterfacedecl(type_t *iface)
|
||||
{
|
||||
unsigned int ver = get_attrv(iface->attrs, ATTR_VERSION);
|
||||
UUID *uuid = get_attrp(iface->attrs, ATTR_UUID);
|
||||
struct uuid *uuid = get_attrp(iface->attrs, ATTR_UUID);
|
||||
const str_list_t *endpoints = get_attrp(iface->attrs, ATTR_ENDPOINT);
|
||||
|
||||
if (endpoints) write_endpoints( server, iface->name, endpoints );
|
||||
@@ -429,10 +438,10 @@ static void write_serverinterfacedecl(type_t *iface)
|
||||
indent--;
|
||||
print_server("};\n");
|
||||
if (old_names)
|
||||
print_server("RPC_IF_HANDLE %s_ServerIfHandle DECLSPEC_HIDDEN = (RPC_IF_HANDLE)& %s___RpcServerInterface;\n",
|
||||
print_server("RPC_IF_HANDLE %s_ServerIfHandle = (RPC_IF_HANDLE)& %s___RpcServerInterface;\n",
|
||||
iface->name, iface->name);
|
||||
else
|
||||
print_server("RPC_IF_HANDLE %s%s_v%d_%d_s_ifspec DECLSPEC_HIDDEN = (RPC_IF_HANDLE)& %s___RpcServerInterface;\n",
|
||||
print_server("RPC_IF_HANDLE %s%s_v%d_%d_s_ifspec = (RPC_IF_HANDLE)& %s___RpcServerInterface;\n",
|
||||
prefix_server, iface->name, MAJORVERSION(ver), MINORVERSION(ver), iface->name);
|
||||
fprintf(server, "\n");
|
||||
}
|
||||
@@ -449,10 +458,6 @@ static void init_server(void)
|
||||
print_server("#include <string.h>\n");
|
||||
fprintf(server, "\n");
|
||||
print_server("#include \"%s\"\n", header_name);
|
||||
print_server("\n");
|
||||
print_server( "#ifndef DECLSPEC_HIDDEN\n");
|
||||
print_server( "#define DECLSPEC_HIDDEN\n");
|
||||
print_server( "#endif\n");
|
||||
print_server( "\n");
|
||||
}
|
||||
|
||||
|
||||
+895
-651
File diff suppressed because it is too large
Load Diff
@@ -97,7 +97,6 @@ int is_full_pointer_function(const var_t *func);
|
||||
void write_full_pointer_init(FILE *file, int indent, const var_t *func, int is_server);
|
||||
void write_full_pointer_free(FILE *file, int indent, const var_t *func);
|
||||
unsigned char get_basic_fc(const type_t *type);
|
||||
unsigned char get_pointer_fc(const type_t *type, const attr_list_t *attrs, int toplevel_param);
|
||||
unsigned char get_struct_fc(const type_t *type);
|
||||
enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *attrs, unsigned int flags);
|
||||
unsigned int type_memsize_and_alignment(const type_t *t, unsigned int *align);
|
||||
|
||||
+110
-90
@@ -20,27 +20,23 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "wine/port.h"
|
||||
#include "wine/wpp.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "widl.h"
|
||||
#ifdef __REACTOS__
|
||||
#include <typedefs.h>
|
||||
#include <pecoff.h>
|
||||
#else
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#endif
|
||||
|
||||
#include "widl.h"
|
||||
#include "utils.h"
|
||||
#include "wpp_private.h"
|
||||
#include "parser.h"
|
||||
#include "header.h"
|
||||
#include "typelib.h"
|
||||
@@ -71,7 +67,6 @@ static const struct oatype {
|
||||
{"VARIANT", VT_VARIANT},
|
||||
{"VARIANT_BOOL", VT_BOOL}
|
||||
};
|
||||
#define NTYPES (sizeof(oatypes)/sizeof(oatypes[0]))
|
||||
#define KWP(p) ((const struct oatype *)(p))
|
||||
|
||||
static int kw_cmp_func(const void *s1, const void *s2)
|
||||
@@ -86,11 +81,11 @@ static unsigned short builtin_vt(const type_t *t)
|
||||
const struct oatype *kwp;
|
||||
key.kw = kw;
|
||||
#ifdef KW_BSEARCH
|
||||
kwp = bsearch(&key, oatypes, NTYPES, sizeof(oatypes[0]), kw_cmp_func);
|
||||
kwp = bsearch(&key, oatypes, ARRAY_SIZE(oatypes), sizeof(oatypes[0]), kw_cmp_func);
|
||||
#else
|
||||
{
|
||||
unsigned int i;
|
||||
for (kwp=NULL, i=0; i < NTYPES; i++)
|
||||
for (kwp = NULL, i = 0; i < ARRAY_SIZE(oatypes); i++)
|
||||
if (!kw_cmp_func(&key, &oatypes[i])) {
|
||||
kwp = &oatypes[i];
|
||||
break;
|
||||
@@ -104,9 +99,9 @@ static unsigned short builtin_vt(const type_t *t)
|
||||
{
|
||||
const type_t *elem_type;
|
||||
if (is_array(t))
|
||||
elem_type = type_array_get_element(t);
|
||||
elem_type = type_array_get_element_type(t);
|
||||
else
|
||||
elem_type = type_pointer_get_ref(t);
|
||||
elem_type = type_pointer_get_ref_type(t);
|
||||
if (type_get_type(elem_type) == TYPE_BASIC)
|
||||
{
|
||||
switch (type_basic_get_type(elem_type))
|
||||
@@ -136,7 +131,8 @@ unsigned short get_type_vt(type_t *t)
|
||||
if (vt) return vt;
|
||||
}
|
||||
|
||||
if (type_is_alias(t) && is_attr(t->attrs, ATTR_PUBLIC))
|
||||
if (type_is_alias(t) &&
|
||||
(is_attr(t->attrs, ATTR_PUBLIC) || is_attr(t->attrs, ATTR_WIREMARSHAL)))
|
||||
return VT_USERDEFINED;
|
||||
|
||||
switch (type_get_type(t)) {
|
||||
@@ -205,7 +201,7 @@ unsigned short get_type_vt(type_t *t)
|
||||
case TYPE_ARRAY:
|
||||
if (type_array_is_decl_as_ptr(t))
|
||||
{
|
||||
if (match(type_array_get_element(t)->name, "SAFEARRAY"))
|
||||
if (match(type_array_get_element_type(t)->name, "SAFEARRAY"))
|
||||
return VT_SAFEARRAY;
|
||||
return VT_PTR;
|
||||
}
|
||||
@@ -225,13 +221,18 @@ unsigned short get_type_vt(type_t *t)
|
||||
case TYPE_MODULE:
|
||||
case TYPE_UNION:
|
||||
case TYPE_ENCAPSULATED_UNION:
|
||||
case TYPE_RUNTIMECLASS:
|
||||
case TYPE_DELEGATE:
|
||||
return VT_USERDEFINED;
|
||||
|
||||
case TYPE_VOID:
|
||||
return VT_VOID;
|
||||
|
||||
case TYPE_ALIAS:
|
||||
/* aliases should be filtered out by the type_get_type call above */
|
||||
case TYPE_APICONTRACT:
|
||||
case TYPE_PARAMETERIZED_TYPE:
|
||||
case TYPE_PARAMETER:
|
||||
/* not supposed to be here */
|
||||
assert(0);
|
||||
break;
|
||||
|
||||
@@ -261,128 +262,147 @@ void end_typelib(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
static void tlb_read(int fd, void *buf, int count)
|
||||
static void msft_read_guid(void *data, MSFT_SegDir *segdir, int offset, struct uuid *guid)
|
||||
{
|
||||
if(read(fd, buf, count) < count)
|
||||
error("error while reading importlib.\n");
|
||||
memcpy( guid, (char *)data + segdir->pGuidTab.offset + offset, sizeof(*guid) );
|
||||
}
|
||||
|
||||
static void tlb_lseek(int fd, off_t offset)
|
||||
static void read_msft_importlib(importlib_t *importlib, void *data, unsigned int size)
|
||||
{
|
||||
if(lseek(fd, offset, SEEK_SET) == -1)
|
||||
error("lseek failed\n");
|
||||
}
|
||||
|
||||
static void msft_read_guid(int fd, MSFT_SegDir *segdir, int offset, GUID *guid)
|
||||
{
|
||||
tlb_lseek(fd, segdir->pGuidTab.offset+offset);
|
||||
tlb_read(fd, guid, sizeof(GUID));
|
||||
}
|
||||
|
||||
static void read_msft_importlib(importlib_t *importlib, int fd)
|
||||
{
|
||||
MSFT_Header header;
|
||||
MSFT_SegDir segdir;
|
||||
MSFT_Header *header = data;
|
||||
MSFT_SegDir *segdir;
|
||||
int *typeinfo_offs;
|
||||
int i;
|
||||
|
||||
importlib->allocated = 0;
|
||||
importlib->version = header->version;
|
||||
|
||||
tlb_lseek(fd, 0);
|
||||
tlb_read(fd, &header, sizeof(header));
|
||||
typeinfo_offs = (int *)(header + 1);
|
||||
segdir = (MSFT_SegDir *)(typeinfo_offs + header->nrtypeinfos);
|
||||
|
||||
importlib->version = header.version;
|
||||
msft_read_guid(data, segdir, header->posguid, &importlib->guid);
|
||||
|
||||
typeinfo_offs = xmalloc(header.nrtypeinfos*sizeof(INT));
|
||||
tlb_read(fd, typeinfo_offs, header.nrtypeinfos*sizeof(INT));
|
||||
tlb_read(fd, &segdir, sizeof(segdir));
|
||||
|
||||
msft_read_guid(fd, &segdir, header.posguid, &importlib->guid);
|
||||
|
||||
importlib->ntypeinfos = header.nrtypeinfos;
|
||||
importlib->ntypeinfos = header->nrtypeinfos;
|
||||
importlib->importinfos = xmalloc(importlib->ntypeinfos*sizeof(importinfo_t));
|
||||
|
||||
for(i=0; i < importlib->ntypeinfos; i++) {
|
||||
MSFT_TypeInfoBase base;
|
||||
MSFT_NameIntro nameintro;
|
||||
MSFT_TypeInfoBase *base = (MSFT_TypeInfoBase *)((char *)(segdir + 1) + typeinfo_offs[i]);
|
||||
MSFT_NameIntro *nameintro;
|
||||
int len;
|
||||
|
||||
tlb_lseek(fd, sizeof(MSFT_Header) + header.nrtypeinfos*sizeof(INT) + sizeof(MSFT_SegDir)
|
||||
+ typeinfo_offs[i]);
|
||||
tlb_read(fd, &base, sizeof(base));
|
||||
|
||||
importlib->importinfos[i].importlib = importlib;
|
||||
importlib->importinfos[i].flags = (base.typekind&0xf)<<24;
|
||||
importlib->importinfos[i].flags = (base->typekind & 0xf)<<24;
|
||||
importlib->importinfos[i].offset = -1;
|
||||
importlib->importinfos[i].id = i;
|
||||
|
||||
if(base.posguid != -1) {
|
||||
if(base->posguid != -1) {
|
||||
importlib->importinfos[i].flags |= MSFT_IMPINFO_OFFSET_IS_GUID;
|
||||
msft_read_guid(fd, &segdir, base.posguid, &importlib->importinfos[i].guid);
|
||||
msft_read_guid(data, segdir, base->posguid, &importlib->importinfos[i].guid);
|
||||
}
|
||||
else memset( &importlib->importinfos[i].guid, 0, sizeof(importlib->importinfos[i].guid));
|
||||
|
||||
tlb_lseek(fd, segdir.pNametab.offset + base.NameOffset);
|
||||
tlb_read(fd, &nameintro, sizeof(nameintro));
|
||||
|
||||
len = nameintro.namelen & 0xff;
|
||||
nameintro = (MSFT_NameIntro *)((char *)data + segdir->pNametab.offset + base->NameOffset);
|
||||
|
||||
len = nameintro->namelen & 0xff;
|
||||
importlib->importinfos[i].name = xmalloc(len+1);
|
||||
tlb_read(fd, importlib->importinfos[i].name, len);
|
||||
memcpy( importlib->importinfos[i].name, nameintro + 1, len );
|
||||
importlib->importinfos[i].name[len] = 0;
|
||||
}
|
||||
|
||||
free(typeinfo_offs);
|
||||
}
|
||||
|
||||
static int open_typelib(const char *name)
|
||||
static unsigned int rva_to_va( const IMAGE_NT_HEADERS32 *nt, unsigned int rva )
|
||||
{
|
||||
char *file_name;
|
||||
int fd;
|
||||
IMAGE_SECTION_HEADER *sec = IMAGE_FIRST_SECTION( nt );
|
||||
unsigned int i;
|
||||
|
||||
file_name = wpp_find_include(name, NULL);
|
||||
if(!file_name)
|
||||
return open(name, O_RDONLY | O_BINARY );
|
||||
for (i = 0; i < nt->FileHeader.NumberOfSections; i++, sec++)
|
||||
if (sec->VirtualAddress <= rva && sec->VirtualAddress + sec->Misc.VirtualSize > rva)
|
||||
return sec->PointerToRawData + (rva - sec->VirtualAddress);
|
||||
error( "no PE section found for addr %x\n", rva );
|
||||
#ifdef __REACTOS__
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
fd = open(file_name, O_RDONLY | O_BINARY );
|
||||
free(file_name);
|
||||
return fd;
|
||||
static void read_pe_importlib(importlib_t *importlib, void *data, unsigned int size)
|
||||
{
|
||||
IMAGE_DOS_HEADER *dos = data;
|
||||
IMAGE_NT_HEADERS32 *nt;
|
||||
IMAGE_DATA_DIRECTORY *dir;
|
||||
IMAGE_RESOURCE_DIRECTORY *root, *resdir;
|
||||
IMAGE_RESOURCE_DIRECTORY_ENTRY *entry;
|
||||
IMAGE_RESOURCE_DATA_ENTRY *resdata;
|
||||
void *ptr;
|
||||
unsigned int i, va;
|
||||
|
||||
if (dos->e_lfanew < sizeof(*dos) || dos->e_lfanew >= size) error( "not a PE file\n" );
|
||||
nt = (IMAGE_NT_HEADERS32 *)((char *)data + dos->e_lfanew);
|
||||
if (nt->Signature != IMAGE_NT_SIGNATURE) error( "not a PE file\n" );
|
||||
if ((char *)(IMAGE_FIRST_SECTION(nt) + nt->FileHeader.NumberOfSections) > (char *)data + size)
|
||||
error( "invalid PE file\n" );
|
||||
switch (nt->OptionalHeader.Magic)
|
||||
{
|
||||
case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
|
||||
dir = &nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE];
|
||||
break;
|
||||
case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
|
||||
dir = &((IMAGE_NT_HEADERS64 *)nt)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE];
|
||||
break;
|
||||
default:
|
||||
error( "invalid PE file\n" );
|
||||
}
|
||||
if (!dir->VirtualAddress || !dir->Size) error( "resource not found in PE file\n" );
|
||||
va = rva_to_va( nt, dir->VirtualAddress );
|
||||
if (va + dir->Size > size) error( "invalid resource data in PE file\n" );
|
||||
root = resdir = (IMAGE_RESOURCE_DIRECTORY *)((char *)data + va );
|
||||
entry = (IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1);
|
||||
for (i = 0; i < resdir->NumberOfNamedEntries; i++, entry++)
|
||||
{
|
||||
static const WCHAR typelibW[] = {'T','Y','P','E','L','I','B'};
|
||||
WCHAR *name = (WCHAR *)((char *)root + entry->NameOffset);
|
||||
if (name[0] != ARRAY_SIZE(typelibW)) continue;
|
||||
if (!memcmp( name + 1, typelibW, sizeof(typelibW) )) break;
|
||||
}
|
||||
if (i == resdir->NumberOfNamedEntries) error( "typelib resource not found in PE file\n" );
|
||||
while (entry->DataIsDirectory)
|
||||
{
|
||||
resdir = (IMAGE_RESOURCE_DIRECTORY *)((char *)root + entry->OffsetToDirectory);
|
||||
entry = (IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1);
|
||||
}
|
||||
resdata = (IMAGE_RESOURCE_DATA_ENTRY *)((char *)root + entry->OffsetToData);
|
||||
ptr = (char *)data + rva_to_va( nt, resdata->OffsetToData );
|
||||
if (memcmp( ptr, "MSFT", 4 )) error( "invalid typelib found in PE file\n" );
|
||||
read_msft_importlib( importlib, ptr, resdata->Size );
|
||||
}
|
||||
|
||||
static void read_importlib(importlib_t *importlib)
|
||||
{
|
||||
int fd;
|
||||
INT magic;
|
||||
int fd, size;
|
||||
void *data;
|
||||
|
||||
fd = open_typelib(importlib->name);
|
||||
|
||||
/* widl extension: if importlib name has no .tlb extension, try using .tlb */
|
||||
if(fd < 0) {
|
||||
const char *p = strrchr(importlib->name, '.');
|
||||
size_t len = p ? p - importlib->name : strlen(importlib->name);
|
||||
if(strcmp(importlib->name + len, ".tlb")) {
|
||||
char *tlb_name = xmalloc(len + 5);
|
||||
memcpy(tlb_name, importlib->name, len);
|
||||
strcpy(tlb_name + len, ".tlb");
|
||||
fd = open_typelib(tlb_name);
|
||||
free(tlb_name);
|
||||
}
|
||||
}
|
||||
if (fd < 0 && !strendswith( importlib->name, ".tlb" ))
|
||||
fd = open_typelib( strmake( "%s.tlb", importlib->name ));
|
||||
|
||||
if(fd < 0)
|
||||
error("Could not find importlib %s.\n", importlib->name);
|
||||
|
||||
tlb_read(fd, &magic, sizeof(magic));
|
||||
size = lseek( fd, 0, SEEK_END );
|
||||
data = xmalloc( size );
|
||||
lseek( fd, 0, SEEK_SET );
|
||||
if (read( fd, data, size) < size) error("error while reading importlib.\n");
|
||||
close( fd );
|
||||
|
||||
switch(magic) {
|
||||
case MSFT_MAGIC:
|
||||
read_msft_importlib(importlib, fd);
|
||||
break;
|
||||
default:
|
||||
error("Wrong or unsupported typelib magic %x\n", magic);
|
||||
};
|
||||
if (!memcmp( data, "MSFT", 4 ))
|
||||
read_msft_importlib(importlib, data, size);
|
||||
else if (!memcmp( data, "MZ", 2 ))
|
||||
read_pe_importlib(importlib, data, size);
|
||||
else
|
||||
error("Wrong or unsupported typelib\n");
|
||||
|
||||
close(fd);
|
||||
free( data );
|
||||
}
|
||||
|
||||
#ifdef __REACTOS__
|
||||
|
||||
+270
-290
@@ -49,13 +49,13 @@
|
||||
*
|
||||
*/
|
||||
typedef struct tagMSFT_Header {
|
||||
/*0x00*/INT magic1; /* 0x5446534D "MSFT" */
|
||||
INT magic2; /* 0x00010002 version nr? */
|
||||
INT posguid; /* position of libid in guid table */
|
||||
/*0x00*/int magic1; /* 0x5446534D "MSFT" */
|
||||
int magic2; /* 0x00010002 version nr? */
|
||||
int posguid; /* position of libid in guid table */
|
||||
/* (should be, else -1) */
|
||||
INT lcid; /* locale id */
|
||||
/*0x10*/INT lcid2;
|
||||
INT varflags; /* (largely) unknown flags */
|
||||
int lcid; /* locale id */
|
||||
/*0x10*/int lcid2;
|
||||
int varflags; /* (largely) unknown flags */
|
||||
/* the lower nibble is syskind */
|
||||
/* 0x40 always seems to be set */
|
||||
/* 0x10 set with a helpfile defined */
|
||||
@@ -63,30 +63,30 @@ typedef struct tagMSFT_Header {
|
||||
case the offset to the name in the stringtable
|
||||
appears right after this struct, before the
|
||||
typeinfo offsets */
|
||||
INT version; /* set with SetVersion() */
|
||||
INT flags; /* set with SetFlags() */
|
||||
/*0x20*/INT nrtypeinfos; /* number of typeinfo's (till so far) */
|
||||
INT helpstring; /* position of help string in stringtable */
|
||||
INT helpstringcontext;
|
||||
INT helpcontext;
|
||||
/*0x30*/INT nametablecount; /* number of names in name table */
|
||||
INT nametablechars; /* nr of characters in name table */
|
||||
INT NameOffset; /* offset of name in name table */
|
||||
INT helpfile; /* position of helpfile in stringtable */
|
||||
/*0x40*/INT CustomDataOffset; /* if -1 no custom data, else it is offset */
|
||||
int version; /* set with SetVersion() */
|
||||
int flags; /* set with SetFlags() */
|
||||
/*0x20*/int nrtypeinfos; /* number of typeinfo's (till so far) */
|
||||
int helpstring; /* position of help string in stringtable */
|
||||
int helpstringcontext;
|
||||
int helpcontext;
|
||||
/*0x30*/int nametablecount; /* number of names in name table */
|
||||
int nametablechars; /* nr of characters in name table */
|
||||
int NameOffset; /* offset of name in name table */
|
||||
int helpfile; /* position of helpfile in stringtable */
|
||||
/*0x40*/int CustomDataOffset; /* if -1 no custom data, else it is offset */
|
||||
/* in customer data/guid offset table */
|
||||
INT res44; /* unknown always: 0x20 (guid hash size?) */
|
||||
INT res48; /* unknown always: 0x80 (name hash size?) */
|
||||
INT dispatchpos; /* HREFTYPE to IDispatch, or -1 if no IDispatch */
|
||||
/*0x50*/INT nimpinfos; /* number of impinfos */
|
||||
int res44; /* unknown always: 0x20 (guid hash size?) */
|
||||
int res48; /* unknown always: 0x80 (name hash size?) */
|
||||
int dispatchpos; /* HREFTYPE to IDispatch, or -1 if no IDispatch */
|
||||
/*0x50*/int nimpinfos; /* number of impinfos */
|
||||
} MSFT_Header;
|
||||
|
||||
/* segments in the type lib file have a structure like this: */
|
||||
typedef struct tagMSFT_pSeg {
|
||||
INT offset; /* absolute offset in file */
|
||||
INT length; /* length of segment */
|
||||
INT res08; /* unknown always -1 */
|
||||
INT res0c; /* unknown always 0x0f in the header */
|
||||
int offset; /* absolute offset in file */
|
||||
int length; /* length of segment */
|
||||
int res08; /* unknown always -1 */
|
||||
int res0c; /* unknown always 0x0f in the header */
|
||||
/* 0x03 in the typeinfo_data */
|
||||
} MSFT_pSeg;
|
||||
|
||||
@@ -118,70 +118,60 @@ typedef struct tagMSFT_SegDir {
|
||||
|
||||
/* base type info data */
|
||||
typedef struct tagMSFT_TypeInfoBase {
|
||||
/*000*/ INT typekind; /* it is the TKIND_xxx */
|
||||
/*000*/ int typekind; /* it is the TKIND_xxx */
|
||||
/* some byte alignment stuff */
|
||||
INT memoffset; /* points past the file, if no elements */
|
||||
INT res2; /* zero if no element, N*0x40 */
|
||||
INT res3; /* -1 if no element, (N-1)*0x38 */
|
||||
/*010*/ INT res4; /* always? 3 */
|
||||
INT res5; /* always? zero */
|
||||
INT cElement; /* counts elements, HI=cVars, LO=cFuncs */
|
||||
INT res7; /* always? zero */
|
||||
/*020*/ INT res8; /* always? zero */
|
||||
INT res9; /* always? zero */
|
||||
INT resA; /* always? zero */
|
||||
INT posguid; /* position in guid table */
|
||||
/*030*/ INT flags; /* Typeflags */
|
||||
INT NameOffset; /* offset in name table */
|
||||
INT version; /* element version */
|
||||
INT docstringoffs; /* offset of docstring in string tab */
|
||||
/*040*/ INT helpstringcontext; /* */
|
||||
INT helpcontext; /* */
|
||||
INT oCustData; /* offset in customer data table */
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
INT16 cbSizeVft; /* virtual table size, including inherits */
|
||||
INT16 cImplTypes; /* nr of implemented interfaces */
|
||||
#else
|
||||
INT16 cImplTypes; /* nr of implemented interfaces */
|
||||
INT16 cbSizeVft; /* virtual table size, including inherits */
|
||||
#endif
|
||||
/*050*/ INT size; /* size in bytes, at least for structures */
|
||||
int memoffset; /* points past the file, if no elements */
|
||||
int res2; /* zero if no element, N*0x40 */
|
||||
int res3; /* -1 if no element, (N-1)*0x38 */
|
||||
/*010*/ int res4; /* always? 3 */
|
||||
int res5; /* always? zero */
|
||||
int cElement; /* counts elements, HI=cVars, LO=cFuncs */
|
||||
int res7; /* always? zero */
|
||||
/*020*/ int res8; /* always? zero */
|
||||
int res9; /* always? zero */
|
||||
int resA; /* always? zero */
|
||||
int posguid; /* position in guid table */
|
||||
/*030*/ int flags; /* Typeflags */
|
||||
int NameOffset; /* offset in name table */
|
||||
int version; /* element version */
|
||||
int docstringoffs; /* offset of docstring in string tab */
|
||||
/*040*/ int helpstringcontext; /* */
|
||||
int helpcontext; /* */
|
||||
int oCustData; /* offset in customer data table */
|
||||
short cImplTypes; /* nr of implemented interfaces */
|
||||
short cbSizeVft; /* virtual table size, including inherits */
|
||||
/*050*/ int size; /* size in bytes, at least for structures */
|
||||
/* FIXME: name of this field */
|
||||
INT datatype1; /* position in type description table */
|
||||
int datatype1; /* position in type description table */
|
||||
/* or in base interfaces */
|
||||
/* if coclass: offset in reftable */
|
||||
/* if interface: reference to inherited if */
|
||||
INT datatype2; /* for interfaces: hiword is num of inherited funcs */
|
||||
int datatype2; /* for interfaces: hiword is num of inherited funcs */
|
||||
/* loword is num of inherited interfaces */
|
||||
INT res18; /* always? 0 */
|
||||
/*060*/ INT res19; /* always? -1 */
|
||||
int res18; /* always? 0 */
|
||||
/*060*/ int res19; /* always? -1 */
|
||||
} MSFT_TypeInfoBase;
|
||||
|
||||
/* layout of an entry with information on imported types */
|
||||
typedef struct tagMSFT_ImpInfo {
|
||||
INT flags; /* bits 0 - 15: count */
|
||||
int flags; /* bits 0 - 15: count */
|
||||
/* bit 16: if set oGuid is an offset to Guid */
|
||||
/* if clear oGuid is a typeinfo index in the specified typelib */
|
||||
/* bits 24 - 31: TKIND of reference */
|
||||
INT oImpFile; /* offset in the Import File table */
|
||||
INT oGuid; /* offset in Guid table or typeinfo index (see bit 16 of flags) */
|
||||
int oImpFile; /* offset in the Import File table */
|
||||
int oGuid; /* offset in Guid table or typeinfo index (see bit 16 of flags) */
|
||||
} MSFT_ImpInfo;
|
||||
|
||||
#define MSFT_IMPINFO_OFFSET_IS_GUID 0x00010000
|
||||
|
||||
/* function description data */
|
||||
typedef struct {
|
||||
/* INT recsize; record size including some extra stuff */
|
||||
INT DataType; /* data type of the member, eg return of function */
|
||||
INT Flags; /* something to do with attribute flags (LOWORD) */
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
INT16 funcdescsize; /* size of reconstituted FUNCDESC and related structs */
|
||||
INT16 VtableOffset; /* offset in vtable */
|
||||
#else
|
||||
INT16 VtableOffset; /* offset in vtable */
|
||||
INT16 funcdescsize; /* size of reconstituted FUNCDESC and related structs */
|
||||
#endif
|
||||
INT FKCCIC; /* bit string with the following */
|
||||
/* int recsize; record size including some extra stuff */
|
||||
int DataType; /* data type of the member, eg return of function */
|
||||
int Flags; /* something to do with attribute flags (LOWORD) */
|
||||
short VtableOffset; /* offset in vtable */
|
||||
short funcdescsize; /* size of reconstituted FUNCDESC and related structs */
|
||||
int FKCCIC; /* bit string with the following */
|
||||
/* meaning (bit 0 is the lsb): */
|
||||
/* bits 0 - 2: FUNCKIND */
|
||||
/* bits 3 - 6: INVOKEKIND */
|
||||
@@ -191,96 +181,86 @@ typedef struct {
|
||||
/* bit 13: oEntry is numeric */
|
||||
/* bit 14: has retval param */
|
||||
/* bits 16 - 31: index of next function with same id */
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
INT16 nroargs; /* nr of optional arguments */
|
||||
INT16 nrargs; /* number of arguments (including optional ????) */
|
||||
#else
|
||||
INT16 nrargs; /* number of arguments (including optional ????) */
|
||||
INT16 nroargs; /* nr of optional arguments */
|
||||
#endif
|
||||
short nrargs; /* number of arguments (including optional ????) */
|
||||
short nroargs; /* nr of optional arguments */
|
||||
/* optional attribute fields, the number of them is variable */
|
||||
INT OptAttr[1];
|
||||
int OptAttr[1];
|
||||
/*
|
||||
0* INT helpcontext;
|
||||
1* INT oHelpString;
|
||||
2* INT oEntry; // either offset in string table or numeric as it is (see bit 13 of FKCCIC) //
|
||||
3* INT res9; // unknown (-1) //
|
||||
4* INT resA; // unknown (-1) //
|
||||
5* INT HelpStringContext;
|
||||
0* int helpcontext;
|
||||
1* int oHelpString;
|
||||
2* int oEntry; // either offset in string table or numeric as it is (see bit 13 of FKCCIC) //
|
||||
3* int res9; // unknown (-1) //
|
||||
4* int resA; // unknown (-1) //
|
||||
5* int HelpStringContext;
|
||||
// these are controlled by a bit set in the FKCCIC field //
|
||||
6* INT oCustData; // custom data for function //
|
||||
7* INT oArgCustData[1]; // custom data per argument //
|
||||
6* int oCustData; // custom data for function //
|
||||
7* int oArgCustData[1]; // custom data per argument //
|
||||
*/
|
||||
} MSFT_FuncRecord;
|
||||
|
||||
/* after this may follow an array with default value pointers if the
|
||||
* appropriate bit in the FKCCIC field has been set:
|
||||
* INT oDefaultValue[nrargs];
|
||||
* int oDefaultValue[nrargs];
|
||||
*/
|
||||
|
||||
/* Parameter info one per argument*/
|
||||
typedef struct {
|
||||
INT DataType;
|
||||
INT oName;
|
||||
INT Flags;
|
||||
int DataType;
|
||||
int oName;
|
||||
int Flags;
|
||||
} MSFT_ParameterInfo;
|
||||
|
||||
/* Variable description data */
|
||||
typedef struct {
|
||||
/* INT recsize; // record size including some extra stuff */
|
||||
INT DataType; /* data type of the variable */
|
||||
INT Flags; /* VarFlags (LOWORD) */
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
INT16 vardescsize; /* size of reconstituted VARDESC and related structs */
|
||||
INT16 VarKind; /* VarKind */
|
||||
#else
|
||||
INT16 VarKind; /* VarKind */
|
||||
INT16 vardescsize; /* size of reconstituted VARDESC and related structs */
|
||||
#endif
|
||||
INT OffsValue; /* value of the variable or the offset */
|
||||
/* int recsize; // record size including some extra stuff */
|
||||
int DataType; /* data type of the variable */
|
||||
int Flags; /* VarFlags (LOWORD) */
|
||||
short VarKind; /* VarKind */
|
||||
short vardescsize; /* size of reconstituted VARDESC and related structs */
|
||||
int OffsValue; /* value of the variable or the offset */
|
||||
/* in the data structure */
|
||||
/* optional attribute fields, the number of them is variable */
|
||||
/* controlled by record length */
|
||||
INT HelpContext;
|
||||
INT oHelpString;
|
||||
INT res9; /* unknown (-1) */
|
||||
INT oCustData; /* custom data for variable */
|
||||
INT HelpStringContext;
|
||||
int HelpContext;
|
||||
int oHelpString;
|
||||
int res9; /* unknown (-1) */
|
||||
int oCustData; /* custom data for variable */
|
||||
int HelpStringContext;
|
||||
|
||||
} MSFT_VarRecord;
|
||||
|
||||
/* Structure of the reference data */
|
||||
typedef struct {
|
||||
INT reftype; /* either offset in type info table, then it's */
|
||||
int reftype; /* either offset in type info table, then it's */
|
||||
/* a multiple of 64 */
|
||||
/* or offset in the external reference table */
|
||||
/* with an offset of 1 */
|
||||
INT flags;
|
||||
INT oCustData; /* custom data */
|
||||
INT onext; /* next offset, -1 if last */
|
||||
int flags;
|
||||
int oCustData; /* custom data */
|
||||
int onext; /* next offset, -1 if last */
|
||||
} MSFT_RefRecord;
|
||||
|
||||
/* this is how a guid is stored */
|
||||
typedef struct {
|
||||
GUID guid;
|
||||
INT hreftype; /* -2 for the typelib guid, typeinfo offset
|
||||
struct uuid guid;
|
||||
int hreftype; /* -2 for the typelib guid, typeinfo offset
|
||||
for typeinfo guid, low two bits are 01 if
|
||||
this is an imported typeinfo, low two bits
|
||||
are 10 if this is an imported typelib (used
|
||||
by imported typeinfos) */
|
||||
INT next_hash; /* offset to next guid in the hash bucket */
|
||||
int next_hash; /* offset to next guid in the hash bucket */
|
||||
} MSFT_GuidEntry;
|
||||
/* some data preceding entries in the name table */
|
||||
typedef struct {
|
||||
INT hreftype; /* is -1 if name is for neither a typeinfo,
|
||||
int hreftype; /* is -1 if name is for neither a typeinfo,
|
||||
a variable, or a function (that is, name
|
||||
is for a typelib or a function parameter).
|
||||
otherwise is the offset of the first
|
||||
typeinfo that this name refers to (either
|
||||
to the typeinfo itself or to a member of
|
||||
the typeinfo */
|
||||
INT next_hash; /* offset to next name in the hash bucket */
|
||||
INT namelen; /* only lower 8 bits are valid */
|
||||
int next_hash; /* offset to next name in the hash bucket */
|
||||
int namelen; /* only lower 8 bits are valid */
|
||||
/* 0x1000 if name is only used once as a variable name */
|
||||
/* 0x2000 if name is a variable in an enumeration */
|
||||
/* 0x3800 if name is typeinfo name */
|
||||
@@ -288,9 +268,9 @@ typedef struct {
|
||||
} MSFT_NameIntro;
|
||||
/* the custom data table directory has entries like this */
|
||||
typedef struct {
|
||||
INT GuidOffset;
|
||||
INT DataOffset;
|
||||
INT next; /* next offset in the table, -1 if it's the last */
|
||||
int GuidOffset;
|
||||
int DataOffset;
|
||||
int next; /* next offset in the table, -1 if it's the last */
|
||||
} MSFT_CDGuid;
|
||||
|
||||
|
||||
@@ -305,35 +285,35 @@ typedef struct {
|
||||
#include "pshpack1.h"
|
||||
|
||||
typedef struct {
|
||||
/*00*/ DWORD SLTG_magic; /* 0x47544c53 == "SLTG" */
|
||||
/*04*/ WORD nrOfFileBlks; /* no of SLTG_BlkEntry's + 1 */
|
||||
/*06*/ WORD res06; /* ?? always 9 */
|
||||
/*08*/ WORD res08; /* some kind of len/offset ?? */
|
||||
/*0a*/ WORD first_blk; /* 1 based index into blk entries that
|
||||
corresponds to first block in file */
|
||||
/*0c*/ DWORD res0c; /* always 0x000204ff */
|
||||
/*10*/ DWORD res10; /* always 0x00000000 */
|
||||
/*14*/ DWORD res14; /* always 0x000000c0 */
|
||||
/*18*/ DWORD res18; /* always 0x46000000 */
|
||||
/*1c*/ DWORD res1c; /* always 0x00000044 */
|
||||
/*20*/ DWORD res20; /* always 0xffff0000 */
|
||||
/*00*/ unsigned int SLTG_magic; /* 0x47544c53 == "SLTG" */
|
||||
/*04*/ unsigned short nrOfFileBlks; /* no of SLTG_BlkEntry's + 1 */
|
||||
/*06*/ unsigned short res06; /* ?? always 9 */
|
||||
/*08*/ unsigned short res08; /* some kind of len/offset ?? */
|
||||
/*0a*/ unsigned short first_blk; /* 1 based index into blk entries that
|
||||
corresponds to first block in file */
|
||||
/*0c*/ unsigned int res0c; /* always 0x000204ff */
|
||||
/*10*/ unsigned int res10; /* always 0x00000000 */
|
||||
/*14*/ unsigned int res14; /* always 0x000000c0 */
|
||||
/*18*/ unsigned int res18; /* always 0x46000000 */
|
||||
/*1c*/ unsigned int res1c; /* always 0x00000044 */
|
||||
/*20*/ unsigned int res20; /* always 0xffff0000 */
|
||||
} SLTG_Header;
|
||||
|
||||
/* This gets followed by a list of block entries */
|
||||
typedef struct {
|
||||
/*00*/ DWORD len;
|
||||
/*04*/ WORD index_string; /* offs from start of SLTG_Magic to index string */
|
||||
/*06*/ WORD next;
|
||||
/*00*/ unsigned int len;
|
||||
/*04*/ unsigned short index_string; /* offs from start of SLTG_Magic to index string */
|
||||
/*06*/ unsigned short next;
|
||||
} SLTG_BlkEntry;
|
||||
|
||||
/* The order of the blocks in the file is given by starting at Block
|
||||
entry firt_blk and stepping through using the next pointer */
|
||||
entry first_blk and stepping through using the next pointer */
|
||||
|
||||
/* These then get followed by this magic */
|
||||
typedef struct {
|
||||
/*00*/ BYTE res00; /* always 0x01 */
|
||||
/*01*/ CHAR CompObj_magic[8]; /* always "CompObj" */
|
||||
/*09*/ CHAR dir_magic[4]; /* always "dir" */
|
||||
/*00*/ unsigned char res00; /* always 0x01 */
|
||||
/*01*/ char CompObj_magic[8]; /* always "CompObj" */
|
||||
/*09*/ char dir_magic[4]; /* always "dir" */
|
||||
} SLTG_Magic;
|
||||
|
||||
#define SLTG_COMPOBJ_MAGIC "CompObj"
|
||||
@@ -346,13 +326,13 @@ uniqueness. I guess successive chars increment when we need to wrap
|
||||
the first one. */
|
||||
|
||||
typedef struct {
|
||||
/*00*/ CHAR string[11];
|
||||
/*00*/ char string[11];
|
||||
} SLTG_Index;
|
||||
|
||||
|
||||
/* This is followed by SLTG_pad9 */
|
||||
typedef struct {
|
||||
/*00*/ CHAR pad[9]; /* 9 '\0's */
|
||||
/*00*/ char pad[9]; /* 9 '\0's */
|
||||
} SLTG_Pad9;
|
||||
|
||||
|
||||
@@ -362,25 +342,25 @@ each block is given by its entry in SLTG_BlkEntry. */
|
||||
/* type SLTG_NAME in rather like a BSTR except that the length in
|
||||
bytes is given by the first WORD and the string contains 8bit chars */
|
||||
|
||||
typedef WORD SLTG_Name;
|
||||
typedef unsigned short SLTG_Name;
|
||||
|
||||
/* The main library block looks like this. This one seems to come last */
|
||||
|
||||
typedef struct {
|
||||
/*00*/ WORD magic; /* 0x51cc */
|
||||
/*02*/ WORD res02; /* 0x0003, 0x0004 */
|
||||
/*04*/ WORD name; /* offset to name in name table */
|
||||
/*06*/ SLTG_Name res06; /* maybe this is just WORD == 0xffff */
|
||||
SLTG_Name helpstring;
|
||||
SLTG_Name helpfile;
|
||||
DWORD helpcontext;
|
||||
WORD syskind; /* == 1 for win32, 0 for win16 */
|
||||
WORD lcid; /* == 0x409, 0x809 etc */
|
||||
DWORD res12; /* == 0 */
|
||||
WORD libflags; /* LIBFLAG_* */
|
||||
WORD maj_vers;
|
||||
WORD min_vers;
|
||||
GUID uuid;
|
||||
/*00*/ unsigned short magic; /* 0x51cc */
|
||||
/*02*/ unsigned short res02; /* 0x0003, 0x0004 */
|
||||
/*04*/ unsigned short name; /* offset to name in name table */
|
||||
/*06*/ SLTG_Name res06; /* maybe this is just WORD == 0xffff */
|
||||
SLTG_Name helpstring;
|
||||
SLTG_Name helpfile;
|
||||
unsigned int helpcontext;
|
||||
unsigned short syskind; /* == 1 for win32, 0 for win16 */
|
||||
unsigned short lcid; /* == 0x409, 0x809 etc */
|
||||
unsigned int res12; /* == 0 */
|
||||
unsigned short libflags; /* LIBFLAG_* */
|
||||
unsigned short maj_vers;
|
||||
unsigned short min_vers;
|
||||
struct uuid uuid;
|
||||
} SLTG_LibBlk;
|
||||
|
||||
#define SLTG_LIBBLK_MAGIC 0x51cc
|
||||
@@ -388,18 +368,18 @@ typedef struct {
|
||||
/* we then get 0x40 bytes worth of 0xffff or small numbers followed by
|
||||
nrOfFileBlks - 2 of these */
|
||||
typedef struct {
|
||||
WORD small_no;
|
||||
SLTG_Name index_name; /* This refers to a name in the directory */
|
||||
SLTG_Name other_name; /* Another one of these weird names */
|
||||
WORD res1a; /* 0xffff */
|
||||
WORD name_offs; /* offset to name in name table */
|
||||
WORD more_bytes; /* if this is non-zero we get this many
|
||||
bytes before the next element, which seem
|
||||
to reference the docstring of the type ? */
|
||||
WORD res20; /* 0xffff */
|
||||
DWORD helpcontext;
|
||||
WORD res26; /* 0xffff */
|
||||
GUID uuid;
|
||||
unsigned short small_no;
|
||||
SLTG_Name index_name; /* This refers to a name in the directory */
|
||||
SLTG_Name other_name; /* Another one of these weird names */
|
||||
unsigned short res1a; /* 0xffff */
|
||||
unsigned short name_offs; /* offset to name in name table */
|
||||
unsigned short more_bytes; /* if this is non-zero we get this many
|
||||
bytes before the next element, which seem
|
||||
to reference the docstring of the type ? */
|
||||
unsigned short res20; /* 0xffff */
|
||||
unsigned int helpcontext;
|
||||
unsigned short res26; /* 0xffff */
|
||||
struct uuid uuid;
|
||||
} SLTG_OtherTypeInfo;
|
||||
|
||||
/* Next we get WORD 0x0003 followed by a DWORD which if we add to
|
||||
@@ -407,104 +387,104 @@ typedef struct {
|
||||
struct */
|
||||
|
||||
typedef struct {
|
||||
/*00*/ WORD magic; /* 0x0501 */
|
||||
/*02*/ DWORD href_table; /* if not 0xffffffff, then byte offset from
|
||||
beginning of struct to href table */
|
||||
/*06*/ DWORD res06; /* 0xffffffff */
|
||||
/*0a*/ DWORD elem_table; /* offset to members */
|
||||
/*0e*/ DWORD res0e; /* 0xffffffff */
|
||||
/*12*/ WORD major_version; /* major version number */
|
||||
/*14*/ WORD minor_version; /* minor version number */
|
||||
/*16*/ DWORD res16; /* 0xfffe0000 */
|
||||
/*1a*/ BYTE typeflags1;/* 0x02 | top 5 bits hold l5sbs of TYPEFLAGS */
|
||||
/*1b*/ BYTE typeflags2;/* TYPEFLAGS >> 5 */
|
||||
/*1c*/ BYTE typeflags3;/* 0x02*/
|
||||
/*1d*/ BYTE typekind; /* 0x03 == TKIND_INTERFACE etc. */
|
||||
/*1e*/ DWORD res1e; /* 0x00000000 or 0xffffffff */
|
||||
/*00*/ unsigned short magic; /* 0x0501 */
|
||||
/*02*/ unsigned int href_table; /* if not 0xffffffff, then byte offset from
|
||||
beginning of struct to href table */
|
||||
/*06*/ unsigned int res06; /* 0xffffffff */
|
||||
/*0a*/ unsigned int elem_table; /* offset to members */
|
||||
/*0e*/ unsigned int res0e; /* 0xffffffff */
|
||||
/*12*/ unsigned short major_version; /* major version number */
|
||||
/*14*/ unsigned short minor_version; /* minor version number */
|
||||
/*16*/ unsigned int res16; /* 0xfffe0000 */
|
||||
/*1a*/ unsigned char typeflags1;/* 0x02 | top 5 bits hold l5sbs of TYPEFLAGS */
|
||||
/*1b*/ unsigned char typeflags2;/* TYPEFLAGS >> 5 */
|
||||
/*1c*/ unsigned char typeflags3;/* 0x02*/
|
||||
/*1d*/ unsigned char typekind; /* 0x03 == TKIND_INTERFACE etc. */
|
||||
/*1e*/ unsigned int res1e; /* 0x00000000 or 0xffffffff */
|
||||
} SLTG_TypeInfoHeader;
|
||||
|
||||
#define SLTG_TIHEADER_MAGIC 0x0501
|
||||
|
||||
typedef struct {
|
||||
/*00*/ WORD cFuncs;
|
||||
/*02*/ WORD cVars;
|
||||
/*04*/ WORD cImplTypes;
|
||||
/*06*/ WORD res06;
|
||||
/*08*/ WORD res08;
|
||||
/*0a*/ WORD res0a;
|
||||
/*0c*/ WORD res0c;
|
||||
/*0e*/ WORD res0e;
|
||||
/*10*/ WORD res10;
|
||||
/*12*/ WORD res12;
|
||||
/*14*/ WORD tdescalias_vt; /* for TKIND_ALIAS */
|
||||
/*16*/ WORD res16;
|
||||
/*18*/ WORD res18;
|
||||
/*1a*/ WORD res1a;
|
||||
/*1c*/ WORD res1c;
|
||||
/*1e*/ WORD res1e;
|
||||
/*20*/ WORD cbSizeInstance;
|
||||
/*22*/ WORD cbAlignment;
|
||||
/*24*/ WORD res24;
|
||||
/*26*/ WORD res26;
|
||||
/*28*/ WORD cbSizeVft;
|
||||
/*2a*/ WORD res2a;
|
||||
/*2c*/ WORD res2c;
|
||||
/*2e*/ WORD res2e;
|
||||
/*30*/ WORD res30;
|
||||
/*32*/ WORD res32;
|
||||
/*34*/ WORD res34;
|
||||
/*00*/ unsigned short cFuncs;
|
||||
/*02*/ unsigned short cVars;
|
||||
/*04*/ unsigned short cImplTypes;
|
||||
/*06*/ unsigned short res06;
|
||||
/*08*/ unsigned short res08;
|
||||
/*0a*/ unsigned short res0a;
|
||||
/*0c*/ unsigned short res0c;
|
||||
/*0e*/ unsigned short res0e;
|
||||
/*10*/ unsigned short res10;
|
||||
/*12*/ unsigned short res12;
|
||||
/*14*/ unsigned short tdescalias_vt; /* for TKIND_ALIAS */
|
||||
/*16*/ unsigned short res16;
|
||||
/*18*/ unsigned short res18;
|
||||
/*1a*/ unsigned short res1a;
|
||||
/*1c*/ unsigned short res1c;
|
||||
/*1e*/ unsigned short res1e;
|
||||
/*20*/ unsigned short cbSizeInstance;
|
||||
/*22*/ unsigned short cbAlignment;
|
||||
/*24*/ unsigned short res24;
|
||||
/*26*/ unsigned short res26;
|
||||
/*28*/ unsigned short cbSizeVft;
|
||||
/*2a*/ unsigned short res2a;
|
||||
/*2c*/ unsigned short res2c;
|
||||
/*2e*/ unsigned short res2e;
|
||||
/*30*/ unsigned short res30;
|
||||
/*32*/ unsigned short res32;
|
||||
/*34*/ unsigned short res34;
|
||||
} SLTG_TypeInfoTail;
|
||||
|
||||
typedef struct {
|
||||
/*00*/ WORD res00; /* 0x0001 sometimes 0x0003 ?? */
|
||||
/*02*/ WORD res02; /* 0xffff */
|
||||
/*04*/ BYTE res04; /* 0x01 */
|
||||
/*05*/ DWORD cbExtra; /* No of bytes that follow */
|
||||
/*00*/ unsigned short res00; /* 0x0001 sometimes 0x0003 ?? */
|
||||
/*02*/ unsigned short res02; /* 0xffff */
|
||||
/*04*/ unsigned char res04; /* 0x01 */
|
||||
/*05*/ unsigned int cbExtra; /* No of bytes that follow */
|
||||
} SLTG_MemberHeader;
|
||||
|
||||
typedef struct {
|
||||
/*00*/ WORD magic; /* 0x120a */
|
||||
/*02*/ WORD next; /* offset in bytes to next block from start of block
|
||||
group, 0xffff if last item */
|
||||
/*04*/ WORD name; /* offset to name within name table */
|
||||
/*06*/ WORD value; /* offset to value from start of block group */
|
||||
/*08*/ WORD res08; /* 0x56 */
|
||||
/*0a*/ DWORD memid; /* memid */
|
||||
/*0e*/ WORD helpcontext;/* 0xfffe == no context, 0x0001 == stored in EnumInfo struct, else offset
|
||||
to value from start of block group */
|
||||
/*10*/ WORD helpstring;/* offset from start of block group to string offset */
|
||||
/*00*/ unsigned short magic; /* 0x120a */
|
||||
/*02*/ unsigned short next; /* offset in bytes to next block from start of block
|
||||
group, 0xffff if last item */
|
||||
/*04*/ unsigned short name; /* offset to name within name table */
|
||||
/*06*/ unsigned short value; /* offset to value from start of block group */
|
||||
/*08*/ unsigned short res08; /* 0x56 */
|
||||
/*0a*/ unsigned int memid; /* memid */
|
||||
/*0e*/ unsigned short helpcontext;/* 0xfffe == no context, 0x0001 == stored in EnumInfo struct, else offset
|
||||
to value from start of block group */
|
||||
/*10*/ unsigned short helpstring;/* offset from start of block group to string offset */
|
||||
} SLTG_EnumItem;
|
||||
|
||||
#define SLTG_ENUMITEM_MAGIC 0x120a
|
||||
|
||||
typedef struct {
|
||||
/*00*/ WORD vt; /* vartype, 0xffff marks end. */
|
||||
/*02*/ WORD res02; /* ?, 0xffff marks end */
|
||||
/*00*/ unsigned short vt; /* vartype, 0xffff marks end. */
|
||||
/*02*/ unsigned short res02; /* ?, 0xffff marks end */
|
||||
} SLTG_AliasItem;
|
||||
|
||||
#define SLTG_ALIASITEM_MAGIC 0x001d
|
||||
|
||||
|
||||
typedef struct {
|
||||
BYTE magic; /* 0x4c or 0x6c */
|
||||
BYTE inv; /* high nibble is INVOKE_KIND, low nibble = 2 */
|
||||
WORD next; /* byte offset from beginning of group to next fn */
|
||||
WORD name; /* Offset within name table to name */
|
||||
DWORD dispid; /* dispid */
|
||||
WORD helpcontext; /* helpcontext (again 1 is special) */
|
||||
WORD helpstring;/* helpstring offset to offset */
|
||||
WORD arg_off; /* offset to args from start of block */
|
||||
BYTE nacc; /* lowest 3bits are CALLCONV, rest are no of args */
|
||||
BYTE retnextopt;/* if 0x80 bit set ret type follows else next WORD
|
||||
unsigned char magic; /* 0x4c or 0x6c */
|
||||
unsigned char inv; /* high nibble is INVOKE_KIND, low nibble = 2 */
|
||||
unsigned short next; /* byte offset from beginning of group to next fn */
|
||||
unsigned short name; /* Offset within name table to name */
|
||||
unsigned int dispid; /* dispid */
|
||||
unsigned short helpcontext; /* helpcontext (again 1 is special) */
|
||||
unsigned short helpstring;/* helpstring offset to offset */
|
||||
unsigned short arg_off; /* offset to args from start of block */
|
||||
unsigned char nacc; /* lowest 3bits are CALLCONV, rest are no of args */
|
||||
unsigned char retnextopt;/* if 0x80 bit set ret type follows else next WORD
|
||||
is offset to ret type. No of optional args is
|
||||
middle 6 bits */
|
||||
WORD rettype; /* return type VT_?? or offset to ret type */
|
||||
WORD vtblpos; /* position in vtbl? */
|
||||
WORD funcflags; /* present if magic == 0x6c */
|
||||
unsigned short rettype; /* return type VT_?? or offset to ret type */
|
||||
unsigned short vtblpos; /* position in vtbl? */
|
||||
unsigned short funcflags; /* present if magic == 0x6c */
|
||||
/* Param list starts, repeat next two as required */
|
||||
#if 0
|
||||
WORD name; /* offset to 2nd letter of name */
|
||||
WORD+ type; /* VT_ of param */
|
||||
unsigned short name; /* offset to 2nd letter of name */
|
||||
unsigned short+ type; /* VT_ of param */
|
||||
#endif
|
||||
} SLTG_Function;
|
||||
|
||||
@@ -512,32 +492,32 @@ typedef struct {
|
||||
#define SLTG_FUNCTION_WITH_FLAGS_MAGIC 0x6c
|
||||
|
||||
typedef struct {
|
||||
/*00*/ BYTE magic; /* 0xdf */
|
||||
/*01*/ BYTE res01; /* 0x00 */
|
||||
/*02*/ DWORD res02; /* 0xffffffff */
|
||||
/*06*/ DWORD res06; /* 0xffffffff */
|
||||
/*0a*/ DWORD res0a; /* 0xffffffff */
|
||||
/*0e*/ DWORD res0e; /* 0xffffffff */
|
||||
/*12*/ DWORD res12; /* 0xffffffff */
|
||||
/*16*/ DWORD res16; /* 0xffffffff */
|
||||
/*1a*/ DWORD res1a; /* 0xffffffff */
|
||||
/*1e*/ DWORD res1e; /* 0xffffffff */
|
||||
/*22*/ DWORD res22; /* 0xffffffff */
|
||||
/*26*/ DWORD res26; /* 0xffffffff */
|
||||
/*2a*/ DWORD res2a; /* 0xffffffff */
|
||||
/*2e*/ DWORD res2e; /* 0xffffffff */
|
||||
/*32*/ DWORD res32; /* 0xffffffff */
|
||||
/*36*/ DWORD res36; /* 0xffffffff */
|
||||
/*3a*/ DWORD res3a; /* 0xffffffff */
|
||||
/*3e*/ DWORD res3e; /* 0xffffffff */
|
||||
/*42*/ WORD res42; /* 0xffff */
|
||||
/*44*/ DWORD number; /* this is 8 times the number of refs */
|
||||
/*00*/ unsigned char magic; /* 0xdf */
|
||||
/*01*/ unsigned char res01; /* 0x00 */
|
||||
/*02*/ unsigned int res02; /* 0xffffffff */
|
||||
/*06*/ unsigned int res06; /* 0xffffffff */
|
||||
/*0a*/ unsigned int res0a; /* 0xffffffff */
|
||||
/*0e*/ unsigned int res0e; /* 0xffffffff */
|
||||
/*12*/ unsigned int res12; /* 0xffffffff */
|
||||
/*16*/ unsigned int res16; /* 0xffffffff */
|
||||
/*1a*/ unsigned int res1a; /* 0xffffffff */
|
||||
/*1e*/ unsigned int res1e; /* 0xffffffff */
|
||||
/*22*/ unsigned int res22; /* 0xffffffff */
|
||||
/*26*/ unsigned int res26; /* 0xffffffff */
|
||||
/*2a*/ unsigned int res2a; /* 0xffffffff */
|
||||
/*2e*/ unsigned int res2e; /* 0xffffffff */
|
||||
/*32*/ unsigned int res32; /* 0xffffffff */
|
||||
/*36*/ unsigned int res36; /* 0xffffffff */
|
||||
/*3a*/ unsigned int res3a; /* 0xffffffff */
|
||||
/*3e*/ unsigned int res3e; /* 0xffffffff */
|
||||
/*42*/ unsigned short res42; /* 0xffff */
|
||||
/*44*/ unsigned int number; /* this is 8 times the number of refs */
|
||||
/*48*/ /* Now we have number bytes (8 for each ref) of SLTG_UnknownRefInfo */
|
||||
|
||||
/*50*/ WORD res50; /* 0xffff */
|
||||
/*52*/ BYTE res52; /* 0x01 */
|
||||
/*53*/ DWORD res53; /* 0x00000000 */
|
||||
/*57*/ SLTG_Name names[1];
|
||||
/*50*/ unsigned short res50; /* 0xffff */
|
||||
/*52*/ unsigned char res52; /* 0x01 */
|
||||
/*53*/ unsigned int res53; /* 0x00000000 */
|
||||
/*57*/ SLTG_Name names[1];
|
||||
/* Now we have number/8 SLTG_Names (first WORD is no of bytes in the ascii
|
||||
* string). Strings look like "*\Rxxxx*#n". If xxxx == ffff then the
|
||||
* ref refers to the nth type listed in this library (0 based). Else
|
||||
@@ -547,47 +527,47 @@ typedef struct {
|
||||
* the imported typelib.
|
||||
*/
|
||||
|
||||
/*xx*/ BYTE resxx; /* 0xdf */
|
||||
/*xx*/ unsigned char resxx; /* 0xdf */
|
||||
|
||||
} SLTG_RefInfo;
|
||||
|
||||
#define SLTG_REF_MAGIC 0xdf
|
||||
|
||||
typedef struct {
|
||||
WORD res00; /* 0x0001 */
|
||||
BYTE res02; /* 0x02 */
|
||||
BYTE res03; /* 0x40 if internal ref, 0x00 if external ? */
|
||||
WORD res04; /* 0xffff */
|
||||
WORD res06; /* 0x0000, 0x0013 or 0xffff ?? */
|
||||
unsigned short res00; /* 0x0001 */
|
||||
unsigned char res02; /* 0x02 */
|
||||
unsigned char res03; /* 0x40 if internal ref, 0x00 if external ? */
|
||||
unsigned short res04; /* 0xffff */
|
||||
unsigned short res06; /* 0x0000, 0x0013 or 0xffff ?? */
|
||||
} SLTG_UnknownRefInfo;
|
||||
|
||||
typedef struct {
|
||||
WORD res00; /* 0x004a */
|
||||
WORD next; /* byte offs to next interface */
|
||||
WORD res04; /* 0xffff */
|
||||
BYTE impltypeflags; /* IMPLTYPEFLAG_* */
|
||||
BYTE res07; /* 0x80 */
|
||||
WORD res08; /* 0x0012, 0x0028 ?? */
|
||||
WORD ref; /* number in ref table ? */
|
||||
WORD res0c; /* 0x4000 */
|
||||
WORD res0e; /* 0xfffe */
|
||||
WORD res10; /* 0xffff */
|
||||
WORD res12; /* 0x001d */
|
||||
WORD pos_in_table; /* 0x0, 0x4, ? */
|
||||
unsigned short res00; /* 0x004a */
|
||||
unsigned short next; /* byte offs to next interface */
|
||||
unsigned short res04; /* 0xffff */
|
||||
unsigned char impltypeflags; /* IMPLTYPEFLAG_* */
|
||||
unsigned char res07; /* 0x80 */
|
||||
unsigned short res08; /* 0x0012, 0x0028 ?? */
|
||||
unsigned short ref; /* number in ref table ? */
|
||||
unsigned short res0c; /* 0x4000 */
|
||||
unsigned short res0e; /* 0xfffe */
|
||||
unsigned short res10; /* 0xffff */
|
||||
unsigned short res12; /* 0x001d */
|
||||
unsigned short pos_in_table; /* 0x0, 0x4, ? */
|
||||
} SLTG_ImplInfo;
|
||||
|
||||
#define SLTG_IMPL_MAGIC 0x004a
|
||||
|
||||
typedef struct {
|
||||
BYTE magic; /* 0x0a */
|
||||
BYTE typepos;
|
||||
WORD next;
|
||||
WORD name;
|
||||
WORD byte_offs; /* pos in struct */
|
||||
WORD type; /* if typepos == 0x02 this is the type, else offset to type */
|
||||
DWORD memid;
|
||||
WORD helpcontext; /* ?? */
|
||||
WORD helpstring; /* ?? */
|
||||
unsigned char magic; /* 0x0a */
|
||||
unsigned char typepos;
|
||||
unsigned short next;
|
||||
unsigned short name;
|
||||
unsigned short byte_offs; /* pos in struct */
|
||||
unsigned short type; /* if typepos == 0x02 this is the type, else offset to type */
|
||||
unsigned int memid;
|
||||
unsigned short helpcontext; /* ?? */
|
||||
unsigned short helpstring; /* ?? */
|
||||
} SLTG_RecordItem;
|
||||
|
||||
#define SLTG_RECORD_MAGIC 0x0a
|
||||
|
||||
+974
-146
File diff suppressed because it is too large
Load Diff
+167
-38
@@ -20,6 +20,9 @@
|
||||
|
||||
#include "widltypes.h"
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#ifndef WIDL_TYPE_TREE_H
|
||||
#define WIDL_TYPE_TREE_H
|
||||
@@ -29,29 +32,63 @@ enum name_type {
|
||||
NAME_C
|
||||
};
|
||||
|
||||
type_t *find_parameterized_type(type_t *type, typeref_list_t *params);
|
||||
|
||||
type_t *type_new_function(var_list_t *args);
|
||||
type_t *type_new_pointer(unsigned char pointer_default, type_t *ref, attr_list_t *attrs);
|
||||
type_t *type_new_alias(type_t *t, const char *name);
|
||||
type_t *type_new_module(char *name);
|
||||
type_t *type_new_array(const char *name, type_t *element, int declptr,
|
||||
unsigned int dim, expr_t *size_is, expr_t *length_is,
|
||||
unsigned char ptr_default_fc);
|
||||
type_t *type_new_pointer(type_t *ref);
|
||||
type_t *type_new_alias(const decl_spec_t *t, const char *name);
|
||||
type_t *type_module_declare(char *name);
|
||||
type_t *type_new_array(const char *name, const decl_spec_t *element, int declptr,
|
||||
unsigned int dim, expr_t *size_is, expr_t *length_is);
|
||||
type_t *type_new_basic(enum type_basic_type basic_type);
|
||||
type_t *type_new_int(enum type_basic_type basic_type, int sign);
|
||||
type_t *type_new_void(void);
|
||||
type_t *type_new_coclass(char *name);
|
||||
type_t *type_new_enum(const char *name, struct namespace *namespace, int defined, var_list_t *enums);
|
||||
type_t *type_new_struct(char *name, struct namespace *namespace, int defined, var_list_t *fields);
|
||||
type_t *type_new_nonencapsulated_union(const char *name, int defined, var_list_t *fields);
|
||||
type_t *type_new_encapsulated_union(char *name, var_t *switch_field, var_t *union_field, var_list_t *cases);
|
||||
type_t *type_coclass_declare(char *name);
|
||||
type_t *type_new_enum(const char *name, struct namespace *namespace,
|
||||
int defined, var_list_t *enums, const struct location *where);
|
||||
type_t *type_new_struct(char *name, struct namespace *namespace,
|
||||
int defined, var_list_t *fields, const struct location *where);
|
||||
type_t *type_new_nonencapsulated_union(const char *name, struct namespace *namespace,
|
||||
int defined, var_list_t *fields, const struct location *where);
|
||||
type_t *type_new_encapsulated_union(char *name, var_t *switch_field,
|
||||
var_t *union_field, var_list_t *cases, const struct location *where);
|
||||
type_t *type_new_bitfield(type_t *field_type, const expr_t *bits);
|
||||
void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stmts);
|
||||
void type_dispinterface_define(type_t *iface, var_list_t *props, var_list_t *methods);
|
||||
void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface);
|
||||
void type_module_define(type_t *module, statement_list_t *stmts);
|
||||
type_t *type_coclass_define(type_t *coclass, ifref_list_t *ifaces);
|
||||
type_t *type_runtimeclass_declare(char *name, struct namespace *namespace);
|
||||
type_t *type_interface_declare(char *name, struct namespace *namespace);
|
||||
type_t *type_interface_define(type_t *iface, attr_list_t *attrs, type_t *inherit,
|
||||
statement_list_t *stmts, typeref_list_t *requires, const struct location *where);
|
||||
type_t *type_dispinterface_declare(char *name);
|
||||
type_t *type_dispinterface_define(type_t *iface, attr_list_t *attrs,
|
||||
var_list_t *props, var_list_t *methods, const struct location *where);
|
||||
type_t *type_dispinterface_define_from_iface(type_t *dispiface,
|
||||
attr_list_t *attrs, type_t *iface, const struct location *where);
|
||||
type_t *type_module_define(type_t* module, attr_list_t *attrs,
|
||||
statement_list_t *stmts, const struct location *where);
|
||||
type_t *type_coclass_define(type_t *coclass, attr_list_t *attrs,
|
||||
typeref_list_t *ifaces, const struct location *where);
|
||||
type_t *type_runtimeclass_define(type_t *runtimeclass, attr_list_t *attrs,
|
||||
typeref_list_t *ifaces, const struct location *where);
|
||||
type_t *type_apicontract_declare(char *name, struct namespace *namespace);
|
||||
type_t *type_apicontract_define(type_t *apicontract, attr_list_t *attrs, const struct location *where);
|
||||
type_t *type_delegate_declare(char *name, struct namespace *namespace);
|
||||
type_t *type_delegate_define(type_t *delegate, attr_list_t *attrs,
|
||||
statement_list_t *stmts, const struct location *where);
|
||||
type_t *type_parameterized_interface_declare(char *name, struct namespace *namespace, typeref_list_t *params);
|
||||
type_t *type_parameterized_interface_define(type_t *type, attr_list_t *attrs, type_t *inherit,
|
||||
statement_list_t *stmts, typeref_list_t *requires, const struct location *where);
|
||||
type_t *type_parameterized_delegate_declare(char *name, struct namespace *namespace, typeref_list_t *params);
|
||||
type_t *type_parameterized_delegate_define(type_t *type, attr_list_t *attrs,
|
||||
statement_list_t *stmts, const struct location *where);
|
||||
type_t *type_parameterized_type_specialize_partial(type_t *type, typeref_list_t *params);
|
||||
type_t *type_parameterized_type_specialize_declare(type_t *type, typeref_list_t *params);
|
||||
type_t *type_parameterized_type_specialize_define(type_t *type);
|
||||
int type_is_equal(const type_t *type1, const type_t *type2);
|
||||
const char *type_get_decl_name(const type_t *type, enum name_type name_type);
|
||||
const char *type_get_name(const type_t *type, enum name_type name_type);
|
||||
char *gen_name(void);
|
||||
|
||||
typeref_t *make_typeref(type_t *type);
|
||||
typeref_list_t *append_typeref(typeref_list_t *list, typeref_t *ref);
|
||||
|
||||
/* FIXME: shouldn't need to export this */
|
||||
type_t *duptype(type_t *t, int dupname);
|
||||
@@ -59,8 +96,16 @@ type_t *duptype(type_t *t, int dupname);
|
||||
/* un-alias the type until finding the non-alias type */
|
||||
static inline type_t *type_get_real_type(const type_t *type)
|
||||
{
|
||||
if (type->is_alias)
|
||||
return type_get_real_type(type->orig);
|
||||
if (type->type_type == TYPE_ALIAS)
|
||||
return type_get_real_type(type->details.alias.aliasee.type);
|
||||
else
|
||||
return (type_t *)type;
|
||||
}
|
||||
|
||||
static inline type_t *type_parameterized_type_get_real_type(const type_t *type)
|
||||
{
|
||||
if (type->type_type == TYPE_PARAMETERIZED_TYPE)
|
||||
return type_parameterized_type_get_real_type(type->details.parameterized.type);
|
||||
else
|
||||
return (type_t *)type;
|
||||
}
|
||||
@@ -105,9 +150,14 @@ static inline var_t *type_function_get_retval(const type_t *type)
|
||||
return type->details.function->retval;
|
||||
}
|
||||
|
||||
static inline const decl_spec_t *type_function_get_ret(const type_t *type)
|
||||
{
|
||||
return &type_function_get_retval(type)->declspec;
|
||||
}
|
||||
|
||||
static inline type_t *type_function_get_rettype(const type_t *type)
|
||||
{
|
||||
return type_function_get_retval(type)->type;
|
||||
return type_function_get_retval(type)->declspec.type;
|
||||
}
|
||||
|
||||
static inline var_list_t *type_enum_get_values(const type_t *type)
|
||||
@@ -142,7 +192,7 @@ static inline var_list_t *type_union_get_cases(const type_t *type)
|
||||
if (type_type == TYPE_ENCAPSULATED_UNION)
|
||||
{
|
||||
const var_t *uv = LIST_ENTRY(list_tail(type->details.structure->fields), const var_t, entry);
|
||||
return uv->type->details.structure->fields;
|
||||
return uv->declspec.type->details.structure->fields;
|
||||
}
|
||||
else
|
||||
return type->details.structure->fields;
|
||||
@@ -162,6 +212,20 @@ static inline type_t *type_iface_get_inherit(const type_t *type)
|
||||
return type->details.iface->inherit;
|
||||
}
|
||||
|
||||
static inline typeref_list_t *type_iface_get_requires(const type_t *type)
|
||||
{
|
||||
type = type_get_real_type(type);
|
||||
assert(type_get_type(type) == TYPE_INTERFACE);
|
||||
return type->details.iface->requires;
|
||||
}
|
||||
|
||||
static inline type_t *type_iface_get_async_iface(const type_t *type)
|
||||
{
|
||||
type = type_get_real_type(type);
|
||||
assert(type_get_type(type) == TYPE_INTERFACE);
|
||||
return type->details.iface->async_iface;
|
||||
}
|
||||
|
||||
static inline var_list_t *type_dispiface_get_props(const type_t *type)
|
||||
{
|
||||
type = type_get_real_type(type);
|
||||
@@ -210,7 +274,14 @@ static inline int type_is_complete(const type_t *type)
|
||||
case TYPE_POINTER:
|
||||
case TYPE_ARRAY:
|
||||
case TYPE_BITFIELD:
|
||||
case TYPE_RUNTIMECLASS:
|
||||
case TYPE_DELEGATE:
|
||||
return TRUE;
|
||||
case TYPE_APICONTRACT:
|
||||
case TYPE_PARAMETERIZED_TYPE:
|
||||
case TYPE_PARAMETER:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
@@ -250,11 +321,30 @@ static inline expr_t *type_array_get_variance(const type_t *type)
|
||||
return type->details.array.length_is;
|
||||
}
|
||||
|
||||
static inline type_t *type_array_get_element(const type_t *type)
|
||||
static inline unsigned short type_array_get_ptr_tfsoff(const type_t *type)
|
||||
{
|
||||
type = type_get_real_type(type);
|
||||
assert(type_get_type(type) == TYPE_ARRAY);
|
||||
return type->details.array.elem;
|
||||
return type->details.array.ptr_tfsoff;
|
||||
}
|
||||
|
||||
static inline void type_array_set_ptr_tfsoff(type_t *type, unsigned short ptr_tfsoff)
|
||||
{
|
||||
type = type_get_real_type(type);
|
||||
assert(type_get_type(type) == TYPE_ARRAY);
|
||||
type->details.array.ptr_tfsoff = ptr_tfsoff;
|
||||
}
|
||||
|
||||
static inline const decl_spec_t *type_array_get_element(const type_t *type)
|
||||
{
|
||||
type = type_get_real_type(type);
|
||||
assert(type_get_type(type) == TYPE_ARRAY);
|
||||
return &type->details.array.elem;
|
||||
}
|
||||
|
||||
static inline type_t *type_array_get_element_type(const type_t *type)
|
||||
{
|
||||
return type_array_get_element(type)->type;
|
||||
}
|
||||
|
||||
static inline int type_array_is_decl_as_ptr(const type_t *type)
|
||||
@@ -264,43 +354,82 @@ static inline int type_array_is_decl_as_ptr(const type_t *type)
|
||||
return type->details.array.declptr;
|
||||
}
|
||||
|
||||
static inline unsigned char type_array_get_ptr_default_fc(const type_t *type)
|
||||
{
|
||||
type = type_get_real_type(type);
|
||||
assert(type_get_type(type) == TYPE_ARRAY);
|
||||
return type->details.array.ptr_def_fc;
|
||||
}
|
||||
|
||||
static inline int type_is_alias(const type_t *type)
|
||||
{
|
||||
return type->is_alias;
|
||||
return type->type_type == TYPE_ALIAS;
|
||||
}
|
||||
|
||||
static inline type_t *type_alias_get_aliasee(const type_t *type)
|
||||
static inline int type_is_ptr( const type_t *type )
|
||||
{
|
||||
return type->type_type == TYPE_POINTER;
|
||||
}
|
||||
|
||||
static inline const decl_spec_t *type_alias_get_aliasee(const type_t *type)
|
||||
{
|
||||
assert(type_is_alias(type));
|
||||
return type->orig;
|
||||
return &type->details.alias.aliasee;
|
||||
}
|
||||
|
||||
static inline ifref_list_t *type_coclass_get_ifaces(const type_t *type)
|
||||
static inline type_t *type_alias_get_aliasee_type(const type_t *type)
|
||||
{
|
||||
assert(type_is_alias(type));
|
||||
return type->details.alias.aliasee.type;
|
||||
}
|
||||
|
||||
static inline typeref_list_t *type_coclass_get_ifaces(const type_t *type)
|
||||
{
|
||||
type = type_get_real_type(type);
|
||||
assert(type_get_type(type) == TYPE_COCLASS);
|
||||
return type->details.coclass.ifaces;
|
||||
}
|
||||
|
||||
static inline type_t *type_pointer_get_ref(const type_t *type)
|
||||
static inline typeref_list_t *type_runtimeclass_get_ifaces(const type_t *type)
|
||||
{
|
||||
type = type_get_real_type(type);
|
||||
assert(type_get_type(type) == TYPE_POINTER);
|
||||
return type->details.pointer.ref;
|
||||
assert(type_get_type(type) == TYPE_RUNTIMECLASS);
|
||||
return type->details.runtimeclass.ifaces;
|
||||
}
|
||||
|
||||
static inline unsigned char type_pointer_get_default_fc(const type_t *type)
|
||||
static inline type_t *type_runtimeclass_get_default_iface(const type_t *type, int check)
|
||||
{
|
||||
typeref_list_t *ifaces = type_runtimeclass_get_ifaces(type);
|
||||
typeref_t *ref;
|
||||
|
||||
if (ifaces) LIST_FOR_EACH_ENTRY(ref, ifaces, typeref_t, entry)
|
||||
if (is_attr(ref->attrs, ATTR_DEFAULT))
|
||||
return ref->type;
|
||||
|
||||
if (!check) return NULL;
|
||||
error_at( &type->where, "runtimeclass %s needs a default interface\n", type->name );
|
||||
|
||||
#ifdef __REACTOS__
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline type_t *type_delegate_get_iface(const type_t *type)
|
||||
{
|
||||
type = type_get_real_type(type);
|
||||
assert(type_get_type(type) == TYPE_DELEGATE);
|
||||
return type->details.delegate.iface;
|
||||
}
|
||||
|
||||
static inline const decl_spec_t *type_pointer_get_ref(const type_t *type)
|
||||
{
|
||||
type = type_get_real_type(type);
|
||||
assert(type_get_type(type) == TYPE_POINTER);
|
||||
return type->details.pointer.def_fc;
|
||||
return &type->details.pointer.ref;
|
||||
}
|
||||
|
||||
static inline type_t *type_pointer_get_ref_type(const type_t *type)
|
||||
{
|
||||
return type_pointer_get_ref(type)->type;
|
||||
}
|
||||
|
||||
static inline type_t *type_pointer_get_root_type(type_t *type)
|
||||
{
|
||||
for (; type && type->type_type == TYPE_POINTER; type = type_pointer_get_ref_type(type)) {}
|
||||
return type;
|
||||
}
|
||||
|
||||
static inline type_t *type_bitfield_get_field(const type_t *type)
|
||||
|
||||
+47
-219
@@ -20,7 +20,6 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "wine/port.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
@@ -33,72 +32,17 @@
|
||||
#include "utils.h"
|
||||
#include "parser.h"
|
||||
|
||||
#define CURRENT_LOCATION { input_name ? input_name : "stdin", line_number, parser_text }
|
||||
|
||||
static const int want_near_indication = 0;
|
||||
|
||||
static void make_print(char *str)
|
||||
void error_at( const struct location *where, const char *s, ... )
|
||||
{
|
||||
while(*str)
|
||||
{
|
||||
if(!isprint(*str))
|
||||
*str = ' ';
|
||||
str++;
|
||||
}
|
||||
}
|
||||
char buffer[1024];
|
||||
|
||||
static void generic_msg(const loc_info_t *loc_info, const char *s, const char *t, va_list ap)
|
||||
{
|
||||
fprintf(stderr, "%s:%d: %s: ", loc_info->input_name, loc_info->line_number, t);
|
||||
vfprintf(stderr, s, ap);
|
||||
va_list ap;
|
||||
va_start( ap, s );
|
||||
vsnprintf( buffer, sizeof(buffer), s, ap );
|
||||
va_end( ap );
|
||||
|
||||
if (want_near_indication)
|
||||
{
|
||||
char *cpy;
|
||||
if(loc_info->near_text)
|
||||
{
|
||||
cpy = xstrdup(loc_info->near_text);
|
||||
make_print(cpy);
|
||||
fprintf(stderr, " near '%s'", cpy);
|
||||
free(cpy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void error_loc(const char *s, ...)
|
||||
{
|
||||
loc_info_t cur_loc = CURRENT_LOCATION;
|
||||
va_list ap;
|
||||
va_start(ap, s);
|
||||
generic_msg(&cur_loc, s, "error", ap);
|
||||
va_end(ap);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* yyerror: yacc assumes this is not newline terminated. */
|
||||
void parser_error(const char *s)
|
||||
{
|
||||
error_loc("%s\n", s);
|
||||
}
|
||||
|
||||
void error_loc_info(const loc_info_t *loc_info, const char *s, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, s);
|
||||
generic_msg(loc_info, s, "error", ap);
|
||||
va_end(ap);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int parser_warning(const char *s, ...)
|
||||
{
|
||||
loc_info_t cur_loc = CURRENT_LOCATION;
|
||||
va_list ap;
|
||||
va_start(ap, s);
|
||||
generic_msg(&cur_loc, s, "warning", ap);
|
||||
va_end(ap);
|
||||
return 0;
|
||||
parser_error( where, buffer );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
void error(const char *s, ...)
|
||||
@@ -120,12 +64,16 @@ void warning(const char *s, ...)
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void warning_loc_info(const loc_info_t *loc_info, const char *s, ...)
|
||||
void warning_at( const struct location *where, const char *s, ... )
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, s);
|
||||
generic_msg(loc_info, s, "warning", ap);
|
||||
va_end(ap);
|
||||
char buffer[1024];
|
||||
|
||||
va_list ap;
|
||||
va_start( ap, s );
|
||||
vsnprintf( buffer, sizeof(buffer), s, ap );
|
||||
va_end( ap );
|
||||
|
||||
parser_warning( where, buffer );
|
||||
}
|
||||
|
||||
void chat(const char *s, ...)
|
||||
@@ -140,35 +88,6 @@ void chat(const char *s, ...)
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
slash = strrchr(name, '\\');
|
||||
|
||||
if (slash)
|
||||
name = slash + 1;
|
||||
|
||||
namelen = strlen(name);
|
||||
|
||||
/* +6 for later extension (strlen("_r.rgs")) and +1 for '\0' */
|
||||
base = xmalloc(namelen +6 +1);
|
||||
strcpy(base, name);
|
||||
if(!strcasecmp(name + namelen-extlen, ext))
|
||||
{
|
||||
base[namelen - extlen] = '\0';
|
||||
}
|
||||
return base;
|
||||
}
|
||||
|
||||
size_t widl_getline(char **linep, size_t *lenp, FILE *fp)
|
||||
{
|
||||
char *line = *linep;
|
||||
@@ -198,48 +117,41 @@ size_t widl_getline(char **linep, size_t *lenp, FILE *fp)
|
||||
return n;
|
||||
}
|
||||
|
||||
void *xmalloc(size_t size)
|
||||
size_t strappend(char **buf, size_t *len, size_t pos, const char* fmt, ...)
|
||||
{
|
||||
void *res;
|
||||
size_t size;
|
||||
va_list ap;
|
||||
char *ptr;
|
||||
int n;
|
||||
|
||||
assert(size > 0);
|
||||
res = malloc(size);
|
||||
if(res == NULL)
|
||||
assert( buf && len );
|
||||
assert( (*len == 0 && *buf == NULL) || (*len != 0 && *buf != NULL) );
|
||||
|
||||
if (*buf)
|
||||
{
|
||||
error("Virtual memory exhausted.\n");
|
||||
size = *len;
|
||||
ptr = *buf;
|
||||
}
|
||||
memset(res, 0x55, size);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
void *xrealloc(void *p, size_t size)
|
||||
{
|
||||
void *res;
|
||||
|
||||
assert(size > 0);
|
||||
res = realloc(p, size);
|
||||
if(res == NULL)
|
||||
else
|
||||
{
|
||||
error("Virtual memory exhausted.\n");
|
||||
size = 100;
|
||||
ptr = xmalloc( size );
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
char *xstrdup(const char *str)
|
||||
{
|
||||
char *s;
|
||||
for (;;)
|
||||
{
|
||||
va_start( ap, fmt );
|
||||
n = vsnprintf( ptr + pos, size - pos, fmt, ap );
|
||||
va_end( ap );
|
||||
if (n == -1) size *= 2;
|
||||
else if (pos + (size_t)n >= size) size = pos + n + 1;
|
||||
else break;
|
||||
ptr = xrealloc( ptr, size );
|
||||
}
|
||||
|
||||
assert(str != NULL);
|
||||
s = xmalloc(strlen(str)+1);
|
||||
return strcpy(s, str);
|
||||
}
|
||||
|
||||
int strendswith(const char* str, const char* end)
|
||||
{
|
||||
int l = strlen(str);
|
||||
int m = strlen(end);
|
||||
return l >= m && strcmp(str + l - m, end) == 0;
|
||||
*len = size;
|
||||
*buf = ptr;
|
||||
return n;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
@@ -248,7 +160,6 @@ int strendswith(const char* str, const char* end)
|
||||
* Function for writing to a memory buffer.
|
||||
*/
|
||||
|
||||
int byte_swapped = 0;
|
||||
unsigned char *output_buffer;
|
||||
size_t output_buffer_pos;
|
||||
size_t output_buffer_size;
|
||||
@@ -260,32 +171,6 @@ static struct resource
|
||||
} resources[16];
|
||||
static unsigned int nb_resources;
|
||||
|
||||
static void check_output_buffer_space( size_t size )
|
||||
{
|
||||
if (output_buffer_pos + size >= output_buffer_size)
|
||||
{
|
||||
output_buffer_size = max( output_buffer_size * 2, output_buffer_pos + size );
|
||||
output_buffer = xrealloc( output_buffer, output_buffer_size );
|
||||
}
|
||||
}
|
||||
|
||||
void init_output_buffer(void)
|
||||
{
|
||||
output_buffer_size = 1024;
|
||||
output_buffer_pos = 0;
|
||||
output_buffer = xmalloc( output_buffer_size );
|
||||
}
|
||||
|
||||
void flush_output_buffer( const char *name )
|
||||
{
|
||||
int fd = open( name, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666 );
|
||||
if (fd == -1) error( "Error creating %s\n", name );
|
||||
if (write( fd, output_buffer, output_buffer_pos ) != output_buffer_pos)
|
||||
error( "Error writing to %s\n", name );
|
||||
close( fd );
|
||||
free( output_buffer );
|
||||
}
|
||||
|
||||
static inline void put_resource_id( const char *str )
|
||||
{
|
||||
if (str[0] != '#')
|
||||
@@ -309,7 +194,7 @@ void add_output_to_resources( const char *type, const char *name )
|
||||
size_t data_size = output_buffer_pos;
|
||||
size_t header_size = 5 * sizeof(unsigned int) + 2 * sizeof(unsigned short);
|
||||
|
||||
assert( nb_resources < sizeof(resources)/sizeof(resources[0]) );
|
||||
assert( nb_resources < ARRAY_SIZE( resources ));
|
||||
|
||||
if (type[0] != '#') header_size += (strlen( type ) + 1) * sizeof(unsigned short);
|
||||
else header_size += 2 * sizeof(unsigned short);
|
||||
@@ -340,7 +225,6 @@ void add_output_to_resources( const char *type, const char *name )
|
||||
|
||||
void flush_output_resources( const char *name )
|
||||
{
|
||||
int fd;
|
||||
unsigned int i;
|
||||
|
||||
/* all output must have been saved with add_output_to_resources() first */
|
||||
@@ -358,59 +242,13 @@ void flush_output_resources( const char *name )
|
||||
put_dword( 0 ); /* Version */
|
||||
put_dword( 0 ); /* Characteristics */
|
||||
|
||||
fd = open( name, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666 );
|
||||
if (fd == -1) error( "Error creating %s\n", name );
|
||||
if (write( fd, output_buffer, output_buffer_pos ) != output_buffer_pos)
|
||||
error( "Error writing to %s\n", name );
|
||||
for (i = 0; i < nb_resources; i++)
|
||||
{
|
||||
if (write( fd, resources[i].data, resources[i].size ) != resources[i].size)
|
||||
error( "Error writing to %s\n", name );
|
||||
put_data( resources[i].data, resources[i].size );
|
||||
free( resources[i].data );
|
||||
}
|
||||
close( fd );
|
||||
flush_output_buffer( name );
|
||||
nb_resources = 0;
|
||||
free( output_buffer );
|
||||
}
|
||||
|
||||
void put_data( const void *data, size_t size )
|
||||
{
|
||||
check_output_buffer_space( size );
|
||||
memcpy( output_buffer + output_buffer_pos, data, size );
|
||||
output_buffer_pos += size;
|
||||
}
|
||||
|
||||
void put_byte( unsigned char val )
|
||||
{
|
||||
check_output_buffer_space( 1 );
|
||||
output_buffer[output_buffer_pos++] = val;
|
||||
}
|
||||
|
||||
void put_word( unsigned short val )
|
||||
{
|
||||
if (byte_swapped) val = (val << 8) | (val >> 8);
|
||||
put_data( &val, sizeof(val) );
|
||||
}
|
||||
|
||||
void put_dword( unsigned int val )
|
||||
{
|
||||
if (byte_swapped)
|
||||
val = ((val << 24) | ((val << 8) & 0x00ff0000) | ((val >> 8) & 0x0000ff00) | (val >> 24));
|
||||
put_data( &val, sizeof(val) );
|
||||
}
|
||||
|
||||
void put_qword( unsigned int val )
|
||||
{
|
||||
if (byte_swapped)
|
||||
{
|
||||
put_dword( 0 );
|
||||
put_dword( val );
|
||||
}
|
||||
else
|
||||
{
|
||||
put_dword( val );
|
||||
put_dword( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
/* pointer-sized word */
|
||||
@@ -445,13 +283,3 @@ void put_str( int indent, const char *format, ... )
|
||||
check_output_buffer_space( size );
|
||||
}
|
||||
}
|
||||
|
||||
void align_output( unsigned int align )
|
||||
{
|
||||
size_t size = align - (output_buffer_pos % align);
|
||||
|
||||
if (size == align) return;
|
||||
check_output_buffer_space( size );
|
||||
memset( output_buffer + output_buffer_pos, 0, size );
|
||||
output_buffer_pos += size;
|
||||
}
|
||||
|
||||
+6
-40
@@ -22,52 +22,25 @@
|
||||
#define __WIDL_UTILS_H
|
||||
|
||||
#include "widltypes.h"
|
||||
#include "parser.h"
|
||||
|
||||
#include <stddef.h> /* size_t */
|
||||
|
||||
void *xmalloc(size_t);
|
||||
void *xrealloc(void *, size_t);
|
||||
char *xstrdup(const char *str);
|
||||
int strendswith(const char* str, const char* end);
|
||||
|
||||
#ifndef __GNUC__
|
||||
#define __attribute__(X)
|
||||
#endif
|
||||
|
||||
void parser_error(const char *s) __attribute__((noreturn));
|
||||
int parser_warning(const char *s, ...) __attribute__((format (printf, 1, 2)));
|
||||
void error_loc(const char *s, ...) __attribute__((format (printf, 1, 2))) __attribute__((noreturn));
|
||||
void error(const char *s, ...) __attribute__((format (printf, 1, 2))) __attribute__((noreturn));
|
||||
void error_loc_info(const loc_info_t *, const char *s, ...) __attribute__((format (printf, 2, 3))) __attribute__((noreturn));
|
||||
void error_at( const struct location *, const char *s, ... ) __attribute__((format( printf, 2, 3 ))) __attribute__((noreturn));
|
||||
#define error_loc( ... ) error_at( NULL, ## __VA_ARGS__ )
|
||||
void warning(const char *s, ...) __attribute__((format (printf, 1, 2)));
|
||||
void warning_loc_info(const loc_info_t *, const char *s, ...) __attribute__((format (printf, 2, 3)));
|
||||
void warning_at( const struct location *, const char *s, ... ) __attribute__((format( printf, 2, 3 )));
|
||||
#define warning_loc( ... ) warning_at( NULL, ## __VA_ARGS__ )
|
||||
void chat(const char *s, ...) __attribute__((format (printf, 1, 2)));
|
||||
size_t strappend(char **buf, size_t *len, size_t pos, const char* fmt, ...) __attribute__((__format__ (__printf__, 4, 5 )));
|
||||
|
||||
char *dup_basename(const char *name, const char *ext);
|
||||
size_t widl_getline(char **linep, size_t *lenp, FILE *fp);
|
||||
|
||||
UUID *parse_uuid(const char *u);
|
||||
int is_valid_uuid(const char *s);
|
||||
|
||||
/* buffer management */
|
||||
|
||||
extern int byte_swapped;
|
||||
extern unsigned char *output_buffer;
|
||||
extern size_t output_buffer_pos;
|
||||
extern size_t output_buffer_size;
|
||||
|
||||
extern void init_output_buffer(void);
|
||||
extern void flush_output_buffer( const char *name );
|
||||
extern void add_output_to_resources( const char *type, const char *name );
|
||||
extern void flush_output_resources( const char *name );
|
||||
extern void put_data( const void *data, size_t size );
|
||||
extern void put_byte( unsigned char val );
|
||||
extern void put_word( unsigned short val );
|
||||
extern void put_dword( unsigned int val );
|
||||
extern void put_qword( unsigned int val );
|
||||
extern void put_pword( unsigned int val );
|
||||
extern void put_str( int indent, const char *format, ... ) __attribute__((format (printf, 2, 3)));
|
||||
extern void align_output( unsigned int align );
|
||||
|
||||
/* typelibs expect the minor version to be stored in the higher bits and
|
||||
* major to be stored in the lower bits */
|
||||
@@ -75,11 +48,4 @@ extern void align_output( unsigned int align );
|
||||
#define MAJORVERSION(version) ((version) & 0xffff)
|
||||
#define MINORVERSION(version) (((version) >> 16) & 0xffff)
|
||||
|
||||
#ifndef max
|
||||
#define max(a,b) (((a) > (b)) ? (a) : (b))
|
||||
#endif
|
||||
#ifndef min
|
||||
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
+277
-334
@@ -20,33 +20,28 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "wine/port.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <signal.h>
|
||||
#ifdef HAVE_GETOPT_H
|
||||
# include <getopt.h>
|
||||
#endif
|
||||
#include <limits.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "widl.h"
|
||||
#include "utils.h"
|
||||
#include "parser.h"
|
||||
#include "wine/wpp.h"
|
||||
#include "wpp_private.h"
|
||||
#include "header.h"
|
||||
|
||||
static const char usage[] =
|
||||
"Usage: widl [options...] infile.idl\n"
|
||||
" or: widl [options...] --dlldata-only name1 [name2...]\n"
|
||||
" --acf=file Use ACF file\n"
|
||||
" --align=n Set structure packing to 'n'\n"
|
||||
" -app_config Ignored, present for midl compatibility\n"
|
||||
" -b arch Set the target architecture\n"
|
||||
" -c Generate client stub\n"
|
||||
@@ -56,30 +51,32 @@ static const char usage[] =
|
||||
" --help Display this help and exit\n"
|
||||
" -h Generate headers\n"
|
||||
" -H file Name of header file (default is infile.h)\n"
|
||||
" -I path Set include search dir to path (multiple -I allowed)\n"
|
||||
" -I directory Add directory to the include search path (multiple -I allowed)\n"
|
||||
" -L directory Add directory to the library search path (multiple -L allowed)\n"
|
||||
" --local-stubs=file Write empty stubs for call_as/local methods to file\n"
|
||||
" -m32, -m64 Set the target architecture (Win32 or Win64)\n"
|
||||
" -N Do not preprocess input\n"
|
||||
" --nostdinc Do not search the standard include path\n"
|
||||
" --ns_prefix Prefix namespaces with ABI namespace\n"
|
||||
" --oldnames Use old naming conventions\n"
|
||||
" --oldtlb Use old typelib (SLTG) format\n"
|
||||
" --oldtlb Generate typelib in the old format (SLTG)\n"
|
||||
" -o, --output=NAME Set the output file name\n"
|
||||
" -Otype Type of stubs to generate (-Os, -Oi, -Oif)\n"
|
||||
" -p Generate proxy\n"
|
||||
" --packing=n Set structure packing to 'n'\n"
|
||||
" --prefix-all=p Prefix names of client stubs / server functions with 'p'\n"
|
||||
" --prefix-client=p Prefix names of client stubs with 'p'\n"
|
||||
" --prefix-server=p Prefix names of server functions with 'p'\n"
|
||||
" -r Generate registration script\n"
|
||||
" -robust Ignored, present for midl compatibility\n"
|
||||
" --winrt Enable Windows Runtime mode\n"
|
||||
" --ns_prefix Prefix namespaces with ABI namespace\n"
|
||||
" --sysroot=DIR Prefix include paths with DIR\n"
|
||||
" -s Generate server stub\n"
|
||||
" -t Generate typelib\n"
|
||||
" -u Generate interface identifiers file\n"
|
||||
" -V Print version and exit\n"
|
||||
" -W Enable pedantic warnings\n"
|
||||
" --win32, --win64 Set the target architecture (Win32 or Win64)\n"
|
||||
" --win32-align n Set win32 structure alignment to 'n'\n"
|
||||
" --win64-align n Set win64 structure alignment to 'n'\n"
|
||||
" --winrt Enable Windows Runtime mode\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"
|
||||
@@ -92,19 +89,7 @@ static const char usage[] =
|
||||
static const char version_string[] = "Wine IDL Compiler version " PACKAGE_VERSION "\n"
|
||||
"Copyright 2002 Ove Kaaven\n";
|
||||
|
||||
#ifdef __i386__
|
||||
enum target_cpu target_cpu = CPU_x86;
|
||||
#elif defined(__x86_64__)
|
||||
enum target_cpu target_cpu = CPU_x86_64;
|
||||
#elif defined(__powerpc__)
|
||||
enum target_cpu target_cpu = CPU_POWERPC;
|
||||
#elif defined(__arm__)
|
||||
enum target_cpu target_cpu = CPU_ARM;
|
||||
#elif defined(__aarch64__)
|
||||
enum target_cpu target_cpu = CPU_ARM64;
|
||||
#else
|
||||
#error Unsupported CPU
|
||||
#endif
|
||||
struct target target = { 0 };
|
||||
|
||||
int debuglevel = DEBUGLEVEL_NONE;
|
||||
int parser_debug, yy_flex_debug;
|
||||
@@ -114,7 +99,6 @@ int do_everything = 1;
|
||||
static int preprocess_only = 0;
|
||||
int do_header = 0;
|
||||
int do_typelib = 0;
|
||||
int do_old_typelib = 0;
|
||||
int do_proxies = 0;
|
||||
int do_client = 0;
|
||||
int do_server = 0;
|
||||
@@ -123,14 +107,14 @@ int do_idfile = 0;
|
||||
int do_dlldata = 0;
|
||||
static int no_preprocess = 0;
|
||||
int old_names = 0;
|
||||
int win32_packing = 8;
|
||||
int win64_packing = 8;
|
||||
int old_typelib = 0;
|
||||
int winrt_mode = 0;
|
||||
int interpreted_mode = 1;
|
||||
int use_abi_namespace = 0;
|
||||
static enum stub_mode stub_mode = MODE_Os;
|
||||
static int stdinc = 1;
|
||||
|
||||
char *input_name;
|
||||
char *input_idl_name;
|
||||
char *idl_name;
|
||||
char *acf_name;
|
||||
char *header_name;
|
||||
char *local_stubs_name;
|
||||
@@ -146,14 +130,20 @@ char *server_token;
|
||||
char *regscript_name;
|
||||
char *regscript_token;
|
||||
static char *idfile_name;
|
||||
char *temp_name;
|
||||
struct strarray temp_files = { 0 };
|
||||
const char *temp_dir = NULL;
|
||||
const char *prefix_client = "";
|
||||
const char *prefix_server = "";
|
||||
|
||||
int line_number = 1;
|
||||
static const char *bindir;
|
||||
static const char *libdir;
|
||||
static const char *includedir;
|
||||
static struct strarray dlldirs;
|
||||
static char *output_name;
|
||||
static const char *sysroot = "";
|
||||
|
||||
static FILE *idfile;
|
||||
|
||||
unsigned int packing = 8;
|
||||
unsigned int pointer_size = 0;
|
||||
|
||||
time_t now;
|
||||
@@ -165,7 +155,9 @@ enum {
|
||||
DLLDATA_OPTION,
|
||||
DLLDATA_ONLY_OPTION,
|
||||
LOCAL_STUBS_OPTION,
|
||||
NOSTDINC_OPTION,
|
||||
OLD_TYPELIB_OPTION,
|
||||
PACKING_OPTION,
|
||||
PREFIX_ALL_OPTION,
|
||||
PREFIX_CLIENT_OPTION,
|
||||
PREFIX_SERVER_OPTION,
|
||||
@@ -173,60 +165,47 @@ enum {
|
||||
RT_NS_PREFIX,
|
||||
RT_OPTION,
|
||||
ROBUST_OPTION,
|
||||
SYSROOT_OPTION,
|
||||
WIN32_OPTION,
|
||||
WIN64_OPTION,
|
||||
WIN32_ALIGN_OPTION,
|
||||
WIN64_ALIGN_OPTION
|
||||
};
|
||||
|
||||
static const char short_options[] =
|
||||
"b:cC:d:D:EhH:I:m:No:O:pP:rsS:tT:uU:VW";
|
||||
static const struct option long_options[] = {
|
||||
{ "acf", 1, NULL, ACF_OPTION },
|
||||
{ "app_config", 0, NULL, APP_CONFIG_OPTION },
|
||||
{ "dlldata", 1, NULL, DLLDATA_OPTION },
|
||||
{ "dlldata-only", 0, NULL, DLLDATA_ONLY_OPTION },
|
||||
{ "help", 0, NULL, PRINT_HELP },
|
||||
{ "local-stubs", 1, NULL, LOCAL_STUBS_OPTION },
|
||||
{ "ns_prefix", 0, NULL, RT_NS_PREFIX },
|
||||
{ "oldnames", 0, NULL, OLDNAMES_OPTION },
|
||||
{ "oldtlb", 0, NULL, OLD_TYPELIB_OPTION },
|
||||
{ "output", 0, NULL, 'o' },
|
||||
{ "prefix-all", 1, NULL, PREFIX_ALL_OPTION },
|
||||
{ "prefix-client", 1, NULL, PREFIX_CLIENT_OPTION },
|
||||
{ "prefix-server", 1, NULL, PREFIX_SERVER_OPTION },
|
||||
{ "robust", 0, NULL, ROBUST_OPTION },
|
||||
{ "target", 0, NULL, 'b' },
|
||||
{ "winrt", 0, NULL, RT_OPTION },
|
||||
{ "win32", 0, NULL, WIN32_OPTION },
|
||||
{ "win64", 0, NULL, WIN64_OPTION },
|
||||
{ "win32-align", 1, NULL, WIN32_ALIGN_OPTION },
|
||||
{ "win64-align", 1, NULL, WIN64_ALIGN_OPTION },
|
||||
{ NULL, 0, NULL, 0 }
|
||||
"b:cC:d:D:EhH:I:L:m:No:O:pP:rsS:tT:uU:VW";
|
||||
static const struct long_option long_options[] = {
|
||||
{ "acf", 1, ACF_OPTION },
|
||||
{ "align", 1, PACKING_OPTION },
|
||||
{ "app_config", 0, APP_CONFIG_OPTION },
|
||||
{ "dlldata", 1, DLLDATA_OPTION },
|
||||
{ "dlldata-only", 0, DLLDATA_ONLY_OPTION },
|
||||
{ "help", 0, PRINT_HELP },
|
||||
{ "local-stubs", 1, LOCAL_STUBS_OPTION },
|
||||
{ "nostdinc", 0, NOSTDINC_OPTION },
|
||||
{ "ns_prefix", 0, RT_NS_PREFIX },
|
||||
{ "oldnames", 0, OLDNAMES_OPTION },
|
||||
{ "oldtlb", 0, OLD_TYPELIB_OPTION },
|
||||
{ "output", 0, 'o' },
|
||||
{ "packing", 1, PACKING_OPTION },
|
||||
{ "prefix-all", 1, PREFIX_ALL_OPTION },
|
||||
{ "prefix-client", 1, PREFIX_CLIENT_OPTION },
|
||||
{ "prefix-server", 1, PREFIX_SERVER_OPTION },
|
||||
{ "robust", 0, ROBUST_OPTION },
|
||||
{ "sysroot", 1, SYSROOT_OPTION },
|
||||
{ "target", 0, 'b' },
|
||||
{ "winrt", 0, RT_OPTION },
|
||||
{ "win32", 0, WIN32_OPTION },
|
||||
{ "win64", 0, WIN64_OPTION },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static void rm_tempfile(void);
|
||||
|
||||
enum stub_mode get_stub_mode(void)
|
||||
{
|
||||
/* old-style interpreted stubs are not supported on 64-bit */
|
||||
if (stub_mode == MODE_Oi && pointer_size == 8) return MODE_Oif;
|
||||
return stub_mode;
|
||||
}
|
||||
|
||||
static char *make_token(const char *name)
|
||||
{
|
||||
char *token;
|
||||
char *slash;
|
||||
int i;
|
||||
|
||||
slash = strrchr(name, '/');
|
||||
if(!slash)
|
||||
slash = strrchr(name, '\\');
|
||||
|
||||
if (slash) name = slash + 1;
|
||||
|
||||
token = xstrdup(name);
|
||||
token = get_basename( name );
|
||||
for (i=0; token[i]; i++) {
|
||||
if (!isalnum(token[i])) token[i] = '_';
|
||||
else token[i] = tolower(token[i]);
|
||||
@@ -237,7 +216,7 @@ static char *make_token(const char *name)
|
||||
/* duplicate a basename into a valid C token */
|
||||
static char *dup_basename_token(const char *name, const char *ext)
|
||||
{
|
||||
char *p, *ret = dup_basename( name, ext );
|
||||
char *p, *ret = replace_extension( get_basename(name), ext, "" );
|
||||
/* map invalid characters to '_' */
|
||||
for (p = ret; *p; p++) if (!isalnum(*p)) *p = '_';
|
||||
return ret;
|
||||
@@ -245,6 +224,7 @@ static char *dup_basename_token(const char *name, const char *ext)
|
||||
|
||||
static void add_widl_version_define(void)
|
||||
{
|
||||
char version_str[32];
|
||||
unsigned int version;
|
||||
const char *p = PACKAGE_VERSION;
|
||||
|
||||
@@ -263,58 +243,8 @@ static void add_widl_version_define(void)
|
||||
if (p)
|
||||
version += atoi(p + 1);
|
||||
|
||||
if (version != 0)
|
||||
{
|
||||
char version_str[11];
|
||||
snprintf(version_str, sizeof(version_str), "0x%x", version);
|
||||
wpp_add_define("__WIDL__", version_str);
|
||||
}
|
||||
else
|
||||
wpp_add_define("__WIDL__", NULL);
|
||||
}
|
||||
|
||||
/* set the target platform */
|
||||
static void set_target( const char *target )
|
||||
{
|
||||
static const struct
|
||||
{
|
||||
const char *name;
|
||||
enum target_cpu cpu;
|
||||
} cpu_names[] =
|
||||
{
|
||||
{ "i386", CPU_x86 },
|
||||
{ "i486", CPU_x86 },
|
||||
{ "i586", CPU_x86 },
|
||||
{ "i686", CPU_x86 },
|
||||
{ "i786", CPU_x86 },
|
||||
{ "amd64", CPU_x86_64 },
|
||||
{ "x86_64", CPU_x86_64 },
|
||||
{ "powerpc", CPU_POWERPC },
|
||||
{ "arm", CPU_ARM },
|
||||
{ "armv5", CPU_ARM },
|
||||
{ "armv6", CPU_ARM },
|
||||
{ "armv7", CPU_ARM },
|
||||
{ "arm64", CPU_ARM64 },
|
||||
{ "aarch64", CPU_ARM64 },
|
||||
};
|
||||
|
||||
unsigned int i;
|
||||
char *p, *spec = xstrdup( target );
|
||||
|
||||
/* target specification is in the form CPU-MANUFACTURER-OS or CPU-MANUFACTURER-KERNEL-OS */
|
||||
|
||||
if (!(p = strchr( spec, '-' ))) error( "Invalid target specification '%s'\n", target );
|
||||
*p++ = 0;
|
||||
for (i = 0; i < sizeof(cpu_names)/sizeof(cpu_names[0]); i++)
|
||||
{
|
||||
if (!strcmp( cpu_names[i].name, spec ))
|
||||
{
|
||||
target_cpu = cpu_names[i].cpu;
|
||||
free( spec );
|
||||
return;
|
||||
}
|
||||
}
|
||||
error( "Unrecognized CPU '%s'\n", spec );
|
||||
snprintf(version_str, sizeof(version_str), "__WIDL__=0x%x", version);
|
||||
wpp_add_cmdline_define(version_str);
|
||||
}
|
||||
|
||||
/* clean things up when aborting on a signal */
|
||||
@@ -327,7 +257,6 @@ static void set_everything(int x)
|
||||
{
|
||||
do_header = x;
|
||||
do_typelib = x;
|
||||
do_old_typelib = x;
|
||||
do_proxies = x;
|
||||
do_client = x;
|
||||
do_server = x;
|
||||
@@ -350,33 +279,10 @@ void end_cplusplus_guard(FILE *fp)
|
||||
fprintf(fp, "#endif\n\n");
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *filename;
|
||||
struct list link;
|
||||
} filename_node_t;
|
||||
|
||||
static void add_filename_node(struct list *list, const char *name)
|
||||
{
|
||||
filename_node_t *node = xmalloc(sizeof *node);
|
||||
node->filename = dup_basename( name, ".idl" );
|
||||
list_add_tail(list, &node->link);
|
||||
}
|
||||
|
||||
static void free_filename_nodes(struct list *list)
|
||||
{
|
||||
filename_node_t *node, *next;
|
||||
LIST_FOR_EACH_ENTRY_SAFE(node, next, list, filename_node_t, link) {
|
||||
list_remove(&node->link);
|
||||
free(node->filename);
|
||||
free(node);
|
||||
}
|
||||
}
|
||||
|
||||
static void write_dlldata_list(struct list *filenames, int define_proxy_delegation)
|
||||
static void write_dlldata_list( struct strarray filenames, int define_proxy_delegation)
|
||||
{
|
||||
FILE *dlldata;
|
||||
filename_node_t *node;
|
||||
unsigned int i;
|
||||
|
||||
dlldata = fopen(dlldata_name, "w");
|
||||
if (!dlldata)
|
||||
@@ -387,22 +293,24 @@ static void write_dlldata_list(struct list *filenames, int define_proxy_delegati
|
||||
if (define_proxy_delegation)
|
||||
fprintf(dlldata, "#define PROXY_DELEGATION\n");
|
||||
|
||||
#ifdef __REACTOS__
|
||||
fprintf(dlldata, "#ifdef __REACTOS__\n");
|
||||
fprintf(dlldata, "#define WIN32_NO_STATUS\n");
|
||||
fprintf(dlldata, "#define WIN32_LEAN_AND_MEAN\n");
|
||||
fprintf(dlldata, "#endif\n\n");
|
||||
#endif
|
||||
|
||||
fprintf(dlldata, "#include <objbase.h>\n");
|
||||
fprintf(dlldata, "#include <rpcproxy.h>\n\n");
|
||||
start_cplusplus_guard(dlldata);
|
||||
|
||||
LIST_FOR_EACH_ENTRY(node, filenames, filename_node_t, link)
|
||||
fprintf(dlldata, "EXTERN_PROXY_FILE(%s)\n", node->filename);
|
||||
for (i = 0; i < filenames.count; i++)
|
||||
fprintf(dlldata, "EXTERN_PROXY_FILE(%s)\n", filenames.str[i]);
|
||||
|
||||
fprintf(dlldata, "\nPROXYFILE_LIST_START\n");
|
||||
fprintf(dlldata, "/* Start of list */\n");
|
||||
LIST_FOR_EACH_ENTRY(node, filenames, filename_node_t, link)
|
||||
fprintf(dlldata, " REFERENCE_PROXY_FILE(%s),\n", node->filename);
|
||||
for (i = 0; i < filenames.count; i++)
|
||||
fprintf(dlldata, " REFERENCE_PROXY_FILE(%s),\n", filenames.str[i]);
|
||||
fprintf(dlldata, "/* End of list */\n");
|
||||
fprintf(dlldata, "PROXYFILE_LIST_END\n\n");
|
||||
|
||||
@@ -420,9 +328,8 @@ static char *eat_space(char *s)
|
||||
|
||||
void write_dlldata(const statement_list_t *stmts)
|
||||
{
|
||||
struct list filenames = LIST_INIT(filenames);
|
||||
struct strarray filenames = empty_strarray;
|
||||
int define_proxy_delegation = 0;
|
||||
filename_node_t *node;
|
||||
FILE *dlldata;
|
||||
|
||||
if (!do_dlldata || !need_proxy_file(stmts))
|
||||
@@ -453,7 +360,7 @@ void write_dlldata(const statement_list_t *stmts)
|
||||
--end;
|
||||
*end = '\0';
|
||||
if (start < end)
|
||||
add_filename_node(&filenames, start);
|
||||
strarray_add(&filenames, replace_extension( get_basename( start ), ".idl", "" ));
|
||||
}else if (!define_proxy_delegation && strncmp(start, delegation_define, sizeof(delegation_define)-1)) {
|
||||
define_proxy_delegation = 1;
|
||||
}
|
||||
@@ -466,19 +373,15 @@ void write_dlldata(const statement_list_t *stmts)
|
||||
fclose(dlldata);
|
||||
}
|
||||
|
||||
LIST_FOR_EACH_ENTRY(node, &filenames, filename_node_t, link)
|
||||
if (strcmp(proxy_token, node->filename) == 0) {
|
||||
if (strarray_exists( &filenames, proxy_token ))
|
||||
/* We're already in the list, no need to regenerate this file. */
|
||||
free_filename_nodes(&filenames);
|
||||
return;
|
||||
}
|
||||
|
||||
add_filename_node(&filenames, proxy_token);
|
||||
write_dlldata_list(&filenames, define_proxy_delegation);
|
||||
free_filename_nodes(&filenames);
|
||||
strarray_add(&filenames, proxy_token);
|
||||
write_dlldata_list(filenames, define_proxy_delegation);
|
||||
}
|
||||
|
||||
static void write_id_guid(FILE *f, const char *type, const char *guid_prefix, const char *name, const UUID *uuid)
|
||||
static void write_id_guid(FILE *f, const char *type, const char *guid_prefix, const char *name, const struct uuid *uuid)
|
||||
{
|
||||
if (!uuid) return;
|
||||
fprintf(f, "MIDL_DEFINE_GUID(%s, %s_%s, 0x%08x, 0x%04x, 0x%04x, 0x%02x,0x%02x, 0x%02x,"
|
||||
@@ -498,27 +401,27 @@ static void write_id_data_stmts(const statement_list_t *stmts)
|
||||
const type_t *type = stmt->u.type;
|
||||
if (type_get_type(type) == TYPE_INTERFACE)
|
||||
{
|
||||
const UUID *uuid;
|
||||
const struct uuid *uuid;
|
||||
if (!is_object(type) && !is_attr(type->attrs, ATTR_DISPINTERFACE))
|
||||
continue;
|
||||
uuid = get_attrp(type->attrs, ATTR_UUID);
|
||||
write_id_guid(idfile, "IID", is_attr(type->attrs, ATTR_DISPINTERFACE) ? "DIID" : "IID",
|
||||
type->name, uuid);
|
||||
if (type->details.iface->async_iface)
|
||||
if (type_iface_get_async_iface(type))
|
||||
{
|
||||
uuid = get_attrp(type->details.iface->async_iface->attrs, ATTR_UUID);
|
||||
write_id_guid(idfile, "IID", "IID", type->details.iface->async_iface->name, uuid);
|
||||
uuid = get_attrp(type_iface_get_async_iface(type)->attrs, ATTR_UUID);
|
||||
write_id_guid(idfile, "IID", "IID", type_iface_get_async_iface(type)->name, uuid);
|
||||
}
|
||||
}
|
||||
else if (type_get_type(type) == TYPE_COCLASS)
|
||||
{
|
||||
const UUID *uuid = get_attrp(type->attrs, ATTR_UUID);
|
||||
const struct uuid *uuid = get_attrp(type->attrs, ATTR_UUID);
|
||||
write_id_guid(idfile, "CLSID", "CLSID", type->name, uuid);
|
||||
}
|
||||
}
|
||||
else if (stmt->type == STMT_LIBRARY)
|
||||
{
|
||||
const UUID *uuid = get_attrp(stmt->u.lib->attrs, ATTR_UUID);
|
||||
const struct uuid *uuid = get_attrp(stmt->u.lib->attrs, ATTR_UUID);
|
||||
write_id_guid(idfile, "IID", "LIBID", stmt->u.lib->name, uuid);
|
||||
write_id_data_stmts(stmt->u.lib->stmts);
|
||||
}
|
||||
@@ -536,13 +439,13 @@ void write_id_data(const statement_list_t *stmts)
|
||||
}
|
||||
|
||||
fprintf(idfile, "/*** Autogenerated by WIDL %s ", PACKAGE_VERSION);
|
||||
fprintf(idfile, "from %s - Do not edit ***/\n\n", input_idl_name);
|
||||
|
||||
fprintf(idfile, "from %s - Do not edit ***/\n\n", idl_name);
|
||||
#ifdef __REACTOS__
|
||||
fprintf(idfile, "#ifdef __REACTOS__\n");
|
||||
fprintf(idfile, "#define WIN32_NO_STATUS\n");
|
||||
fprintf(idfile, "#define WIN32_LEAN_AND_MEAN\n");
|
||||
fprintf(idfile, "#endif\n\n");
|
||||
|
||||
#endif
|
||||
fprintf(idfile, "#include <rpc.h>\n");
|
||||
fprintf(idfile, "#include <rpcndr.h>\n\n");
|
||||
|
||||
@@ -581,23 +484,10 @@ void write_id_data(const statement_list_t *stmts)
|
||||
fclose(idfile);
|
||||
}
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
static void option_callback( int optc, char *optarg )
|
||||
{
|
||||
int optc;
|
||||
int ret = 0;
|
||||
int opti = 0;
|
||||
char *output_name = NULL;
|
||||
|
||||
signal( SIGTERM, exit_on_signal );
|
||||
signal( SIGINT, exit_on_signal );
|
||||
#ifdef SIGHUP
|
||||
signal( SIGHUP, exit_on_signal );
|
||||
#endif
|
||||
|
||||
now = time(NULL);
|
||||
|
||||
while((optc = getopt_long_only(argc, argv, short_options, long_options, &opti)) != EOF) {
|
||||
switch(optc) {
|
||||
switch (optc)
|
||||
{
|
||||
case DLLDATA_OPTION:
|
||||
dlldata_name = xstrdup(optarg);
|
||||
break;
|
||||
@@ -609,6 +499,9 @@ int main(int argc,char *argv[])
|
||||
do_everything = 0;
|
||||
local_stubs_name = xstrdup(optarg);
|
||||
break;
|
||||
case NOSTDINC_OPTION:
|
||||
stdinc = 0;
|
||||
break;
|
||||
case OLDNAMES_OPTION:
|
||||
old_names = 1;
|
||||
break;
|
||||
@@ -624,28 +517,26 @@ int main(int argc,char *argv[])
|
||||
break;
|
||||
case PRINT_HELP:
|
||||
fprintf(stderr, "%s", usage);
|
||||
return 0;
|
||||
exit(0);
|
||||
case RT_OPTION:
|
||||
winrt_mode = 1;
|
||||
break;
|
||||
case RT_NS_PREFIX:
|
||||
use_abi_namespace = 1;
|
||||
break;
|
||||
case SYSROOT_OPTION:
|
||||
sysroot = xstrdup(optarg);
|
||||
break;
|
||||
case WIN32_OPTION:
|
||||
pointer_size = 4;
|
||||
break;
|
||||
case WIN64_OPTION:
|
||||
pointer_size = 8;
|
||||
break;
|
||||
case WIN32_ALIGN_OPTION:
|
||||
win32_packing = strtol(optarg, NULL, 0);
|
||||
if(win32_packing != 2 && win32_packing != 4 && win32_packing != 8)
|
||||
error("Packing must be one of 2, 4 or 8\n");
|
||||
break;
|
||||
case WIN64_ALIGN_OPTION:
|
||||
win64_packing = strtol(optarg, NULL, 0);
|
||||
if(win64_packing != 2 && win64_packing != 4 && win64_packing != 8)
|
||||
error("Packing must be one of 2, 4 or 8\n");
|
||||
case PACKING_OPTION:
|
||||
packing = strtol(optarg, NULL, 0);
|
||||
if(packing != 2 && packing != 4 && packing != 8)
|
||||
error("Structure packing must be one of 2, 4 or 8\n");
|
||||
break;
|
||||
case ACF_OPTION:
|
||||
acf_name = xstrdup(optarg);
|
||||
@@ -658,7 +549,8 @@ int main(int argc,char *argv[])
|
||||
/* FIXME: Support robust option */
|
||||
break;
|
||||
case 'b':
|
||||
set_target( optarg );
|
||||
if (!parse_target( optarg, &target ))
|
||||
error( "Invalid target specification '%s'\n", optarg );
|
||||
break;
|
||||
case 'c':
|
||||
do_everything = 0;
|
||||
@@ -687,6 +579,9 @@ int main(int argc,char *argv[])
|
||||
case 'I':
|
||||
wpp_add_include_path(optarg);
|
||||
break;
|
||||
case 'L':
|
||||
strarray_add( &dlldirs, optarg );
|
||||
break;
|
||||
case 'm':
|
||||
if (!strcmp( optarg, "32" )) pointer_size = 4;
|
||||
else if (!strcmp( optarg, "64" )) pointer_size = 8;
|
||||
@@ -698,11 +593,11 @@ int main(int argc,char *argv[])
|
||||
output_name = xstrdup(optarg);
|
||||
break;
|
||||
case 'O':
|
||||
if (!strcmp( optarg, "s" )) stub_mode = MODE_Os;
|
||||
else if (!strcmp( optarg, "i" )) stub_mode = MODE_Oi;
|
||||
else if (!strcmp( optarg, "ic" )) stub_mode = MODE_Oif;
|
||||
else if (!strcmp( optarg, "if" )) stub_mode = MODE_Oif;
|
||||
else if (!strcmp( optarg, "icf" )) stub_mode = MODE_Oif;
|
||||
if (!strcmp( optarg, "s" )) interpreted_mode = 0;
|
||||
else if (!strcmp( optarg, "i" )) interpreted_mode = 1;
|
||||
else if (!strcmp( optarg, "ic" )) interpreted_mode = 1;
|
||||
else if (!strcmp( optarg, "if" )) interpreted_mode = 1;
|
||||
else if (!strcmp( optarg, "icf" )) interpreted_mode = 1;
|
||||
else error( "Invalid argument '-O%s'\n", optarg );
|
||||
break;
|
||||
case 'p':
|
||||
@@ -728,7 +623,7 @@ int main(int argc,char *argv[])
|
||||
do_typelib = 1;
|
||||
break;
|
||||
case OLD_TYPELIB_OPTION:
|
||||
do_old_typelib = 1;
|
||||
old_typelib = 1;
|
||||
break;
|
||||
case 'T':
|
||||
typelib_name = xstrdup(optarg);
|
||||
@@ -742,39 +637,112 @@ int main(int argc,char *argv[])
|
||||
break;
|
||||
case 'V':
|
||||
printf("%s", version_string);
|
||||
return 0;
|
||||
exit(0);
|
||||
case 'W':
|
||||
pedantic = 1;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "%s", usage);
|
||||
return 1;
|
||||
case '?':
|
||||
fprintf(stderr, "widl: %s\n\n%s", optarg, usage);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEFAULT_INCLUDE_DIR
|
||||
wpp_add_include_path(DEFAULT_INCLUDE_DIR);
|
||||
int open_typelib( const char *name )
|
||||
{
|
||||
#ifndef __REACTOS__
|
||||
static const char *default_dirs[] = { LIBDIR "/wine", "/usr/lib/wine", "/usr/local/lib/wine" };
|
||||
#endif
|
||||
struct target win_target = { target.cpu, PLATFORM_WINDOWS };
|
||||
const char *pe_dir = get_arch_dir( win_target );
|
||||
int fd;
|
||||
unsigned int i;
|
||||
|
||||
#define TRYOPEN(str) do { \
|
||||
char *file = str; \
|
||||
if ((fd = open( file, O_RDONLY | O_BINARY )) != -1) return fd; \
|
||||
free( file ); } while(0)
|
||||
|
||||
for (i = 0; i < dlldirs.count; i++)
|
||||
{
|
||||
if (strendswith( dlldirs.str[i], "/*" )) /* special case for wine build tree */
|
||||
{
|
||||
int namelen = strlen( name );
|
||||
if (strendswith( name, ".dll" )) namelen -= 4;
|
||||
TRYOPEN( strmake( "%.*s/%.*s%s/%s", (int)strlen(dlldirs.str[i]) - 2, dlldirs.str[i],
|
||||
namelen, name, pe_dir, name ));
|
||||
}
|
||||
else
|
||||
{
|
||||
TRYOPEN( strmake( "%s%s/%s", dlldirs.str[i], pe_dir, name ));
|
||||
TRYOPEN( strmake( "%s/%s", dlldirs.str[i], name ));
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef __REACTOS__
|
||||
if (stdinc)
|
||||
{
|
||||
if (libdir)
|
||||
{
|
||||
TRYOPEN( strmake( "%s/wine%s/%s", libdir, pe_dir, name ));
|
||||
TRYOPEN( strmake( "%s/wine/%s", libdir, name ));
|
||||
}
|
||||
#ifndef __REACTOS__
|
||||
for (i = 0; i < ARRAY_SIZE(default_dirs); i++)
|
||||
{
|
||||
if (i && !strcmp( default_dirs[i], default_dirs[0] )) continue;
|
||||
TRYOPEN( strmake( "%s%s/%s", default_dirs[i], pe_dir, name ));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (target_cpu)
|
||||
error( "cannot find %s\n", name );
|
||||
#undef TRYOPEN
|
||||
|
||||
#ifdef __REACTOS__
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
int i;
|
||||
int ret = 0;
|
||||
struct strarray files;
|
||||
|
||||
init_signals( exit_on_signal );
|
||||
bindir = get_bindir( argv[0] );
|
||||
libdir = get_libdir( bindir );
|
||||
includedir = get_includedir( bindir );
|
||||
target = init_argv0_target( argv[0] );
|
||||
|
||||
now = time(NULL);
|
||||
|
||||
files = parse_options( argc, argv, short_options, long_options, 1, option_callback );
|
||||
|
||||
#ifndef __REACTOS__
|
||||
if (stdinc)
|
||||
{
|
||||
case CPU_x86:
|
||||
if (pointer_size == 8) target_cpu = CPU_x86_64;
|
||||
else pointer_size = 4;
|
||||
break;
|
||||
case CPU_x86_64:
|
||||
if (pointer_size == 4) target_cpu = CPU_x86;
|
||||
else pointer_size = 8;
|
||||
break;
|
||||
case CPU_ARM64:
|
||||
if (pointer_size == 4) error( "Cannot build 32-bit code for this CPU\n" );
|
||||
pointer_size = 8;
|
||||
break;
|
||||
default:
|
||||
if (pointer_size == 8) error( "Cannot build 64-bit code for this CPU\n" );
|
||||
pointer_size = 4;
|
||||
break;
|
||||
static const char *incl_dirs[] = { INCLUDEDIR, "/usr/include", "/usr/local/include" };
|
||||
|
||||
if (includedir)
|
||||
{
|
||||
wpp_add_include_path( strmake( "%s/wine/msvcrt", includedir ));
|
||||
wpp_add_include_path( strmake( "%s/wine/windows", includedir ));
|
||||
}
|
||||
for (i = 0; i < ARRAY_SIZE(incl_dirs); i++)
|
||||
{
|
||||
if (i && !strcmp( incl_dirs[i], incl_dirs[0] )) continue;
|
||||
wpp_add_include_path( strmake( "%s%s/wine/msvcrt", sysroot, incl_dirs[i] ));
|
||||
wpp_add_include_path( strmake( "%s%s/wine/windows", sysroot, incl_dirs[i] ));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pointer_size)
|
||||
set_target_ptr_size( &target, pointer_size );
|
||||
else
|
||||
pointer_size = get_target_ptr_size( target );
|
||||
|
||||
/* if nothing specified, try to guess output type from the output file name */
|
||||
if (output_name && do_everything && !do_header && !do_typelib && !do_proxies &&
|
||||
@@ -789,6 +757,7 @@ int main(int argc,char *argv[])
|
||||
else if (strendswith( output_name, "_i.c" )) do_idfile = 1;
|
||||
else if (strendswith( output_name, "_r.res" )) do_regscript = 1;
|
||||
else if (strendswith( output_name, "_t.res" )) do_typelib = 1;
|
||||
else if (strendswith( output_name, "_l.res" )) do_typelib = 1;
|
||||
else if (strendswith( output_name, "dlldata.c" )) do_dlldata = 1;
|
||||
else do_everything = 1;
|
||||
}
|
||||
@@ -797,40 +766,40 @@ int main(int argc,char *argv[])
|
||||
set_everything(TRUE);
|
||||
}
|
||||
|
||||
if (!output_name) output_name = dup_basename(input_name, ".idl");
|
||||
|
||||
if (do_header + do_typelib + do_proxies + do_client +
|
||||
do_server + do_regscript + do_idfile + do_dlldata == 1)
|
||||
do_server + do_regscript + do_idfile + do_dlldata == 1 && output_name)
|
||||
{
|
||||
if (do_header) header_name = output_name;
|
||||
else if (do_typelib) typelib_name = output_name;
|
||||
else if (do_proxies) proxy_name = output_name;
|
||||
else if (do_client) client_name = output_name;
|
||||
else if (do_server) server_name = output_name;
|
||||
else if (do_regscript) regscript_name = output_name;
|
||||
else if (do_idfile) idfile_name = output_name;
|
||||
else if (do_dlldata) dlldata_name = output_name;
|
||||
if (do_header && !header_name) header_name = output_name;
|
||||
else if (do_typelib && !typelib_name) typelib_name = output_name;
|
||||
else if (do_proxies && !proxy_name) proxy_name = output_name;
|
||||
else if (do_client && !client_name) client_name = output_name;
|
||||
else if (do_server && !server_name) server_name = output_name;
|
||||
else if (do_regscript && !regscript_name) regscript_name = output_name;
|
||||
else if (do_idfile && !idfile_name) idfile_name = output_name;
|
||||
else if (do_dlldata && !dlldata_name) dlldata_name = output_name;
|
||||
}
|
||||
|
||||
if (!dlldata_name && do_dlldata)
|
||||
dlldata_name = xstrdup("dlldata.c");
|
||||
|
||||
if(optind < argc) {
|
||||
if (files.count) {
|
||||
if (do_dlldata && !do_everything) {
|
||||
struct list filenames = LIST_INIT(filenames);
|
||||
for ( ; optind < argc; ++optind)
|
||||
add_filename_node(&filenames, argv[optind]);
|
||||
struct strarray filenames = empty_strarray;
|
||||
for (i = 0; i < files.count; i++)
|
||||
strarray_add(&filenames, replace_extension( get_basename( files.str[i] ), ".idl", "" ));
|
||||
|
||||
write_dlldata_list(&filenames, 0 /* FIXME */ );
|
||||
free_filename_nodes(&filenames);
|
||||
write_dlldata_list(filenames, 0 /* FIXME */ );
|
||||
return 0;
|
||||
}
|
||||
else if (optind != argc - 1) {
|
||||
else if (files.count > 1) {
|
||||
fprintf(stderr, "%s", usage);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
input_idl_name = input_name = xstrdup(argv[optind]);
|
||||
{
|
||||
input_name = xstrdup( files.str[0] );
|
||||
idl_name = get_basename( input_name );
|
||||
}
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "%s", usage);
|
||||
@@ -850,40 +819,26 @@ int main(int argc,char *argv[])
|
||||
(debuglevel & DEBUGLEVEL_PPTRACE) != 0,
|
||||
(debuglevel & DEBUGLEVEL_PPMSG) != 0 );
|
||||
|
||||
if (!header_name) {
|
||||
header_name = dup_basename(input_name, ".idl");
|
||||
strcat(header_name, ".h");
|
||||
}
|
||||
if (!header_name)
|
||||
header_name = replace_extension( get_basename(input_name), ".idl", ".h" );
|
||||
|
||||
if (!typelib_name && do_typelib) {
|
||||
typelib_name = dup_basename(input_name, ".idl");
|
||||
strcat(typelib_name, ".tlb");
|
||||
}
|
||||
if (!typelib_name && do_typelib)
|
||||
typelib_name = replace_extension( get_basename(input_name), ".idl", ".tlb" );
|
||||
|
||||
if (!proxy_name && do_proxies) {
|
||||
proxy_name = dup_basename(input_name, ".idl");
|
||||
strcat(proxy_name, "_p.c");
|
||||
}
|
||||
if (!proxy_name && do_proxies)
|
||||
proxy_name = replace_extension( get_basename(input_name), ".idl", "_p.c" );
|
||||
|
||||
if (!client_name && do_client) {
|
||||
client_name = dup_basename(input_name, ".idl");
|
||||
strcat(client_name, "_c.c");
|
||||
}
|
||||
if (!client_name && do_client)
|
||||
client_name = replace_extension( get_basename(input_name), ".idl", "_c.c" );
|
||||
|
||||
if (!server_name && do_server) {
|
||||
server_name = dup_basename(input_name, ".idl");
|
||||
strcat(server_name, "_s.c");
|
||||
}
|
||||
if (!server_name && do_server)
|
||||
server_name = replace_extension( get_basename(input_name), ".idl", "_s.c" );
|
||||
|
||||
if (!regscript_name && do_regscript) {
|
||||
regscript_name = dup_basename(input_name, ".idl");
|
||||
strcat(regscript_name, "_r.rgs");
|
||||
}
|
||||
if (!regscript_name && do_regscript)
|
||||
regscript_name = replace_extension( get_basename(input_name), ".idl", "_r.rgs" );
|
||||
|
||||
if (!idfile_name && do_idfile) {
|
||||
idfile_name = dup_basename(input_name, ".idl");
|
||||
strcat(idfile_name, "_i.c");
|
||||
}
|
||||
if (!idfile_name && do_idfile)
|
||||
idfile_name = replace_extension( get_basename(input_name), ".idl", "_i.c" );
|
||||
|
||||
if (do_proxies) proxy_token = dup_basename_token(proxy_name,"_p.c");
|
||||
if (do_client) client_token = dup_basename_token(client_name,"_c.c");
|
||||
@@ -891,61 +846,18 @@ int main(int argc,char *argv[])
|
||||
if (do_regscript) regscript_token = dup_basename_token(regscript_name,"_r.rgs");
|
||||
|
||||
add_widl_version_define();
|
||||
wpp_add_define("_WIN32", NULL);
|
||||
wpp_add_cmdline_define("_WIN32=1");
|
||||
|
||||
atexit(rm_tempfile);
|
||||
if (!no_preprocess)
|
||||
{
|
||||
chat("Starting preprocess\n");
|
||||
|
||||
if (!preprocess_only)
|
||||
{
|
||||
FILE *output;
|
||||
int fd;
|
||||
char *name = xmalloc( strlen(header_name) + 8 );
|
||||
|
||||
strcpy( name, header_name );
|
||||
strcat( name, ".XXXXXX" );
|
||||
|
||||
if ((fd = mkstemps( name, 0 )) == -1)
|
||||
error("Could not generate a temp name from %s\n", name);
|
||||
|
||||
temp_name = name;
|
||||
if (!(output = fdopen(fd, "wt")))
|
||||
error("Could not open fd %s for writing\n", name);
|
||||
|
||||
ret = wpp_parse( input_name, output );
|
||||
fclose( output );
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = wpp_parse( input_name, stdout );
|
||||
}
|
||||
|
||||
if(ret) exit(1);
|
||||
if(preprocess_only) exit(0);
|
||||
if(!(parser_in = fopen(temp_name, "r"))) {
|
||||
fprintf(stderr, "Could not open %s for input\n", temp_name);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(!(parser_in = fopen(input_name, "r"))) {
|
||||
fprintf(stderr, "Could not open %s for input\n", input_name);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (preprocess_only) exit( wpp_parse( input_name, stdout ) );
|
||||
parser_in = open_input_file( input_name );
|
||||
|
||||
header_token = make_token(header_name);
|
||||
|
||||
init_types();
|
||||
ret = parser_parse();
|
||||
|
||||
fclose(parser_in);
|
||||
|
||||
if(ret) {
|
||||
exit(1);
|
||||
}
|
||||
close_all_inputs();
|
||||
if (ret) exit(1);
|
||||
|
||||
/* Everything has been done successfully, don't delete any files. */
|
||||
set_everything(FALSE);
|
||||
@@ -956,9 +868,6 @@ int main(int argc,char *argv[])
|
||||
|
||||
static void rm_tempfile(void)
|
||||
{
|
||||
abort_import();
|
||||
if(temp_name)
|
||||
unlink(temp_name);
|
||||
if (do_header)
|
||||
unlink(header_name);
|
||||
if (local_stubs_name)
|
||||
@@ -975,4 +884,38 @@ static void rm_tempfile(void)
|
||||
unlink(proxy_name);
|
||||
if (do_typelib)
|
||||
unlink(typelib_name);
|
||||
remove_temp_files();
|
||||
}
|
||||
|
||||
char *find_input_file( const char *name, const char *parent )
|
||||
{
|
||||
char *path;
|
||||
|
||||
/* don't search for a file name with a path in the include directories, for compatibility with MIDL */
|
||||
if (strchr( name, '/' ) || strchr( name, '\\' )) path = xstrdup( name );
|
||||
else if (!(path = wpp_find_include( name, parent ))) error_loc( "Unable to open include file %s\n", name );
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
FILE *open_input_file( const char *path )
|
||||
{
|
||||
FILE *file;
|
||||
char *name;
|
||||
int ret;
|
||||
|
||||
if (no_preprocess)
|
||||
{
|
||||
if (!(file = fopen( path, "r" ))) error_loc( "Unable to open %s\n", path );
|
||||
return file;
|
||||
}
|
||||
|
||||
name = make_temp_file( "widl", NULL );
|
||||
if (!(file = fopen( name, "wt" ))) error_loc( "Could not open %s for writing\n", name );
|
||||
ret = wpp_parse( path, file );
|
||||
fclose( file );
|
||||
if (ret) exit( 1 );
|
||||
|
||||
if (!(file = fopen( name, "r" ))) error_loc( "Unable to open %s\n", name );
|
||||
return file;
|
||||
}
|
||||
|
||||
+43
-21
@@ -21,6 +21,7 @@
|
||||
#ifndef __WIDL_WIDL_H
|
||||
#define __WIDL_WIDL_H
|
||||
|
||||
#include "../tools.h"
|
||||
#include "widltypes.h"
|
||||
|
||||
#include <time.h>
|
||||
@@ -38,7 +39,6 @@ extern int pedantic;
|
||||
extern int do_everything;
|
||||
extern int do_header;
|
||||
extern int do_typelib;
|
||||
extern int do_old_typelib;
|
||||
extern int do_proxies;
|
||||
extern int do_client;
|
||||
extern int do_server;
|
||||
@@ -46,13 +46,13 @@ extern int do_regscript;
|
||||
extern int do_idfile;
|
||||
extern int do_dlldata;
|
||||
extern int old_names;
|
||||
extern int win32_packing;
|
||||
extern int win64_packing;
|
||||
extern int old_typelib;
|
||||
extern int winrt_mode;
|
||||
extern int interpreted_mode;
|
||||
extern int use_abi_namespace;
|
||||
|
||||
extern char *input_name;
|
||||
extern char *input_idl_name;
|
||||
extern char *idl_name;
|
||||
extern char *acf_name;
|
||||
extern char *header_name;
|
||||
extern char *header_token;
|
||||
@@ -69,26 +69,12 @@ extern char *regscript_name;
|
||||
extern char *regscript_token;
|
||||
extern const char *prefix_client;
|
||||
extern const char *prefix_server;
|
||||
extern unsigned int packing;
|
||||
extern unsigned int pointer_size;
|
||||
extern struct target target;
|
||||
extern time_t now;
|
||||
|
||||
extern int line_number;
|
||||
extern int char_number;
|
||||
|
||||
enum target_cpu
|
||||
{
|
||||
CPU_x86, CPU_x86_64, CPU_POWERPC, CPU_ARM, CPU_ARM64, CPU_LAST = CPU_ARM64
|
||||
};
|
||||
|
||||
extern enum target_cpu target_cpu;
|
||||
|
||||
enum stub_mode
|
||||
{
|
||||
MODE_Os, /* inline stubs */
|
||||
MODE_Oi, /* old-style interpreted stubs */
|
||||
MODE_Oif /* new-style fully interpreted stubs */
|
||||
};
|
||||
extern enum stub_mode get_stub_mode(void);
|
||||
extern int open_typelib( const char *name );
|
||||
|
||||
extern void write_header(const statement_list_t *stmts);
|
||||
extern void write_id_data(const statement_list_t *stmts);
|
||||
@@ -104,4 +90,40 @@ extern void write_dlldata(const statement_list_t *stmts);
|
||||
extern void start_cplusplus_guard(FILE *fp);
|
||||
extern void end_cplusplus_guard(FILE *fp);
|
||||
|
||||
/* attribute.c */
|
||||
|
||||
extern attr_t *attr_int( struct location where, enum attr_type attr_type, unsigned int val );
|
||||
extern attr_t *attr_ptr( struct location where, enum attr_type attr_type, void *val );
|
||||
|
||||
extern int is_attr( const attr_list_t *list, enum attr_type attr_type );
|
||||
extern int is_ptrchain_attr( const var_t *var, enum attr_type attr_type );
|
||||
extern int is_aliaschain_attr( const type_t *type, enum attr_type attr_type );
|
||||
|
||||
extern unsigned int get_attrv( const attr_list_t *list, enum attr_type attr_type );
|
||||
extern void *get_attrp( const attr_list_t *list, enum attr_type attr_type );
|
||||
extern void *get_aliaschain_attrp( const type_t *type, enum attr_type attr_type );
|
||||
|
||||
typedef int (*map_attrs_filter_t)( attr_list_t *, const attr_t * );
|
||||
extern attr_list_t *append_attr( attr_list_t *list, attr_t *attr );
|
||||
extern attr_list_t *append_attr_list( attr_list_t *new_list, attr_list_t *old_list );
|
||||
extern attr_list_t *append_attribs( attr_list_t *, attr_list_t * );
|
||||
extern attr_list_t *map_attrs( const attr_list_t *list, map_attrs_filter_t filter );
|
||||
extern attr_list_t *move_attr( attr_list_t *dst, attr_list_t *src, enum attr_type type );
|
||||
|
||||
extern attr_list_t *check_apicontract_attrs( const char *name, attr_list_t *attrs );
|
||||
extern attr_list_t *check_coclass_attrs( const char *name, attr_list_t *attrs );
|
||||
extern attr_list_t *check_dispiface_attrs( const char *name, attr_list_t *attrs );
|
||||
extern attr_list_t *check_enum_attrs( attr_list_t *attrs );
|
||||
extern attr_list_t *check_enum_member_attrs( attr_list_t *attrs );
|
||||
extern attr_list_t *check_field_attrs( const char *name, attr_list_t *attrs );
|
||||
extern attr_list_t *check_function_attrs( const char *name, attr_list_t *attrs );
|
||||
extern attr_list_t *check_interface_attrs( const char *name, attr_list_t *attrs );
|
||||
extern attr_list_t *check_library_attrs( const char *name, attr_list_t *attrs );
|
||||
extern attr_list_t *check_module_attrs( const char *name, attr_list_t *attrs );
|
||||
extern attr_list_t *check_runtimeclass_attrs( const char *name, attr_list_t *attrs );
|
||||
extern attr_list_t *check_struct_attrs( attr_list_t *attrs );
|
||||
extern attr_list_t *check_typedef_attrs( attr_list_t *attrs );
|
||||
extern attr_list_t *check_union_attrs( attr_list_t *attrs );
|
||||
extern void check_arg_attrs( const var_t *arg );
|
||||
|
||||
#endif
|
||||
|
||||
+155
-58
@@ -22,26 +22,30 @@
|
||||
#define __WIDL_WIDLTYPES_H
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include "guiddef.h"
|
||||
#include "ndrtypes.h"
|
||||
#include "wine/list.h"
|
||||
|
||||
#ifndef UUID_DEFINED
|
||||
#define UUID_DEFINED
|
||||
typedef GUID UUID;
|
||||
#endif
|
||||
struct uuid
|
||||
{
|
||||
unsigned int Data1;
|
||||
unsigned short Data2;
|
||||
unsigned short Data3;
|
||||
unsigned char Data4[8];
|
||||
};
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
typedef struct _loc_info_t loc_info_t;
|
||||
typedef struct _attr_t attr_t;
|
||||
typedef struct _attr_custdata_t attr_custdata_t;
|
||||
typedef struct _expr_t expr_t;
|
||||
typedef struct _type_t type_t;
|
||||
typedef struct _var_t var_t;
|
||||
typedef struct _decl_spec_t decl_spec_t;
|
||||
typedef struct _declarator_t declarator_t;
|
||||
typedef struct _ifref_t ifref_t;
|
||||
typedef struct _typeref_t typeref_t;
|
||||
typedef struct _typelib_entry_t typelib_entry_t;
|
||||
typedef struct _importlib_t importlib_t;
|
||||
typedef struct _importinfo_t importinfo_t;
|
||||
@@ -49,7 +53,6 @@ typedef struct _typelib_t typelib_t;
|
||||
typedef struct _user_type_t user_type_t;
|
||||
typedef struct _user_type_t context_handle_t;
|
||||
typedef struct _user_type_t generic_handle_t;
|
||||
typedef struct _type_list_t type_list_t;
|
||||
typedef struct _statement_t statement_t;
|
||||
typedef struct _warning_t warning_t;
|
||||
|
||||
@@ -58,7 +61,7 @@ typedef struct list str_list_t;
|
||||
typedef struct list expr_list_t;
|
||||
typedef struct list var_list_t;
|
||||
typedef struct list declarator_list_t;
|
||||
typedef struct list ifref_list_t;
|
||||
typedef struct list typeref_list_t;
|
||||
typedef struct list user_type_list_t;
|
||||
typedef struct list context_handle_list_t;
|
||||
typedef struct list generic_handle_list_t;
|
||||
@@ -67,6 +70,7 @@ typedef struct list warning_list_t;
|
||||
|
||||
enum attr_type
|
||||
{
|
||||
ATTR_ACTIVATABLE,
|
||||
ATTR_AGGREGATABLE,
|
||||
ATTR_ALLOCATE,
|
||||
ATTR_ANNOTATION,
|
||||
@@ -81,15 +85,20 @@ enum attr_type
|
||||
ATTR_CASE,
|
||||
ATTR_CODE,
|
||||
ATTR_COMMSTATUS,
|
||||
ATTR_CONST, /* const pseudo-attribute */
|
||||
ATTR_COMPOSABLE,
|
||||
ATTR_CONTEXTHANDLE,
|
||||
ATTR_CONTRACT,
|
||||
ATTR_CONTRACTVERSION,
|
||||
ATTR_CONTROL,
|
||||
ATTR_CUSTOM,
|
||||
ATTR_DECODE,
|
||||
ATTR_DEFAULT,
|
||||
ATTR_DEFAULT_OVERLOAD,
|
||||
ATTR_DEFAULTBIND,
|
||||
ATTR_DEFAULTCOLLELEM,
|
||||
ATTR_DEFAULTVALUE,
|
||||
ATTR_DEFAULTVTABLE,
|
||||
ATTR_DEPRECATED,
|
||||
ATTR_DISABLECONSISTENCYCHECK,
|
||||
ATTR_DISPINTERFACE,
|
||||
ATTR_DISPLAYBIND,
|
||||
@@ -99,8 +108,12 @@ enum attr_type
|
||||
ATTR_ENCODE,
|
||||
ATTR_ENDPOINT,
|
||||
ATTR_ENTRY,
|
||||
ATTR_EVENTADD,
|
||||
ATTR_EVENTREMOVE,
|
||||
ATTR_EXCLUSIVETO,
|
||||
ATTR_EXPLICIT_HANDLE,
|
||||
ATTR_FAULTSTATUS,
|
||||
ATTR_FLAGS,
|
||||
ATTR_FORCEALLOCATE,
|
||||
ATTR_HANDLE,
|
||||
ATTR_HELPCONTEXT,
|
||||
@@ -116,12 +129,12 @@ enum attr_type
|
||||
ATTR_IMMEDIATEBIND,
|
||||
ATTR_IMPLICIT_HANDLE,
|
||||
ATTR_IN,
|
||||
ATTR_INLINE,
|
||||
ATTR_INPUTSYNC,
|
||||
ATTR_LENGTHIS,
|
||||
ATTR_LIBLCID,
|
||||
ATTR_LICENSED,
|
||||
ATTR_LOCAL,
|
||||
ATTR_MARSHALING_BEHAVIOR,
|
||||
ATTR_MAYBE,
|
||||
ATTR_MESSAGE,
|
||||
ATTR_NOCODE,
|
||||
@@ -136,6 +149,7 @@ enum attr_type
|
||||
ATTR_OPTIMIZE,
|
||||
ATTR_OPTIONAL,
|
||||
ATTR_OUT,
|
||||
ATTR_OVERLOAD,
|
||||
ATTR_PARAMLCID,
|
||||
ATTR_PARTIALIGNORE,
|
||||
ATTR_POINTERDEFAULT,
|
||||
@@ -144,6 +158,7 @@ enum attr_type
|
||||
ATTR_PROPGET,
|
||||
ATTR_PROPPUT,
|
||||
ATTR_PROPPUTREF,
|
||||
ATTR_PROTECTED,
|
||||
ATTR_PROXY,
|
||||
ATTR_PUBLIC,
|
||||
ATTR_RANGE,
|
||||
@@ -154,6 +169,7 @@ enum attr_type
|
||||
ATTR_RETVAL,
|
||||
ATTR_SIZEIS,
|
||||
ATTR_SOURCE,
|
||||
ATTR_STATIC,
|
||||
ATTR_STRICTCONTEXTHANDLE,
|
||||
ATTR_STRING,
|
||||
ATTR_SWITCHIS,
|
||||
@@ -175,7 +191,6 @@ enum expr_type
|
||||
{
|
||||
EXPR_VOID,
|
||||
EXPR_NUM,
|
||||
EXPR_HEXNUM,
|
||||
EXPR_DOUBLE,
|
||||
EXPR_IDENTIFIER,
|
||||
EXPR_NEG,
|
||||
@@ -235,6 +250,16 @@ enum storage_class
|
||||
STG_REGISTER,
|
||||
};
|
||||
|
||||
enum type_qualifier
|
||||
{
|
||||
TYPE_QUALIFIER_CONST = 1,
|
||||
};
|
||||
|
||||
enum function_specifier
|
||||
{
|
||||
FUNCTION_SPECIFIER_INLINE = 1,
|
||||
};
|
||||
|
||||
enum statement_type
|
||||
{
|
||||
STMT_LIBRARY,
|
||||
@@ -258,6 +283,14 @@ enum threading_type
|
||||
THREADING_BOTH
|
||||
};
|
||||
|
||||
enum marshaling_type
|
||||
{
|
||||
MARSHALING_INVALID = 0,
|
||||
MARSHALING_NONE,
|
||||
MARSHALING_AGILE,
|
||||
MARSHALING_STANDARD,
|
||||
};
|
||||
|
||||
enum type_basic_type
|
||||
{
|
||||
TYPE_BASIC_INT8 = 1,
|
||||
@@ -281,11 +314,13 @@ enum type_basic_type
|
||||
#define TYPE_BASIC_INT_MIN TYPE_BASIC_INT8
|
||||
#define TYPE_BASIC_INT_MAX TYPE_BASIC_HYPER
|
||||
|
||||
struct _loc_info_t
|
||||
struct location
|
||||
{
|
||||
const char *input_name;
|
||||
int line_number;
|
||||
const char *near_text;
|
||||
int first_line;
|
||||
int last_line;
|
||||
int first_column;
|
||||
int last_column;
|
||||
};
|
||||
|
||||
struct str_list_entry_t
|
||||
@@ -294,6 +329,14 @@ struct str_list_entry_t
|
||||
struct list entry;
|
||||
};
|
||||
|
||||
struct _decl_spec_t
|
||||
{
|
||||
type_t *type;
|
||||
enum storage_class stgclass;
|
||||
enum type_qualifier qualifier;
|
||||
enum function_specifier func_specifier;
|
||||
};
|
||||
|
||||
struct _attr_t {
|
||||
enum attr_type type;
|
||||
union {
|
||||
@@ -302,17 +345,26 @@ struct _attr_t {
|
||||
} u;
|
||||
/* parser-internal */
|
||||
struct list entry;
|
||||
struct location where;
|
||||
};
|
||||
|
||||
struct integer
|
||||
{
|
||||
int value;
|
||||
int is_unsigned;
|
||||
int is_long;
|
||||
int is_hex;
|
||||
};
|
||||
|
||||
struct _expr_t {
|
||||
enum expr_type type;
|
||||
const expr_t *ref;
|
||||
union {
|
||||
int lval;
|
||||
struct integer integer;
|
||||
double dval;
|
||||
const char *sval;
|
||||
const expr_t *ext;
|
||||
type_t *tref;
|
||||
decl_spec_t tref;
|
||||
} u;
|
||||
const expr_t *ext2;
|
||||
int is_const;
|
||||
@@ -321,6 +373,11 @@ struct _expr_t {
|
||||
struct list entry;
|
||||
};
|
||||
|
||||
struct _attr_custdata_t {
|
||||
struct uuid id;
|
||||
expr_t *pval;
|
||||
};
|
||||
|
||||
struct struct_details
|
||||
{
|
||||
var_list_t *fields;
|
||||
@@ -335,7 +392,6 @@ struct func_details
|
||||
{
|
||||
var_list_t *args;
|
||||
struct _var_t *retval;
|
||||
int idx;
|
||||
};
|
||||
|
||||
struct iface_details
|
||||
@@ -346,6 +402,7 @@ struct iface_details
|
||||
struct _type_t *inherit;
|
||||
struct _type_t *disp_inherit;
|
||||
struct _type_t *async_iface;
|
||||
typeref_list_t *requires;
|
||||
};
|
||||
|
||||
struct module_details
|
||||
@@ -357,16 +414,15 @@ struct array_details
|
||||
{
|
||||
expr_t *size_is;
|
||||
expr_t *length_is;
|
||||
struct _type_t *elem;
|
||||
struct _decl_spec_t elem;
|
||||
unsigned int dim;
|
||||
unsigned char ptr_def_fc;
|
||||
unsigned char declptr; /* if declared as a pointer */
|
||||
unsigned short ptr_tfsoff; /* offset of pointer definition for declptr */
|
||||
};
|
||||
|
||||
struct coclass_details
|
||||
{
|
||||
ifref_list_t *ifaces;
|
||||
typeref_list_t *ifaces;
|
||||
};
|
||||
|
||||
struct basic_details
|
||||
@@ -377,8 +433,7 @@ struct basic_details
|
||||
|
||||
struct pointer_details
|
||||
{
|
||||
struct _type_t *ref;
|
||||
unsigned char def_fc;
|
||||
struct _decl_spec_t ref;
|
||||
};
|
||||
|
||||
struct bitfield_details
|
||||
@@ -387,6 +442,27 @@ struct bitfield_details
|
||||
const expr_t *bits;
|
||||
};
|
||||
|
||||
struct alias_details
|
||||
{
|
||||
struct _decl_spec_t aliasee;
|
||||
};
|
||||
|
||||
struct runtimeclass_details
|
||||
{
|
||||
typeref_list_t *ifaces;
|
||||
};
|
||||
|
||||
struct parameterized_details
|
||||
{
|
||||
type_t *type;
|
||||
typeref_list_t *params;
|
||||
};
|
||||
|
||||
struct delegate_details
|
||||
{
|
||||
type_t *iface;
|
||||
};
|
||||
|
||||
#define HASHMAX 64
|
||||
|
||||
struct namespace {
|
||||
@@ -413,10 +489,15 @@ enum type_type
|
||||
TYPE_POINTER,
|
||||
TYPE_ARRAY,
|
||||
TYPE_BITFIELD,
|
||||
TYPE_APICONTRACT,
|
||||
TYPE_RUNTIMECLASS,
|
||||
TYPE_PARAMETERIZED_TYPE,
|
||||
TYPE_PARAMETER,
|
||||
TYPE_DELEGATE,
|
||||
};
|
||||
|
||||
struct _type_t {
|
||||
const char *name;
|
||||
const char *name; /* C++ name with parameters in brackets */
|
||||
struct namespace *namespace;
|
||||
enum type_type type_type;
|
||||
attr_list_t *attrs;
|
||||
@@ -432,32 +513,45 @@ struct _type_t {
|
||||
struct basic_details basic;
|
||||
struct pointer_details pointer;
|
||||
struct bitfield_details bitfield;
|
||||
struct alias_details alias;
|
||||
struct runtimeclass_details runtimeclass;
|
||||
struct parameterized_details parameterized;
|
||||
struct delegate_details delegate;
|
||||
} details;
|
||||
const char *c_name;
|
||||
type_t *orig; /* dup'd types */
|
||||
const char *c_name; /* mangled C name, with namespaces and parameters */
|
||||
const char *signature;
|
||||
const char *qualified_name; /* C++ fully qualified name */
|
||||
const char *impl_name; /* C++ parameterized types impl base class name */
|
||||
const char *param_name; /* used to build c_name of a parameterized type, when used as a parameter */
|
||||
const char *short_name; /* widl specific short name */
|
||||
unsigned int typestring_offset;
|
||||
unsigned int ptrdesc; /* used for complex structs */
|
||||
int typelib_idx;
|
||||
loc_info_t loc_info;
|
||||
struct location where;
|
||||
unsigned int ignore : 1;
|
||||
unsigned int defined : 1;
|
||||
unsigned int defined_in_import : 1;
|
||||
unsigned int written : 1;
|
||||
unsigned int user_types_registered : 1;
|
||||
unsigned int tfswrite : 1; /* if the type needs to be written to the TFS */
|
||||
unsigned int checked : 1;
|
||||
unsigned int is_alias : 1; /* is the type an alias? */
|
||||
};
|
||||
|
||||
struct _var_t {
|
||||
char *name;
|
||||
type_t *type;
|
||||
decl_spec_t declspec;
|
||||
attr_list_t *attrs;
|
||||
expr_t *eval;
|
||||
enum storage_class stgclass;
|
||||
unsigned int procstring_offset;
|
||||
|
||||
unsigned int typestring_offset;
|
||||
|
||||
struct _loc_info_t loc_info;
|
||||
/* fields specific to functions */
|
||||
unsigned int procstring_offset, func_idx;
|
||||
|
||||
struct location where;
|
||||
|
||||
/* Should we define the UDT in this var, when writing a header? */
|
||||
unsigned int is_defined : 1;
|
||||
|
||||
/* parser-internal */
|
||||
struct list entry;
|
||||
@@ -466,15 +560,15 @@ struct _var_t {
|
||||
struct _declarator_t {
|
||||
var_t *var;
|
||||
type_t *type;
|
||||
type_t *func_type;
|
||||
enum type_qualifier qualifier;
|
||||
expr_t *bits;
|
||||
|
||||
/* parser-internal */
|
||||
struct list entry;
|
||||
};
|
||||
|
||||
struct _ifref_t {
|
||||
type_t *iface;
|
||||
struct _typeref_t {
|
||||
type_t *type;
|
||||
attr_list_t *attrs;
|
||||
|
||||
/* parser-internal */
|
||||
@@ -488,7 +582,7 @@ struct _typelib_entry_t {
|
||||
|
||||
struct _importinfo_t {
|
||||
int offset;
|
||||
GUID guid;
|
||||
struct uuid guid;
|
||||
int flags;
|
||||
int id;
|
||||
|
||||
@@ -498,10 +592,11 @@ struct _importinfo_t {
|
||||
};
|
||||
|
||||
struct _importlib_t {
|
||||
int offset;
|
||||
char *name;
|
||||
|
||||
int version;
|
||||
GUID guid;
|
||||
struct uuid guid;
|
||||
|
||||
importinfo_t *importinfos;
|
||||
int ntypeinfos;
|
||||
@@ -516,6 +611,9 @@ struct _typelib_t {
|
||||
const attr_list_t *attrs;
|
||||
struct list importlibs;
|
||||
statement_list_t *stmts;
|
||||
|
||||
type_t **reg_ifaces;
|
||||
unsigned int reg_iface_count;
|
||||
};
|
||||
|
||||
struct _user_type_t {
|
||||
@@ -523,23 +621,20 @@ struct _user_type_t {
|
||||
const char *name;
|
||||
};
|
||||
|
||||
struct _type_list_t {
|
||||
type_t *type;
|
||||
struct _type_list_t *next;
|
||||
};
|
||||
|
||||
struct _statement_t {
|
||||
struct list entry;
|
||||
enum statement_type type;
|
||||
union
|
||||
{
|
||||
ifref_t iface;
|
||||
type_t *type;
|
||||
const char *str;
|
||||
var_t *var;
|
||||
typelib_t *lib;
|
||||
type_list_t *type_list;
|
||||
typeref_list_t *type_list;
|
||||
} u;
|
||||
/* For STMT_TYPE and STMT_TYPEDEF, should we define the UDT in this
|
||||
* statement, when writing a header? */
|
||||
unsigned int is_defined : 1;
|
||||
};
|
||||
|
||||
struct _warning_t {
|
||||
@@ -557,7 +652,7 @@ typedef enum {
|
||||
extern user_type_list_t user_type_list;
|
||||
extern context_handle_list_t context_handle_list;
|
||||
extern generic_handle_list_t generic_handle_list;
|
||||
void check_for_additional_prototype_types(const var_list_t *list);
|
||||
void check_for_additional_prototype_types(type_t *type);
|
||||
|
||||
void init_types(void);
|
||||
type_t *alloc_type(void);
|
||||
@@ -573,31 +668,23 @@ type_t *find_type(const char *name, struct namespace *namespace, int t);
|
||||
type_t *make_type(enum type_type type);
|
||||
type_t *get_type(enum type_type type, char *name, struct namespace *namespace, int t);
|
||||
type_t *reg_type(type_t *type, const char *name, struct namespace *namespace, int t);
|
||||
void add_incomplete(type_t *t);
|
||||
|
||||
var_t *make_var(char *name);
|
||||
var_list_t *append_var(var_list_t *list, var_t *var);
|
||||
|
||||
void init_loc_info(loc_info_t *);
|
||||
|
||||
char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix);
|
||||
|
||||
static inline var_list_t *type_get_function_args(const type_t *func_type)
|
||||
{
|
||||
return func_type->details.function->args;
|
||||
}
|
||||
char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix,
|
||||
const char *abi_prefix);
|
||||
char *format_parameterized_type_name(type_t *type, typeref_list_t *params);
|
||||
|
||||
static inline enum type_type type_get_type_detect_alias(const type_t *type)
|
||||
{
|
||||
if (type->is_alias)
|
||||
return TYPE_ALIAS;
|
||||
return type->type_type;
|
||||
}
|
||||
|
||||
#define STATEMENTS_FOR_EACH_FUNC(stmt, stmts) \
|
||||
if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, statement_t, entry ) \
|
||||
if (stmt->type == STMT_DECLARATION && stmt->u.var->stgclass == STG_NONE && \
|
||||
type_get_type_detect_alias(stmt->u.var->type) == TYPE_FUNCTION)
|
||||
if (stmt->type == STMT_DECLARATION && stmt->u.var->declspec.stgclass == STG_NONE && \
|
||||
type_get_type_detect_alias(stmt->u.var->declspec.type) == TYPE_FUNCTION)
|
||||
|
||||
static inline int statements_has_func(const statement_list_t *stmts)
|
||||
{
|
||||
@@ -616,4 +703,14 @@ static inline int is_global_namespace(const struct namespace *namespace)
|
||||
return !namespace->name;
|
||||
}
|
||||
|
||||
static inline decl_spec_t *init_declspec(decl_spec_t *declspec, type_t *type)
|
||||
{
|
||||
declspec->type = type;
|
||||
declspec->stgclass = STG_NONE;
|
||||
declspec->qualifier = 0;
|
||||
declspec->func_specifier = 0;
|
||||
|
||||
return declspec;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+270
-160
File diff suppressed because it is too large
Load Diff
+197
-246
@@ -19,7 +19,6 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "wine/port.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -28,23 +27,37 @@
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
|
||||
#define NONAMELESSUNION
|
||||
|
||||
#include "widl.h"
|
||||
#ifdef __REACTOS__
|
||||
#include <typedefs.h>
|
||||
#include <nls.h>
|
||||
#include <stddef.h>
|
||||
#else
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#endif
|
||||
|
||||
#include "widl.h"
|
||||
#include "typelib.h"
|
||||
#include "typelib_struct.h"
|
||||
#include "utils.h"
|
||||
#include "header.h"
|
||||
#include "typetree.h"
|
||||
|
||||
#ifdef __REACTOS__
|
||||
|
||||
typedef struct _GUID
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
unsigned long Data1;
|
||||
#else
|
||||
unsigned int Data1;
|
||||
#endif
|
||||
unsigned short Data2;
|
||||
unsigned short Data3;
|
||||
unsigned char Data4[ 8 ];
|
||||
} GUID;
|
||||
#endif
|
||||
|
||||
static const GUID sltg_library_guid = { 0x204ff,0,0,{ 0xc0,0,0,0,0,0,0,0x46 } };
|
||||
|
||||
struct sltg_data
|
||||
@@ -71,7 +84,6 @@ struct sltg_block
|
||||
int length;
|
||||
int index_string;
|
||||
void *data;
|
||||
struct sltg_block *next;
|
||||
};
|
||||
|
||||
struct sltg_typelib
|
||||
@@ -81,9 +93,9 @@ struct sltg_typelib
|
||||
struct sltg_data name_table;
|
||||
struct sltg_library library;
|
||||
struct sltg_block *blocks;
|
||||
int n_file_blocks;
|
||||
int block_count;
|
||||
int first_block;
|
||||
int typeinfo_count;
|
||||
short typeinfo_count;
|
||||
int typeinfo_size;
|
||||
struct sltg_block *typeinfo;
|
||||
};
|
||||
@@ -133,7 +145,7 @@ struct sltg_variable
|
||||
int memid;
|
||||
short helpcontext;
|
||||
short helpstring;
|
||||
short varflags; /* only present if magic & 0x02 */
|
||||
short varflags; /* only present if magic & 0x20 */
|
||||
};
|
||||
|
||||
struct sltg_tail
|
||||
@@ -171,23 +183,7 @@ struct sltg_hrefinfo
|
||||
{
|
||||
char magic; /* 0xdf */
|
||||
char res01; /* 0x00 */
|
||||
int res02; /* 0xffffffff */
|
||||
int res06; /* 0xffffffff */
|
||||
int res0a; /* 0xffffffff */
|
||||
int res0e; /* 0xffffffff */
|
||||
int res12; /* 0xffffffff */
|
||||
int res16; /* 0xffffffff */
|
||||
int res1a; /* 0xffffffff */
|
||||
int res1e; /* 0xffffffff */
|
||||
int res22; /* 0xffffffff */
|
||||
int res26; /* 0xffffffff */
|
||||
int res2a; /* 0xffffffff */
|
||||
int res2e; /* 0xffffffff */
|
||||
int res32; /* 0xffffffff */
|
||||
int res36; /* 0xffffffff */
|
||||
int res3a; /* 0xffffffff */
|
||||
int res3e; /* 0xffffffff */
|
||||
short res42;/* 0xffff */
|
||||
char res02[0x42]; /* 0xff... */
|
||||
int number; /* this is 8 times the number of refs */
|
||||
/* Now we have number bytes (8 for each ref) of SLTG_UnknownRefInfo */
|
||||
|
||||
@@ -257,8 +253,8 @@ static void add_coclass_typeinfo(struct sltg_typelib *typelib, type_t *type);
|
||||
static void init_sltg_data(struct sltg_data *data)
|
||||
{
|
||||
data->size = 0;
|
||||
data->allocated = 0x10;
|
||||
data->data = xmalloc(0x10);
|
||||
data->allocated = 0;
|
||||
data->data = NULL;
|
||||
}
|
||||
|
||||
static int add_index(struct sltg_data *index, const char *name)
|
||||
@@ -270,7 +266,7 @@ static int add_index(struct sltg_data *index, const char *name)
|
||||
|
||||
if (new_size > index->allocated)
|
||||
{
|
||||
index->allocated = max(index->allocated * 2, new_size);
|
||||
index->allocated = index->allocated ? max(index->allocated * 2, new_size) : new_size;
|
||||
index->data = xrealloc(index->data, index->allocated);
|
||||
}
|
||||
|
||||
@@ -289,10 +285,10 @@ static void init_index(struct sltg_data *index)
|
||||
add_index(index, compobj);
|
||||
}
|
||||
|
||||
static int add_name(struct sltg_typelib *sltg, const char *name)
|
||||
static int add_name(struct sltg_data *name_table, const char *name)
|
||||
{
|
||||
int name_offset = sltg->name_table.size;
|
||||
int new_size = sltg->name_table.size + strlen(name) + 1 + 8;
|
||||
int name_offset = name_table->size;
|
||||
int new_size = name_table->size + strlen(name) + 1 + 8;
|
||||
int aligned_size;
|
||||
|
||||
chat("add_name: %s\n", name);
|
||||
@@ -303,33 +299,37 @@ static int add_name(struct sltg_typelib *sltg, const char *name)
|
||||
else
|
||||
new_size = (new_size + 1) & ~1;
|
||||
|
||||
if (new_size > sltg->name_table.allocated)
|
||||
if (new_size > name_table->allocated)
|
||||
{
|
||||
sltg->name_table.allocated = max(sltg->name_table.allocated * 2, new_size);
|
||||
sltg->name_table.data = xrealloc(sltg->name_table.data, sltg->name_table.allocated);
|
||||
name_table->allocated = name_table->allocated ? max(name_table->allocated * 2, new_size) : new_size;
|
||||
name_table->data = xrealloc(name_table->data, name_table->allocated);
|
||||
}
|
||||
|
||||
memset(sltg->name_table.data + sltg->name_table.size, 0xff, 8);
|
||||
strcpy(sltg->name_table.data + sltg->name_table.size + 8, name);
|
||||
sltg->name_table.size = new_size;
|
||||
sltg->name_table.data[sltg->name_table.size - 1] = 0; /* clear alignment */
|
||||
memset(name_table->data + name_table->size, 0xff, 8);
|
||||
strcpy(name_table->data + name_table->size + 8, name);
|
||||
name_table->size = new_size;
|
||||
name_table->data[name_table->size - 1] = 0; /* clear alignment */
|
||||
|
||||
return name_offset;
|
||||
}
|
||||
|
||||
static void init_name_table(struct sltg_typelib *sltg)
|
||||
static void init_name_table(struct sltg_data *name_table)
|
||||
{
|
||||
init_sltg_data(&sltg->name_table);
|
||||
init_sltg_data(name_table);
|
||||
}
|
||||
|
||||
static void init_library(struct sltg_typelib *sltg)
|
||||
{
|
||||
const attr_t *attr;
|
||||
|
||||
sltg->library.name = add_name(sltg, sltg->typelib->name);
|
||||
sltg->library.name = add_name(&sltg->name_table, sltg->typelib->name);
|
||||
sltg->library.helpstring = NULL;
|
||||
sltg->library.helpcontext = 0;
|
||||
#ifdef __REACTOS__
|
||||
sltg->library.syskind = (pointer_size == 8) ? SYS_WIN64 : SYS_WIN32;
|
||||
#else
|
||||
sltg->library.syskind = SYS_WIN32;
|
||||
#endif
|
||||
sltg->library.lcid = 0x0409;
|
||||
sltg->library.libflags = 0;
|
||||
sltg->library.version = 0;
|
||||
@@ -379,28 +379,13 @@ static void init_library(struct sltg_typelib *sltg)
|
||||
}
|
||||
}
|
||||
|
||||
static void add_block_index(struct sltg_typelib *sltg, void *data, int size, int index)
|
||||
static void add_block_index(struct sltg_typelib *sltg, void *data, int length, int index)
|
||||
{
|
||||
struct sltg_block *block = xmalloc(sizeof(*block));
|
||||
|
||||
block->length = size;
|
||||
block->data = data;
|
||||
block->index_string = index;
|
||||
block->next = NULL;
|
||||
|
||||
if (sltg->blocks)
|
||||
{
|
||||
struct sltg_block *blocks = sltg->blocks;
|
||||
|
||||
while (blocks->next)
|
||||
blocks = blocks->next;
|
||||
|
||||
blocks->next = block;
|
||||
}
|
||||
else
|
||||
sltg->blocks = block;
|
||||
|
||||
sltg->n_file_blocks++;
|
||||
sltg->blocks = xrealloc(sltg->blocks, sizeof(sltg->blocks[0]) * (sltg->block_count + 1));
|
||||
sltg->blocks[sltg->block_count].length = length;
|
||||
sltg->blocks[sltg->block_count].data = data;
|
||||
sltg->blocks[sltg->block_count].index_string = index;
|
||||
sltg->block_count++;
|
||||
}
|
||||
|
||||
static void add_block(struct sltg_typelib *sltg, void *data, int size, const char *name)
|
||||
@@ -464,7 +449,7 @@ static void *create_library_block(struct sltg_typelib *typelib, int *size, int *
|
||||
|
||||
static const char *new_index_name(void)
|
||||
{
|
||||
static char name[11] = "0000000000";
|
||||
static char name[11] = "AAAAAAAAAA";
|
||||
static int pos = 0;
|
||||
char *new_name;
|
||||
|
||||
@@ -482,31 +467,16 @@ static const char *new_index_name(void)
|
||||
return new_name;
|
||||
}
|
||||
|
||||
static void sltg_add_typeinfo(struct sltg_typelib *sltg, void *data, int size, const char *name)
|
||||
static void sltg_add_typeinfo(struct sltg_typelib *sltg, void *data, int length, const char *name)
|
||||
{
|
||||
struct sltg_block *block = xmalloc(sizeof(*block));
|
||||
|
||||
chat("sltg_add_typeinfo: %p,%d,%s\n", data, size, name);
|
||||
|
||||
block->length = size;
|
||||
block->data = data;
|
||||
block->index_string = 0;
|
||||
block->next = NULL;
|
||||
|
||||
if (sltg->typeinfo)
|
||||
{
|
||||
struct sltg_block *typeinfo = sltg->typeinfo;
|
||||
|
||||
while (typeinfo->next)
|
||||
typeinfo = typeinfo->next;
|
||||
|
||||
typeinfo->next = block;
|
||||
}
|
||||
else
|
||||
sltg->typeinfo = block;
|
||||
chat("sltg_add_typeinfo: %p,%d,%s\n", data, length, name);
|
||||
|
||||
sltg->typeinfo = xrealloc(sltg->typeinfo, sizeof(sltg->typeinfo[0]) * (sltg->typeinfo_count + 1));
|
||||
sltg->typeinfo[sltg->typeinfo_count].length = length;
|
||||
sltg->typeinfo[sltg->typeinfo_count].data = data;
|
||||
sltg->typeinfo[sltg->typeinfo_count].index_string = 0;
|
||||
sltg->typeinfo_count++;
|
||||
sltg->typeinfo_size += size;
|
||||
sltg->typeinfo_size += length;
|
||||
}
|
||||
|
||||
static void append_data(struct sltg_data *block, const void *data, int size)
|
||||
@@ -528,12 +498,13 @@ static void add_module_typeinfo(struct sltg_typelib *typelib, type_t *type)
|
||||
error("add_module_typeinfo: %s not implemented\n", type->name);
|
||||
}
|
||||
|
||||
static const char *add_typeinfo_block(struct sltg_typelib *typelib, const type_t *type, int kind)
|
||||
static const char *add_typeinfo_block(struct sltg_typelib *typelib, const type_t *type, short kind)
|
||||
{
|
||||
struct sltg_data block;
|
||||
const char *index_name, *other_name;
|
||||
void *block;
|
||||
short *p;
|
||||
int size, helpcontext = 0;
|
||||
short val;
|
||||
void *p;
|
||||
int helpcontext = 0;
|
||||
GUID guid = { 0 };
|
||||
const expr_t *expr;
|
||||
|
||||
@@ -546,38 +517,40 @@ static const char *add_typeinfo_block(struct sltg_typelib *typelib, const type_t
|
||||
p = get_attrp(type->attrs, ATTR_UUID);
|
||||
if (p) guid = *(GUID *)p;
|
||||
|
||||
size = sizeof(short) * 8 + 10 /* index_name */ * 2 + sizeof(int) + sizeof(GUID);
|
||||
init_sltg_data(&block);
|
||||
|
||||
block = xmalloc(size);
|
||||
p = block;
|
||||
*p++ = strlen(index_name);
|
||||
strcpy((char *)p, index_name);
|
||||
p = (short *)((char *)p + strlen(index_name));
|
||||
*p++ = strlen(other_name);
|
||||
strcpy((char *)p, other_name);
|
||||
p = (short *)((char *)p + strlen(other_name));
|
||||
*p++ = -1; /* res1a */
|
||||
*p++ = add_name(typelib, type->name); /* name offset */
|
||||
*p++ = 0; /* FIXME: helpstring */
|
||||
*p++ = -1; /* res20 */
|
||||
*(int *)p = helpcontext;
|
||||
p += 2;
|
||||
*p++ = -1; /* res26 */
|
||||
*(GUID *)p = guid;
|
||||
p += sizeof(GUID)/2;
|
||||
*p = kind;
|
||||
val = strlen(index_name);
|
||||
append_data(&block, &val, sizeof(val));
|
||||
append_data(&block, index_name, val);
|
||||
val = strlen(other_name);
|
||||
append_data(&block, &val, sizeof(val));
|
||||
append_data(&block, other_name, val);
|
||||
val = -1; /* res1a */
|
||||
append_data(&block, &val, sizeof(val));
|
||||
val = add_name(&typelib->name_table, type->name); /* name offset */
|
||||
append_data(&block, &val, sizeof(val));
|
||||
val = 0; /* FIXME: helpstring */
|
||||
append_data(&block, &val, sizeof(val));
|
||||
val = -1; /* res20 */
|
||||
append_data(&block, &val, sizeof(val));
|
||||
append_data(&block, &helpcontext, sizeof(helpcontext));
|
||||
val = -1; /* res26 */
|
||||
append_data(&block, &val, sizeof(val));
|
||||
append_data(&block, &guid, sizeof(guid));
|
||||
append_data(&block, &kind, sizeof(kind));
|
||||
|
||||
sltg_add_typeinfo(typelib, block, size, index_name);
|
||||
sltg_add_typeinfo(typelib, block.data, block.size, index_name);
|
||||
|
||||
return index_name;
|
||||
}
|
||||
|
||||
static void init_typeinfo(struct sltg_typeinfo_header *ti, const type_t *type, int kind,
|
||||
static void init_typeinfo(struct sltg_typeinfo_header *ti, const type_t *type, short kind,
|
||||
const struct sltg_hrefmap *hrefmap)
|
||||
{
|
||||
ti->magic = 0x0501;
|
||||
ti->href_offset = -1;
|
||||
ti->res06 = -1;
|
||||
ti->member_offset = sizeof(*ti);
|
||||
ti->res0e = -1;
|
||||
ti->version = get_attrv(type->attrs, ATTR_VERSION);
|
||||
ti->res16 = 0xfffe0000;
|
||||
@@ -587,8 +560,6 @@ static void init_typeinfo(struct sltg_typeinfo_header *ti, const type_t *type, i
|
||||
ti->misc.typekind = kind;
|
||||
ti->res1e = 0;
|
||||
|
||||
ti->member_offset = sizeof(*ti);
|
||||
|
||||
if (hrefmap->href_count)
|
||||
{
|
||||
char name[64];
|
||||
@@ -598,7 +569,7 @@ static void init_typeinfo(struct sltg_typeinfo_header *ti, const type_t *type, i
|
||||
|
||||
for (i = 0; i < hrefmap->href_count; i++)
|
||||
{
|
||||
sprintf(name, "*\\Rffff*#%x", hrefmap->href[i]);
|
||||
snprintf(name, sizeof(name), "*\\Rffff*#%x", hrefmap->href[i]);
|
||||
hrefinfo_size += 8 + 2 + strlen(name);
|
||||
}
|
||||
|
||||
@@ -607,37 +578,6 @@ static void init_typeinfo(struct sltg_typeinfo_header *ti, const type_t *type, i
|
||||
}
|
||||
}
|
||||
|
||||
static void init_sltg_tail(struct sltg_tail *tail)
|
||||
{
|
||||
tail->cFuncs = 0;
|
||||
tail->cVars = 0;
|
||||
tail->cImplTypes = 0;
|
||||
tail->res06 = 0;
|
||||
tail->funcs_off = -1;
|
||||
tail->vars_off = -1;
|
||||
tail->impls_off = -1;
|
||||
tail->funcs_bytes = -1;
|
||||
tail->vars_bytes = -1;
|
||||
tail->impls_bytes = -1;
|
||||
tail->tdescalias_vt = -1;
|
||||
tail->res16 = -1;
|
||||
tail->res18 = 0;
|
||||
tail->res1a = 0;
|
||||
tail->simple_alias = 0;
|
||||
tail->res1e = 0;
|
||||
tail->cbSizeInstance = 0;
|
||||
tail->cbAlignment = 4;
|
||||
tail->res24 = -1;
|
||||
tail->res26 = -1;
|
||||
tail->cbSizeVft = 0;
|
||||
tail->res2a = -1;
|
||||
tail->res2c = -1;
|
||||
tail->res2e = -1;
|
||||
tail->res30 = -1;
|
||||
tail->res32 = 0;
|
||||
tail->type_bytes = 0;
|
||||
}
|
||||
|
||||
static void write_hrefmap(struct sltg_data *data, const struct sltg_hrefmap *hrefmap)
|
||||
{
|
||||
struct sltg_hrefinfo hrefinfo;
|
||||
@@ -648,23 +588,7 @@ static void write_hrefmap(struct sltg_data *data, const struct sltg_hrefmap *hre
|
||||
|
||||
hrefinfo.magic = 0xdf;
|
||||
hrefinfo.res01 = 0;
|
||||
hrefinfo.res02 = -1;
|
||||
hrefinfo.res06 = -1;
|
||||
hrefinfo.res0a = -1;
|
||||
hrefinfo.res0e = -1;
|
||||
hrefinfo.res12 = -1;
|
||||
hrefinfo.res16 = -1;
|
||||
hrefinfo.res1a = -1;
|
||||
hrefinfo.res1e = -1;
|
||||
hrefinfo.res22 = -1;
|
||||
hrefinfo.res26 = -1;
|
||||
hrefinfo.res2a = -1;
|
||||
hrefinfo.res2e = -1;
|
||||
hrefinfo.res32 = -1;
|
||||
hrefinfo.res36 = -1;
|
||||
hrefinfo.res3a = -1;
|
||||
hrefinfo.res3e = -1;
|
||||
hrefinfo.res42 = -1;
|
||||
memset(hrefinfo.res02, 0xff, sizeof(hrefinfo.res02));
|
||||
hrefinfo.number = hrefmap->href_count * 8;
|
||||
hrefinfo.res50 = -1;
|
||||
hrefinfo.res52 = 1;
|
||||
@@ -682,7 +606,7 @@ static void write_hrefmap(struct sltg_data *data, const struct sltg_hrefmap *hre
|
||||
{
|
||||
short len;
|
||||
|
||||
sprintf(name, "*\\Rffff*#%x", hrefmap->href[i]);
|
||||
snprintf(name, sizeof(name), "*\\Rffff*#%x", hrefmap->href[i]);
|
||||
len = strlen(name);
|
||||
|
||||
append_data(data, &len, sizeof(len));
|
||||
@@ -717,15 +641,13 @@ static int get_element_size(type_t *type)
|
||||
case VT_UI1:
|
||||
return 1;
|
||||
|
||||
case VT_INT:
|
||||
case VT_UINT:
|
||||
return /* typelib_kind == SYS_WIN16 ? 2 : */ 4;
|
||||
|
||||
case VT_UI2:
|
||||
case VT_I2:
|
||||
case VT_BOOL:
|
||||
return 2;
|
||||
|
||||
case VT_INT:
|
||||
case VT_UINT:
|
||||
case VT_I4:
|
||||
case VT_UI4:
|
||||
case VT_R4:
|
||||
@@ -749,13 +671,21 @@ static int get_element_size(type_t *type)
|
||||
case VT_BSTR:
|
||||
case VT_LPSTR:
|
||||
case VT_LPWSTR:
|
||||
#ifdef __REACTOS__
|
||||
return pointer_size;
|
||||
#else
|
||||
return 4;
|
||||
#endif
|
||||
|
||||
case VT_VOID:
|
||||
return 0;
|
||||
|
||||
case VT_VARIANT:
|
||||
#ifdef __REACTOS__
|
||||
return pointer_size == 8 ? 24 : 16;
|
||||
#else
|
||||
return 16;
|
||||
#endif
|
||||
|
||||
case VT_USERDEFINED:
|
||||
return 0;
|
||||
@@ -817,7 +747,7 @@ static short write_var_desc(struct sltg_typelib *typelib, struct sltg_data *data
|
||||
short fFeatures;
|
||||
int cbElements;
|
||||
int cLocks;
|
||||
void *pvData;
|
||||
int pvData;
|
||||
int bound[2];
|
||||
} *array;
|
||||
int *bound;
|
||||
@@ -833,7 +763,7 @@ static short write_var_desc(struct sltg_typelib *typelib, struct sltg_data *data
|
||||
num_dims++;
|
||||
elements *= type_array_get_dim(atype);
|
||||
|
||||
atype = type_array_get_element(atype);
|
||||
atype = type_array_get_element_type(atype);
|
||||
}
|
||||
|
||||
chat("write_var_desc: VT_CARRAY: %d dimensions, %d elements\n", num_dims, elements);
|
||||
@@ -847,7 +777,7 @@ static short write_var_desc(struct sltg_typelib *typelib, struct sltg_data *data
|
||||
array->fFeatures = 0x0004; /* FADF_EMBEDDED */
|
||||
array->cbElements = get_element_size(atype);
|
||||
array->cLocks = 0;
|
||||
array->pvData = NULL;
|
||||
array->pvData = 0;
|
||||
|
||||
bound = array->bound;
|
||||
|
||||
@@ -861,7 +791,7 @@ static short write_var_desc(struct sltg_typelib *typelib, struct sltg_data *data
|
||||
bound[1] = 0;
|
||||
bound += 2;
|
||||
|
||||
atype = type_array_get_element(atype);
|
||||
atype = type_array_get_element_type(atype);
|
||||
}
|
||||
|
||||
if (size_instance)
|
||||
@@ -888,7 +818,7 @@ static short write_var_desc(struct sltg_typelib *typelib, struct sltg_data *data
|
||||
|
||||
if (vt == VT_PTR)
|
||||
{
|
||||
type_t *ref = is_ptr(type) ? type_pointer_get_ref(type) : type_array_get_element(type);
|
||||
type_t *ref = is_ptr(type) ? type_pointer_get_ref_type(type) : type_array_get_element_type(type);
|
||||
|
||||
if (is_ptr(ref))
|
||||
{
|
||||
@@ -912,7 +842,7 @@ static short write_var_desc(struct sltg_typelib *typelib, struct sltg_data *data
|
||||
short href;
|
||||
|
||||
while (type->typelib_idx < 0 && type_is_alias(type))
|
||||
type = type_alias_get_aliasee(type);
|
||||
type = type_alias_get_aliasee_type(type);
|
||||
|
||||
chat("write_var_desc: VT_USERDEFINED, type %p, name %s, real type %d, href %d\n",
|
||||
type, type->name, type_get_type(type), type->typelib_idx);
|
||||
@@ -959,6 +889,37 @@ static short write_var_desc(struct sltg_typelib *typelib, struct sltg_data *data
|
||||
return desc_offset;
|
||||
}
|
||||
|
||||
static void init_sltg_tail(struct sltg_tail *tail)
|
||||
{
|
||||
tail->cFuncs = 0;
|
||||
tail->cVars = 0;
|
||||
tail->cImplTypes = 0;
|
||||
tail->res06 = 0;
|
||||
tail->funcs_off = -1;
|
||||
tail->vars_off = -1;
|
||||
tail->impls_off = -1;
|
||||
tail->funcs_bytes = -1;
|
||||
tail->vars_bytes = -1;
|
||||
tail->impls_bytes = -1;
|
||||
tail->tdescalias_vt = -1;
|
||||
tail->res16 = -1;
|
||||
tail->res18 = 0;
|
||||
tail->res1a = 0;
|
||||
tail->simple_alias = 0;
|
||||
tail->res1e = 0;
|
||||
tail->cbSizeInstance = 0;
|
||||
tail->cbAlignment = 4;
|
||||
tail->res24 = -1;
|
||||
tail->res26 = -1;
|
||||
tail->cbSizeVft = 0;
|
||||
tail->res2a = -1;
|
||||
tail->res2c = -1;
|
||||
tail->res2e = -1;
|
||||
tail->res30 = -1;
|
||||
tail->res32 = 0;
|
||||
tail->type_bytes = 0;
|
||||
}
|
||||
|
||||
static void add_structure_typeinfo(struct sltg_typelib *typelib, type_t *type)
|
||||
{
|
||||
struct sltg_data data, *var_data = NULL;
|
||||
@@ -974,7 +935,7 @@ static void add_structure_typeinfo(struct sltg_typelib *typelib, type_t *type)
|
||||
|
||||
chat("add_structure_typeinfo: type %p, type->name %s\n", type, type->name);
|
||||
|
||||
type->typelib_idx = typelib->n_file_blocks;
|
||||
type->typelib_idx = typelib->block_count;
|
||||
|
||||
hrefmap.href_count = 0;
|
||||
hrefmap.href = NULL;
|
||||
@@ -994,12 +955,12 @@ static void add_structure_typeinfo(struct sltg_typelib *typelib, type_t *type)
|
||||
short base_offset;
|
||||
|
||||
chat("add_structure_typeinfo: var %p (%s), type %p (%s)\n",
|
||||
var, var->name, var->type, var->type->name);
|
||||
var, var->name, var->declspec.type, var->declspec.type->name);
|
||||
|
||||
init_sltg_data(&var_data[i]);
|
||||
|
||||
base_offset = var_data_size + (i + 1) * sizeof(struct sltg_variable);
|
||||
type_desc_offset[i] = write_var_desc(typelib, &var_data[i], var->type, 0, 0,
|
||||
type_desc_offset[i] = write_var_desc(typelib, &var_data[i], var->declspec.type, 0, 0,
|
||||
base_offset, &size_instance, &hrefmap);
|
||||
dump_var_desc(var_data[i].data, var_data[i].size);
|
||||
|
||||
@@ -1041,7 +1002,7 @@ static void add_structure_typeinfo(struct sltg_typelib *typelib, type_t *type)
|
||||
next += sizeof(variable);
|
||||
|
||||
variable.magic = 0x2a; /* always write flags to simplify calculations */
|
||||
variable.name = add_name(typelib, var->name);
|
||||
variable.name = add_name(&typelib->name_table, var->name);
|
||||
variable.byte_offs = 0;
|
||||
if (var_data[i].size > sizeof(short))
|
||||
{
|
||||
@@ -1070,7 +1031,6 @@ static void add_structure_typeinfo(struct sltg_typelib *typelib, type_t *type)
|
||||
}
|
||||
|
||||
init_sltg_tail(&tail);
|
||||
|
||||
tail.cVars = var_count;
|
||||
tail.vars_off = 0;
|
||||
tail.vars_bytes = var_data_size;
|
||||
@@ -1133,7 +1093,7 @@ static int get_func_flags(const var_t *func, int *dispid, int *invokekind, int *
|
||||
flags |= 0x10; /* FUNCFLAG_FDISPLAYBIND */
|
||||
break;
|
||||
case ATTR_HELPCONTEXT:
|
||||
*helpcontext = expr->u.lval;
|
||||
*helpcontext = expr->u.integer.value;
|
||||
break;
|
||||
case ATTR_HELPSTRING:
|
||||
*helpstring = attr->u.pval;
|
||||
@@ -1216,12 +1176,7 @@ static int get_param_flags(const var_t *param)
|
||||
}
|
||||
|
||||
if (out)
|
||||
{
|
||||
if (in)
|
||||
flags |= 0x8000;
|
||||
else
|
||||
flags |= 0x4000;
|
||||
}
|
||||
flags |= in ? 0x8000 : 0x4000;
|
||||
else if (!in)
|
||||
flags |= 0xc000;
|
||||
|
||||
@@ -1233,7 +1188,7 @@ static int add_func_desc(struct sltg_typelib *typelib, struct sltg_data *data, v
|
||||
int idx, int dispid, short base_offset, struct sltg_hrefmap *hrefmap)
|
||||
{
|
||||
struct sltg_data ret_data, *arg_data;
|
||||
int arg_count = 0, arg_data_size, optional = 0, defaults = 0, old_size;
|
||||
int arg_count = 0, arg_data_size, optional = 0, old_size;
|
||||
int funcflags = 0, invokekind = 1 /* INVOKE_FUNC */, helpcontext;
|
||||
const char *helpstring;
|
||||
const var_t *arg;
|
||||
@@ -1245,7 +1200,7 @@ static int add_func_desc(struct sltg_typelib *typelib, struct sltg_data *data, v
|
||||
old_size = data->size;
|
||||
|
||||
init_sltg_data(&ret_data);
|
||||
ret_desc_offset = write_var_desc(typelib, &ret_data, type_function_get_rettype(func->type),
|
||||
ret_desc_offset = write_var_desc(typelib, &ret_data, type_function_get_rettype(func->declspec.type),
|
||||
0, 0, base_offset, NULL, hrefmap);
|
||||
dump_var_desc(ret_data.data, ret_data.size);
|
||||
|
||||
@@ -1258,35 +1213,36 @@ static int add_func_desc(struct sltg_typelib *typelib, struct sltg_data *data, v
|
||||
arg_offset += ret_data.size;
|
||||
}
|
||||
|
||||
if (type_get_function_args(func->type))
|
||||
if (type_function_get_args(func->declspec.type))
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
arg_count = list_count(type_get_function_args(func->type));
|
||||
arg_count = list_count(type_function_get_args(func->declspec.type));
|
||||
|
||||
arg_data = xmalloc(arg_count * sizeof(*arg_data));
|
||||
arg_desc_offset = xmalloc(arg_count * sizeof(*arg_desc_offset));
|
||||
|
||||
arg_offset += arg_count * 2 * sizeof(short);
|
||||
|
||||
LIST_FOR_EACH_ENTRY(arg, type_get_function_args(func->type), const var_t, entry)
|
||||
LIST_FOR_EACH_ENTRY(arg, type_function_get_args(func->declspec.type), const var_t, entry)
|
||||
{
|
||||
const attr_t *attr;
|
||||
short param_flags = get_param_flags(arg);
|
||||
|
||||
chat("add_func_desc: arg[%d] %p (%s), type %p (%s)\n",
|
||||
i, arg, arg->name, arg->type, arg->type->name);
|
||||
i, arg, arg->name, arg->declspec.type, arg->declspec.type->name);
|
||||
|
||||
init_sltg_data(&arg_data[i]);
|
||||
|
||||
arg_desc_offset[i] = write_var_desc(typelib, &arg_data[i], arg->type, param_flags, 0,
|
||||
|
||||
arg_desc_offset[i] = write_var_desc(typelib, &arg_data[i], arg->declspec.type, param_flags, 0,
|
||||
arg_offset, NULL, hrefmap);
|
||||
dump_var_desc(arg_data[i].data, arg_data[i].size);
|
||||
|
||||
if (arg_data[i].size > sizeof(short))
|
||||
{
|
||||
arg_data_size += arg_data[i].size;
|
||||
arg_offset += arg_data[i].size;;
|
||||
arg_offset += arg_data[i].size;
|
||||
}
|
||||
|
||||
i++;
|
||||
@@ -1295,9 +1251,7 @@ static int add_func_desc(struct sltg_typelib *typelib, struct sltg_data *data, v
|
||||
|
||||
LIST_FOR_EACH_ENTRY(attr, arg->attrs, const attr_t, entry)
|
||||
{
|
||||
if (attr->type == ATTR_DEFAULTVALUE)
|
||||
defaults++;
|
||||
else if(attr->type == ATTR_OPTIONAL)
|
||||
if (attr->type == ATTR_OPTIONAL)
|
||||
optional++;
|
||||
}
|
||||
}
|
||||
@@ -1318,10 +1272,10 @@ static int add_func_desc(struct sltg_typelib *typelib, struct sltg_data *data, v
|
||||
}
|
||||
else
|
||||
func_desc.next = base_offset + sizeof(func_desc) + arg_data_size + arg_count * 2 * sizeof(short);
|
||||
func_desc.name = base_offset != -1 ? add_name(typelib, func->name) : -1;
|
||||
func_desc.name = base_offset != -1 ? add_name(&typelib->name_table, func->name) : -1;
|
||||
func_desc.dispid = dispid;
|
||||
func_desc.helpcontext = helpcontext;
|
||||
func_desc.helpstring = (helpstring && base_offset != -1) ? add_name(typelib, helpstring) : -1;
|
||||
func_desc.helpstring = (helpstring && base_offset != -1) ? add_name(&typelib->name_table, helpstring) : -1;
|
||||
func_desc.arg_off = arg_count ? base_offset + sizeof(func_desc) : -1;
|
||||
func_desc.nacc = (arg_count << 3) | 4 /* CC_STDCALL */;
|
||||
func_desc.retnextopt = (optional << 1);
|
||||
@@ -1356,11 +1310,11 @@ static int add_func_desc(struct sltg_typelib *typelib, struct sltg_data *data, v
|
||||
|
||||
arg_offset += arg_count * 2 * sizeof(short);
|
||||
|
||||
LIST_FOR_EACH_ENTRY(arg, type_get_function_args(func->type), const var_t, entry)
|
||||
LIST_FOR_EACH_ENTRY(arg, type_function_get_args(func->declspec.type), const var_t, entry)
|
||||
{
|
||||
short name, type_offset;
|
||||
|
||||
name = base_offset != -1 ? add_name(typelib, arg->name) : -1;
|
||||
name = base_offset != -1 ? add_name(&typelib->name_table, arg->name) : -1;
|
||||
|
||||
if (arg_data[i].size > sizeof(short))
|
||||
{
|
||||
@@ -1476,7 +1430,7 @@ static void add_interface_typeinfo(struct sltg_typelib *typelib, type_t *iface)
|
||||
/* check typelib_idx again, it could have been added while resolving the parent interface */
|
||||
if (iface->typelib_idx != -1) return;
|
||||
|
||||
iface->typelib_idx = typelib->n_file_blocks;
|
||||
iface->typelib_idx = typelib->block_count;
|
||||
|
||||
/* pass 1: calculate function descriptions data size */
|
||||
init_sltg_data(&data);
|
||||
@@ -1617,11 +1571,15 @@ static void add_statement(struct sltg_typelib *typelib, const statement_t *stmt)
|
||||
|
||||
case STMT_TYPEDEF:
|
||||
{
|
||||
const type_list_t *type_entry = stmt->u.type_list;
|
||||
for (; type_entry; type_entry = type_entry->next)
|
||||
typeref_t *ref;
|
||||
|
||||
if (!stmt->u.type_list)
|
||||
break;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(ref, stmt->u.type_list, typeref_t, entry)
|
||||
{
|
||||
/* in old style typelibs all types are public */
|
||||
add_type_typeinfo(typelib, type_entry->type);
|
||||
add_type_typeinfo(typelib, ref->type);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1650,7 +1608,7 @@ static void sltg_write_header(struct sltg_typelib *sltg, int *library_block_star
|
||||
struct sltg_header
|
||||
{
|
||||
int magic;
|
||||
short n_file_blocks;
|
||||
short block_count;
|
||||
short res06;
|
||||
short size_of_index;
|
||||
short first_blk;
|
||||
@@ -1664,40 +1622,37 @@ static void sltg_write_header(struct sltg_typelib *sltg, int *library_block_star
|
||||
short index_string;
|
||||
short next;
|
||||
} entry;
|
||||
struct sltg_block *block;
|
||||
int i;
|
||||
|
||||
header.magic = 0x47544c53;
|
||||
header.n_file_blocks = sltg->n_file_blocks + 1;
|
||||
header.block_count = sltg->block_count + 1; /* 1-based */
|
||||
header.res06 = 9;
|
||||
header.size_of_index = sltg->index.size;
|
||||
header.first_blk = 1;
|
||||
header.first_blk = 1; /* 1-based */
|
||||
header.uuid = sltg_library_guid;
|
||||
header.res1c = 0x00000044;
|
||||
header.res20 = 0xffff0000;
|
||||
|
||||
put_data(&header, sizeof(header));
|
||||
|
||||
block = sltg->blocks;
|
||||
for (i = 0; i < sltg->n_file_blocks - 1; i++)
|
||||
/* library block is written separately */
|
||||
for (i = 0; i < sltg->block_count - 1; i++)
|
||||
{
|
||||
assert(block->next != NULL);
|
||||
|
||||
entry.length = block->length;
|
||||
entry.index_string = block->index_string;
|
||||
entry.next = header.first_blk + i + 1;
|
||||
entry.length = sltg->blocks[i].length;
|
||||
entry.index_string = sltg->blocks[i].index_string;
|
||||
entry.next = header.first_blk + i + 1; /* point to next block */
|
||||
chat("sltg_write_header: writing block entry %d: length %#x, index_string %#x, next %#x\n",
|
||||
i, entry.length, entry.index_string, entry.next);
|
||||
put_data(&entry, sizeof(entry));
|
||||
|
||||
block = block->next;
|
||||
}
|
||||
|
||||
assert(block->next == NULL);
|
||||
|
||||
/* library block length includes helpstrings and name table */
|
||||
entry.length = block->length + 0x40 + 2 + sltg->typeinfo_size + 4 + 6 + 12 + 0x200 + sltg->name_table.size + 12;
|
||||
entry.index_string = block->index_string;
|
||||
entry.length = sltg->blocks[sltg->block_count - 1].length + 0x40 /* pad after library block */ +
|
||||
sizeof(sltg->typeinfo_count) + sltg->typeinfo_size + 4 /* library block size */ + 6 /* dummy help strings */ +
|
||||
12 /* name table header */ + 0x200 /* name table hash */ +
|
||||
sizeof(sltg->name_table.size) + sltg->name_table.size +
|
||||
4 /* 0x01ffff01 */ + 4 /* 0 */;
|
||||
entry.index_string = sltg->blocks[sltg->block_count - 1].index_string;
|
||||
entry.next = 0;
|
||||
chat("sltg_write_header: writing library block entry %d: length %#x, index_string %#x, next %#x\n",
|
||||
i, entry.length, entry.index_string, entry.next);
|
||||
@@ -1708,22 +1663,18 @@ static void sltg_write_header(struct sltg_typelib *sltg, int *library_block_star
|
||||
memset(pad, 0, 9);
|
||||
put_data(pad, 9);
|
||||
|
||||
block = sltg->blocks;
|
||||
for (i = 0; i < sltg->n_file_blocks - 1; i++)
|
||||
/* library block is written separately */
|
||||
for (i = 0; i < sltg->block_count - 1; i++)
|
||||
{
|
||||
chat("sltg_write_header: writing block %d: %d bytes\n", i, block->length);
|
||||
|
||||
put_data(block->data, block->length);
|
||||
block = block->next;
|
||||
chat("sltg_write_header: writing block %d: %d bytes\n", i, sltg->blocks[i].length);
|
||||
put_data(sltg->blocks[i].data, sltg->blocks[i].length);
|
||||
}
|
||||
|
||||
assert(block->next == NULL);
|
||||
|
||||
/* library block */
|
||||
chat("library_block_start = %#lx\n", (SIZE_T)output_buffer_pos);
|
||||
chat("library_block_start = %#x\n", (int)output_buffer_pos);
|
||||
*library_block_start = output_buffer_pos;
|
||||
chat("sltg_write_header: writing library block %d: %d bytes\n", i, block->length);
|
||||
put_data(block->data, block->length);
|
||||
chat("sltg_write_header: writing library block %d: %d bytes\n", i, sltg->blocks[i].length);
|
||||
put_data(sltg->blocks[sltg->block_count - 1].data, sltg->blocks[sltg->block_count - 1].length);
|
||||
|
||||
chat("sltg_write_header: writing pad 0x40 bytes\n");
|
||||
memset(pad, 0xff, 0x40);
|
||||
@@ -1732,21 +1683,15 @@ static void sltg_write_header(struct sltg_typelib *sltg, int *library_block_star
|
||||
|
||||
static void sltg_write_typeinfo(struct sltg_typelib *typelib)
|
||||
{
|
||||
int i;
|
||||
struct sltg_block *block;
|
||||
short count = typelib->typeinfo_count;
|
||||
short i;
|
||||
|
||||
put_data(&count, sizeof(count));
|
||||
put_data(&typelib->typeinfo_count, sizeof(typelib->typeinfo_count));
|
||||
|
||||
block = typelib->typeinfo;
|
||||
for (i = 0; i < typelib->typeinfo_count; i++)
|
||||
{
|
||||
chat("sltg_write_typeinfo: writing block %d: %d bytes\n", i, block->length);
|
||||
|
||||
put_data(block->data, block->length);
|
||||
block = block->next;
|
||||
chat("sltg_write_typeinfo: writing block %d: %d bytes\n", i, typelib->typeinfo[i].length);
|
||||
put_data(typelib->typeinfo[i].data, typelib->typeinfo[i].length);
|
||||
}
|
||||
assert(block == NULL);
|
||||
}
|
||||
|
||||
static void sltg_write_helpstrings(struct sltg_typelib *typelib)
|
||||
@@ -1804,7 +1749,7 @@ static void save_all_changes(struct sltg_typelib *typelib)
|
||||
sltg_write_typeinfo(typelib);
|
||||
|
||||
name_table_offset = (int *)(output_buffer + output_buffer_pos);
|
||||
chat("name_table_offset = %#lx\n", (SIZE_T)output_buffer_pos);
|
||||
chat("name_table_offset = %#x\n", (int)output_buffer_pos);
|
||||
put_data(&library_block_start, sizeof(library_block_start));
|
||||
|
||||
sltg_write_helpstrings(typelib);
|
||||
@@ -1821,9 +1766,10 @@ static void save_all_changes(struct sltg_typelib *typelib)
|
||||
|
||||
expr_t *expr = get_attrp(typelib->typelib->attrs, ATTR_ID);
|
||||
if (expr)
|
||||
sprintf(typelib_id, "#%d", expr->cval);
|
||||
snprintf(typelib_id, sizeof(typelib_id), "#%d", expr->cval);
|
||||
add_output_to_resources("TYPELIB", typelib_id);
|
||||
output_typelib_regscript(typelib->typelib);
|
||||
if (strendswith(typelib_name, "_t.res")) /* add typelib registration */
|
||||
output_typelib_regscript(typelib->typelib);
|
||||
}
|
||||
else flush_output_buffer(typelib_name);
|
||||
}
|
||||
@@ -1835,16 +1781,21 @@ int create_sltg_typelib(typelib_t *typelib)
|
||||
void *library_block;
|
||||
int library_block_size, library_block_index;
|
||||
|
||||
#ifndef __REACTOS__
|
||||
if (pointer_size != 4)
|
||||
error("Only 32-bit platform is supported\n");
|
||||
#endif
|
||||
|
||||
sltg.typelib = typelib;
|
||||
sltg.typeinfo_count = 0;
|
||||
sltg.typeinfo_size = 0;
|
||||
sltg.typeinfo = NULL;
|
||||
sltg.blocks = NULL;
|
||||
sltg.n_file_blocks = 0;
|
||||
sltg.block_count = 0;
|
||||
sltg.first_block = 1;
|
||||
|
||||
init_index(&sltg.index);
|
||||
init_name_table(&sltg);
|
||||
init_name_table(&sltg.name_table);
|
||||
init_library(&sltg);
|
||||
|
||||
library_block = create_library_block(&sltg, &library_block_size, &library_block_index);
|
||||
|
||||
@@ -20,7 +20,8 @@ if(MSVC)
|
||||
# Disable warnings
|
||||
add_compile_options(
|
||||
/wd4146 # "unary minus operator applied to unsigned type, result still unsigned"
|
||||
/wd4244) # "'=': conversion from 'a' to 'b', possible loss of data"
|
||||
/wd4244 # "'=': conversion from 'a' to 'b', possible loss of data"
|
||||
/wd4090) # 'function': different 'const' qualifiers
|
||||
|
||||
endif()
|
||||
|
||||
@@ -35,12 +36,13 @@ if(CMAKE_CROSSCOMPILING)
|
||||
include_directories(${REACTOS_SOURCE_DIR}/sdk/include/wine)
|
||||
endif()
|
||||
|
||||
include_directories(${REACTOS_SOURCE_DIR}/sdk/tools/widl)
|
||||
|
||||
FLEX_TARGET(pp_scanner ppl.l ${CMAKE_CURRENT_BINARY_DIR}/ppl.yy.c)
|
||||
BISON_TARGET(pp_parser ppy.y ${CMAKE_CURRENT_BINARY_DIR}/ppy.tab.c COMPILE_FLAGS "-p ppy_")
|
||||
BISON_TARGET(pp_parser ppy.y ${CMAKE_CURRENT_BINARY_DIR}/ppy.tab.c)
|
||||
ADD_FLEX_BISON_DEPENDENCY(pp_scanner pp_parser)
|
||||
|
||||
list(APPEND SOURCE
|
||||
preproc.c
|
||||
wpp.c)
|
||||
|
||||
if(CMAKE_CROSSCOMPILING)
|
||||
|
||||
+92
-236
@@ -17,16 +17,6 @@
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
* History:
|
||||
* 24-Apr-2000 BS - Started from scratch to restructure everything
|
||||
* and reintegrate the source into the wine-tree.
|
||||
* 04-Jan-2000 BS - Added comments about the lexicographical
|
||||
* grammar to give some insight in the complexity.
|
||||
* 28-Dec-1999 BS - Eliminated backing-up of the flexer by running
|
||||
* `flex -b' on the source. This results in some
|
||||
* weirdo extra rules, but a much faster scanner.
|
||||
* 23-Dec-1999 BS - Started this file
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
* The preprocessor's lexographical grammar (approximately):
|
||||
*
|
||||
@@ -123,7 +113,6 @@
|
||||
|
||||
%top{
|
||||
#include "config.h"
|
||||
#include "wine/port.h"
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -150,6 +139,7 @@
|
||||
%x pp_macexp
|
||||
%x pp_if
|
||||
%x pp_ifd
|
||||
%x pp_ifignored
|
||||
%x pp_endif
|
||||
%x pp_line
|
||||
%x pp_defined
|
||||
@@ -162,6 +152,7 @@ ul [uUlL]|[uUlL][lL]|[lL][uU]|[lL][lL][uU]|[uU][lL][lL]|[lL][uU][lL]
|
||||
|
||||
%{
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
@@ -170,18 +161,17 @@ ul [uUlL]|[uUlL][lL]|[lL][uU]|[lL][lL][uU]|[uU][lL][lL]|[lL][uU][lL]
|
||||
#include <limits.h>
|
||||
|
||||
#ifndef LLONG_MAX
|
||||
# define LLONG_MAX ((long long)0x7fffffff << 32 | 0xffffffff)
|
||||
# define LLONG_MAX ((__int64)0x7fffffff << 32 | 0xffffffff)
|
||||
# define LLONG_MIN (-LLONG_MAX - 1)
|
||||
#endif
|
||||
#ifndef ULLONG_MAX
|
||||
# define ULLONG_MAX ((long long)0xffffffff << 32 | 0xffffffff)
|
||||
# define ULLONG_MAX ((__int64)0xffffffff << 32 | 0xffffffff)
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_UNISTD_H
|
||||
#define YY_NO_UNISTD_H
|
||||
#endif
|
||||
|
||||
#include "wine/wpp.h"
|
||||
#include "../tools.h"
|
||||
#include "utils.h"
|
||||
#include "wpp_private.h"
|
||||
#include "ppy.tab.h"
|
||||
|
||||
@@ -209,7 +199,7 @@ ul [uUlL]|[uUlL][lL]|[lL][uU]|[lL][lL][uU]|[uU][lL][lL]|[lL][uU][lL]
|
||||
|
||||
typedef struct bufferstackentry {
|
||||
YY_BUFFER_STATE bufferstate; /* Buffer to switch back to */
|
||||
void *filehandle; /* Handle to be used with wpp_callbacks->read */
|
||||
FILE *file; /* File handle */
|
||||
pp_entry_t *define; /* Points to expanding define or NULL if handling includes */
|
||||
int line_number; /* Line that we were handling */
|
||||
int char_number; /* The current position on that line */
|
||||
@@ -250,7 +240,7 @@ typedef struct macexpstackentry {
|
||||
* Prototypes
|
||||
*/
|
||||
static void newline(int);
|
||||
static int make_number(int radix, YYSTYPE *val, const char *str, int len);
|
||||
static int make_number(int radix, PPY_STYPE *val, const char *str, int len);
|
||||
static void put_buffer(const char *s, int len);
|
||||
/* Buffer management */
|
||||
static void push_buffer(pp_entry_t *ppp, char *filename, char *incname, int pop);
|
||||
@@ -301,60 +291,13 @@ include_state_t pp_incl_state =
|
||||
0 /* seen_junk */
|
||||
};
|
||||
|
||||
includelogicentry_t *pp_includelogiclist = NULL;
|
||||
static struct list pp_includelogiclist = LIST_INIT( pp_includelogiclist );
|
||||
|
||||
#define YY_INPUT(buf,result,max_size) \
|
||||
{ \
|
||||
result = wpp_callbacks->read(pp_status.file, buf, max_size); \
|
||||
result = fread(buf, 1, max_size, pp_status.file); \
|
||||
}
|
||||
|
||||
#define BUFFERINITIALCAPACITY 256
|
||||
|
||||
void pp_writestring(const char *format, ...)
|
||||
{
|
||||
va_list valist;
|
||||
int len;
|
||||
static char *buffer;
|
||||
static int buffercapacity;
|
||||
char *new_buffer;
|
||||
|
||||
if(buffercapacity == 0)
|
||||
{
|
||||
buffer = pp_xmalloc(BUFFERINITIALCAPACITY);
|
||||
if(buffer == NULL)
|
||||
return;
|
||||
buffercapacity = BUFFERINITIALCAPACITY;
|
||||
}
|
||||
|
||||
va_start(valist, format);
|
||||
len = vsnprintf(buffer, buffercapacity,
|
||||
format, valist);
|
||||
va_end(valist);
|
||||
/* If the string is longer than buffersize, vsnprintf returns
|
||||
* the string length with glibc >= 2.1, -1 with glibc < 2.1 */
|
||||
while(len > buffercapacity || len < 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
buffercapacity *= 2;
|
||||
} while(len > buffercapacity);
|
||||
|
||||
new_buffer = pp_xrealloc(buffer, buffercapacity);
|
||||
if(new_buffer == NULL)
|
||||
{
|
||||
va_end(valist);
|
||||
return;
|
||||
}
|
||||
buffer = new_buffer;
|
||||
va_start(valist, format);
|
||||
len = vsnprintf(buffer, buffercapacity,
|
||||
format, valist);
|
||||
va_end(valist);
|
||||
}
|
||||
|
||||
wpp_callbacks->write(buffer, len);
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
/*
|
||||
@@ -390,7 +333,7 @@ void pp_writestring(const char *format, ...)
|
||||
<pp_pp>{ws}*undef{ws}* if(yy_top_state() != pp_ignore) {yy_pp_state(pp_ifd); return tUNDEF;} else {yy_pp_state(pp_eol);}
|
||||
<pp_pp>{ws}*ifdef{ws}* yy_pp_state(pp_ifd); return tIFDEF;
|
||||
<pp_pp>{ws}*ifndef{ws}* pp_incl_state.seen_junk--; yy_pp_state(pp_ifd); return tIFNDEF;
|
||||
<pp_pp>{ws}*if{ws}* yy_pp_state(pp_if); return tIF;
|
||||
<pp_pp>{ws}*if{ws}* if(yy_top_state() != pp_ignore) {yy_pp_state(pp_if);} else {yy_pp_state(pp_ifignored);} return tIF;
|
||||
<pp_pp>{ws}*elif{ws}* yy_pp_state(pp_if); return tELIF;
|
||||
<pp_pp>{ws}*else{ws}* yy_pp_state(pp_endif); return tELSE;
|
||||
<pp_pp>{ws}*endif{ws}* yy_pp_state(pp_endif); return tENDIF;
|
||||
@@ -450,11 +393,14 @@ void pp_writestring(const char *format, ...)
|
||||
<pp_if>\" ppy_error("String constants not allowed in conditionals");
|
||||
<pp_if>. return *ppy_text;
|
||||
|
||||
<pp_ifignored>[^\n]+ ppy_lval.sint = 0; return tSINT;
|
||||
<pp_ifignored>\n newline(1); yy_pop_state(); return tNL;
|
||||
|
||||
/*
|
||||
* Handle #ifdef, #ifndef and #undef
|
||||
* to get only an untranslated/unexpanded identifier
|
||||
*/
|
||||
<pp_ifd>{cident} ppy_lval.cptr = pp_xstrdup(ppy_text); return tIDENT;
|
||||
<pp_ifd>{cident} ppy_lval.cptr = xstrdup(ppy_text); return tIDENT;
|
||||
<pp_ifd>{ws}+ ;
|
||||
<pp_ifd>\n newline(1); yy_pop_state(); return tNL;
|
||||
<pp_ifd>\\\r?\n newline(0);
|
||||
@@ -473,7 +419,7 @@ void pp_writestring(const char *format, ...)
|
||||
* This is necessary to get the identifier prior to any
|
||||
* substitutions.
|
||||
*/
|
||||
<pp_defined>{cident} yy_pop_state(); ppy_lval.cptr = pp_xstrdup(ppy_text); return tIDENT;
|
||||
<pp_defined>{cident} yy_pop_state(); ppy_lval.cptr = xstrdup(ppy_text); return tIDENT;
|
||||
<pp_defined>{ws}+ ;
|
||||
<pp_defined>(\()|(\)) return *ppy_text;
|
||||
<pp_defined>\\\r?\n newline(0);
|
||||
@@ -485,27 +431,27 @@ void pp_writestring(const char *format, ...)
|
||||
* will act appropriately.
|
||||
* Comments are stripped from the literal text.
|
||||
*/
|
||||
<pp_eol>[^/\\\n]+ if(yy_top_state() != pp_ignore) { ppy_lval.cptr = pp_xstrdup(ppy_text); return tLITERAL; }
|
||||
<pp_eol>\/[^/\\\n*]* if(yy_top_state() != pp_ignore) { ppy_lval.cptr = pp_xstrdup(ppy_text); return tLITERAL; }
|
||||
<pp_eol>(\\\r?)|(\/[^/*]) if(yy_top_state() != pp_ignore) { ppy_lval.cptr = pp_xstrdup(ppy_text); return tLITERAL; }
|
||||
<pp_eol>[^/\\\n]+ if(yy_top_state() != pp_ignore) { ppy_lval.cptr = xstrdup(ppy_text); return tLITERAL; }
|
||||
<pp_eol>\/[^/\\\n*]* if(yy_top_state() != pp_ignore) { ppy_lval.cptr = xstrdup(ppy_text); return tLITERAL; }
|
||||
<pp_eol>(\\\r?)|(\/[^/*]) if(yy_top_state() != pp_ignore) { ppy_lval.cptr = xstrdup(ppy_text); return tLITERAL; }
|
||||
<pp_eol>\n newline(1); yy_pop_state(); if(yy_current_state() != pp_ignore) { return tNL; }
|
||||
<pp_eol>\\\r?\n newline(0);
|
||||
|
||||
/*
|
||||
* Handle left side of #define
|
||||
*/
|
||||
<pp_def>{cident}\( ppy_lval.cptr = pp_xstrdup(ppy_text); if(ppy_lval.cptr) ppy_lval.cptr[ppy_leng-1] = '\0'; yy_pp_state(pp_macro); return tMACRO;
|
||||
<pp_def>{cident} ppy_lval.cptr = pp_xstrdup(ppy_text); yy_pp_state(pp_define); return tDEFINE;
|
||||
<pp_def>{cident}\( ppy_lval.cptr = xstrdup(ppy_text); ppy_lval.cptr[ppy_leng-1] = '\0'; yy_pp_state(pp_macro); return tMACRO;
|
||||
<pp_def>{cident} ppy_lval.cptr = xstrdup(ppy_text); yy_pp_state(pp_define); return tDEFINE;
|
||||
<pp_def>{ws}+ ;
|
||||
<pp_def>\\\r?\n newline(0);
|
||||
<pp_def>(\\\r?)|(\n)|(.) perror("Identifier expected");
|
||||
<pp_def>(\\\r?)|(\n)|(.) ppy_error("Identifier expected");
|
||||
|
||||
/*
|
||||
* Scan the substitution of a define
|
||||
*/
|
||||
<pp_define>[^'"/\\\n]+ ppy_lval.cptr = pp_xstrdup(ppy_text); return tLITERAL;
|
||||
<pp_define>(\\\r?)|(\/[^/*]) ppy_lval.cptr = pp_xstrdup(ppy_text); return tLITERAL;
|
||||
<pp_define>\\\r?\n{ws}+ newline(0); ppy_lval.cptr = pp_xstrdup(" "); return tLITERAL;
|
||||
<pp_define>[^'"/\\\n]+ ppy_lval.cptr = xstrdup(ppy_text); return tLITERAL;
|
||||
<pp_define>(\\\r?)|(\/[^/*]) ppy_lval.cptr = xstrdup(ppy_text); return tLITERAL;
|
||||
<pp_define>\\\r?\n{ws}+ newline(0); ppy_lval.cptr = xstrdup(" "); return tLITERAL;
|
||||
<pp_define>\\\r?\n newline(0);
|
||||
<pp_define>\n newline(1); yy_pop_state(); return tNL;
|
||||
<pp_define>\' new_string(); add_string(ppy_text, ppy_leng); yy_push_state(pp_sqs);
|
||||
@@ -516,22 +462,22 @@ void pp_writestring(const char *format, ...)
|
||||
*/
|
||||
<pp_macro>\){ws}* yy_pp_state(pp_mbody); return tMACROEND;
|
||||
<pp_macro>{ws}+ ;
|
||||
<pp_macro>{cident} ppy_lval.cptr = pp_xstrdup(ppy_text); return tIDENT;
|
||||
<pp_macro>{cident} ppy_lval.cptr = xstrdup(ppy_text); return tIDENT;
|
||||
<pp_macro>, return ',';
|
||||
<pp_macro>"..." return tELIPSIS;
|
||||
<pp_macro>"..." return tELLIPSIS;
|
||||
<pp_macro>(\\\r?)|(\n)|(.)|(\.\.?) ppy_error("Argument identifier expected");
|
||||
<pp_macro>\\\r?\n newline(0);
|
||||
|
||||
/*
|
||||
* Scan the substitution of a macro
|
||||
*/
|
||||
<pp_mbody>[^a-zA-Z0-9'"#/\\\n]+ ppy_lval.cptr = pp_xstrdup(ppy_text); return tLITERAL;
|
||||
<pp_mbody>{cident} ppy_lval.cptr = pp_xstrdup(ppy_text); return tIDENT;
|
||||
<pp_mbody>[^a-zA-Z0-9'"#/\\\n]+ ppy_lval.cptr = xstrdup(ppy_text); return tLITERAL;
|
||||
<pp_mbody>{cident} ppy_lval.cptr = xstrdup(ppy_text); return tIDENT;
|
||||
<pp_mbody>\#\# return tCONCAT;
|
||||
<pp_mbody>\# return tSTRINGIZE;
|
||||
<pp_mbody>[0-9][a-zA-Z0-9]*[^a-zA-Z0-9'"#/\\\n]* ppy_lval.cptr = pp_xstrdup(ppy_text); return tLITERAL;
|
||||
<pp_mbody>(\\\r?)|(\/[^/*'"#\\\n]*) ppy_lval.cptr = pp_xstrdup(ppy_text); return tLITERAL;
|
||||
<pp_mbody>\\\r?\n{ws}+ newline(0); ppy_lval.cptr = pp_xstrdup(" "); return tLITERAL;
|
||||
<pp_mbody>[0-9][a-zA-Z0-9]*[^a-zA-Z0-9'"#/\\\n]* ppy_lval.cptr = xstrdup(ppy_text); return tLITERAL;
|
||||
<pp_mbody>(\\\r?)|(\/[^/*'"#\\\n]*) ppy_lval.cptr = xstrdup(ppy_text); return tLITERAL;
|
||||
<pp_mbody>\\\r?\n{ws}+ newline(0); ppy_lval.cptr = xstrdup(" "); return tLITERAL;
|
||||
<pp_mbody>\\\r?\n newline(0);
|
||||
<pp_mbody>\n newline(1); yy_pop_state(); return tNL;
|
||||
<pp_mbody>\' new_string(); add_string(ppy_text, ppy_leng); yy_push_state(pp_sqs);
|
||||
@@ -698,7 +644,7 @@ void pp_writestring(const char *format, ...)
|
||||
|
||||
else if(yy_current_state() == pp_if)
|
||||
{
|
||||
ppy_lval.cptr = pp_xstrdup(ppy_text);
|
||||
ppy_lval.cptr = xstrdup(ppy_text);
|
||||
return tIDENT;
|
||||
}
|
||||
else {
|
||||
@@ -724,7 +670,7 @@ void pp_writestring(const char *format, ...)
|
||||
push_macro(ppp);
|
||||
break;
|
||||
default:
|
||||
pp_internal_error(__FILE__, __LINE__, "Invalid define type %d\n", ppp->type);
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
else put_buffer(ppy_text, ppy_leng);
|
||||
@@ -747,8 +693,8 @@ void pp_writestring(const char *format, ...)
|
||||
<pp_macexp>(\n)|(.)|(\\\r?(\n|.)) put_buffer(ppy_text, ppy_leng);
|
||||
|
||||
<RCINCL>[A-Za-z0-9_\.\\/]+ {
|
||||
ppy_lval.cptr=pp_xstrdup(ppy_text);
|
||||
yy_pop_state();
|
||||
ppy_lval.cptr = xstrdup(ppy_text);
|
||||
yy_pop_state();
|
||||
return tRCINCLUDEPATH;
|
||||
}
|
||||
|
||||
@@ -847,14 +793,10 @@ static void newline(int dowrite)
|
||||
*
|
||||
* FIXME:
|
||||
* The sizes of resulting 'int' and 'long' are compiler specific.
|
||||
* I depend on sizeof(int) > 2 here (although a relatively safe
|
||||
* assumption).
|
||||
* Long longs are not yet implemented because this is very compiler
|
||||
* specific and I don't want to think too much about the problems.
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static int make_number(int radix, YYSTYPE *val, const char *str, int len)
|
||||
static int make_number(int radix, PPY_STYPE *val, const char *str, int len)
|
||||
{
|
||||
int is_l = 0;
|
||||
int is_ll = 0;
|
||||
@@ -895,29 +837,21 @@ static int make_number(int radix, YYSTYPE *val, const char *str, int len)
|
||||
is_u++;
|
||||
}
|
||||
|
||||
if(is_ll)
|
||||
if(is_u && is_ll)
|
||||
{
|
||||
/* Assume as in the declaration of wrc_ull_t and wrc_sll_t */
|
||||
#ifdef HAVE_LONG_LONG
|
||||
if (is_u)
|
||||
{
|
||||
errno = 0;
|
||||
val->ull = strtoull(str, NULL, radix);
|
||||
if (val->ull == ULLONG_MAX && errno == ERANGE)
|
||||
ppy_error("integer constant %s is too large\n", str);
|
||||
return tULONGLONG;
|
||||
}
|
||||
else
|
||||
{
|
||||
errno = 0;
|
||||
val->sll = strtoll(str, NULL, radix);
|
||||
if ((val->sll == LLONG_MIN || val->sll == LLONG_MAX) && errno == ERANGE)
|
||||
ppy_error("integer constant %s is too large\n", str);
|
||||
return tSLONGLONG;
|
||||
}
|
||||
#else
|
||||
pp_internal_error(__FILE__, __LINE__, "long long constants not supported on this platform");
|
||||
#endif
|
||||
errno = 0;
|
||||
val->ull = strtoull(str, NULL, radix);
|
||||
if (val->ull == ULLONG_MAX && errno == ERANGE)
|
||||
ppy_error("integer constant %s is too large\n", str);
|
||||
return tULONGLONG;
|
||||
}
|
||||
else if(!is_u && is_ll)
|
||||
{
|
||||
errno = 0;
|
||||
val->sll = strtoll(str, NULL, radix);
|
||||
if ((val->sll == LLONG_MIN || val->sll == LLONG_MAX) && errno == ERANGE)
|
||||
ppy_error("integer constant %s is too large\n", str);
|
||||
return tSLONGLONG;
|
||||
}
|
||||
else if(is_u && is_l)
|
||||
{
|
||||
@@ -967,28 +901,19 @@ static int make_number(int radix, YYSTYPE *val, const char *str, int len)
|
||||
static void expand_special(pp_entry_t *ppp)
|
||||
{
|
||||
static char *buf = NULL;
|
||||
char *new_buf;
|
||||
|
||||
assert(ppp->type == def_special);
|
||||
|
||||
if(!strcmp(ppp->ident, "__LINE__"))
|
||||
{
|
||||
new_buf = pp_xrealloc(buf, 32);
|
||||
if(!new_buf)
|
||||
return;
|
||||
buf = new_buf;
|
||||
sprintf(buf, "%d", pp_status.line_number);
|
||||
buf = xrealloc(buf, 32);
|
||||
snprintf(buf, 32, "%d", pp_status.line_number);
|
||||
}
|
||||
else if(!strcmp(ppp->ident, "__FILE__"))
|
||||
{
|
||||
new_buf = pp_xrealloc(buf, strlen(pp_status.input) + 3);
|
||||
if(!new_buf)
|
||||
return;
|
||||
buf = new_buf;
|
||||
sprintf(buf, "\"%s\"", pp_status.input);
|
||||
buf = xrealloc(buf, strlen(pp_status.input) + 3);
|
||||
snprintf(buf, strlen(pp_status.input) + 3, "\"%s\"", pp_status.input);
|
||||
}
|
||||
else
|
||||
pp_internal_error(__FILE__, __LINE__, "Special macro '%s' not found...\n", ppp->ident);
|
||||
|
||||
if(pp_flex_debug)
|
||||
fprintf(stderr, "expand_special(%d): %s:%d: '%s' -> '%s'\n",
|
||||
@@ -1029,21 +954,12 @@ static char *curdef_text = NULL;
|
||||
|
||||
static void add_text(const char *str, int len)
|
||||
{
|
||||
int new_alloc;
|
||||
char *new_text;
|
||||
|
||||
if(len == 0)
|
||||
return;
|
||||
if(curdef_idx >= curdef_alloc || curdef_alloc - curdef_idx < len)
|
||||
{
|
||||
new_alloc = curdef_alloc + ((len + ALLOCBLOCKSIZE-1) & ~(ALLOCBLOCKSIZE-1));
|
||||
new_text = pp_xrealloc(curdef_text, new_alloc * sizeof(curdef_text[0]));
|
||||
if(!new_text)
|
||||
return;
|
||||
curdef_text = new_text;
|
||||
curdef_alloc = new_alloc;
|
||||
if(curdef_alloc > 65536)
|
||||
ppy_warning("Reallocating macro-expansion buffer larger than 64kB");
|
||||
curdef_alloc += (len + ALLOCBLOCKSIZE-1) & ~(ALLOCBLOCKSIZE-1);
|
||||
curdef_text = xrealloc(curdef_text, curdef_alloc * sizeof(curdef_text[0]));
|
||||
}
|
||||
memcpy(&curdef_text[curdef_idx], str, len);
|
||||
curdef_idx += len;
|
||||
@@ -1139,9 +1055,6 @@ static mtext_t *add_expand_text(mtext_t *mtp, macexpstackentry_t *mep, int *nnl)
|
||||
if(pp_flex_debug)
|
||||
fprintf(stderr, "add_expand_text: exp_subst(%d): '%s'\n", mtp->subst.argidx, exp);
|
||||
break;
|
||||
|
||||
default:
|
||||
pp_internal_error(__FILE__, __LINE__, "Invalid expansion type (%d) in macro expansion\n", mtp->type);
|
||||
}
|
||||
return mtp;
|
||||
}
|
||||
@@ -1158,9 +1071,9 @@ static void expand_macro(macexpstackentry_t *mep)
|
||||
assert(ppp->type == def_macro);
|
||||
assert(ppp->expanding == 0);
|
||||
|
||||
if((ppp->nargs >= 0 && nargs != ppp->nargs) || (ppp->nargs < 0 && nargs < -ppp->nargs))
|
||||
if((!ppp->variadic && nargs != ppp->nargs) || (ppp->variadic && nargs < ppp->nargs))
|
||||
{
|
||||
ppy_error("Too %s macro arguments (%d)", nargs < abs(ppp->nargs) ? "few" : "many", nargs);
|
||||
ppy_error("Too %s macro arguments (%d)", nargs < ppp->nargs ? "few" : "many", nargs);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1229,31 +1142,18 @@ static void expand_macro(macexpstackentry_t *mep)
|
||||
*/
|
||||
static void new_string(void)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if(strbuf_idx)
|
||||
ppy_warning("new_string: strbuf_idx != 0");
|
||||
#endif
|
||||
strbuf_idx = 0;
|
||||
str_startline = pp_status.line_number;
|
||||
}
|
||||
|
||||
static void add_string(const char *str, int len)
|
||||
{
|
||||
int new_alloc;
|
||||
char *new_buffer;
|
||||
|
||||
if(len == 0)
|
||||
return;
|
||||
if(strbuf_idx >= strbuf_alloc || strbuf_alloc - strbuf_idx < len)
|
||||
{
|
||||
new_alloc = strbuf_alloc + ((len + ALLOCBLOCKSIZE-1) & ~(ALLOCBLOCKSIZE-1));
|
||||
new_buffer = pp_xrealloc(strbuffer, new_alloc * sizeof(strbuffer[0]));
|
||||
if(!new_buffer)
|
||||
return;
|
||||
strbuffer = new_buffer;
|
||||
strbuf_alloc = new_alloc;
|
||||
if(strbuf_alloc > 65536)
|
||||
ppy_warning("Reallocating string buffer larger than 64kB");
|
||||
strbuf_alloc += (len + ALLOCBLOCKSIZE-1) & ~(ALLOCBLOCKSIZE-1);
|
||||
strbuffer = xrealloc(strbuffer, strbuf_alloc * sizeof(strbuffer[0]));
|
||||
}
|
||||
memcpy(&strbuffer[strbuf_idx], str, len);
|
||||
strbuf_idx += len;
|
||||
@@ -1261,23 +1161,16 @@ static void add_string(const char *str, int len)
|
||||
|
||||
static char *get_string(void)
|
||||
{
|
||||
char *str = pp_xmalloc(strbuf_idx + 1);
|
||||
if(!str)
|
||||
return NULL;
|
||||
char *str = xmalloc(strbuf_idx + 1);
|
||||
|
||||
memcpy(str, strbuffer, strbuf_idx);
|
||||
str[strbuf_idx] = '\0';
|
||||
#ifdef DEBUG
|
||||
strbuf_idx = 0;
|
||||
#endif
|
||||
return str;
|
||||
}
|
||||
|
||||
static void put_string(void)
|
||||
{
|
||||
put_buffer(strbuffer, strbuf_idx);
|
||||
#ifdef DEBUG
|
||||
strbuf_idx = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int string_start(void)
|
||||
@@ -1296,11 +1189,11 @@ static void push_buffer(pp_entry_t *ppp, char *filename, char *incname, int pop)
|
||||
if(ppy_debug)
|
||||
printf("push_buffer(%d): %p %p %p %d\n", bufferstackidx, ppp, filename, incname, pop);
|
||||
if(bufferstackidx >= MAXBUFFERSTACK)
|
||||
pp_internal_error(__FILE__, __LINE__, "Buffer stack overflow");
|
||||
error("Buffer stack overflow\n");
|
||||
|
||||
memset(&bufferstack[bufferstackidx], 0, sizeof(bufferstack[0]));
|
||||
bufferstack[bufferstackidx].bufferstate = YY_CURRENT_BUFFER;
|
||||
bufferstack[bufferstackidx].filehandle = pp_status.file;
|
||||
bufferstack[bufferstackidx].file = pp_status.file;
|
||||
bufferstack[bufferstackidx].define = ppp;
|
||||
bufferstack[bufferstackidx].line_number = pp_status.line_number;
|
||||
bufferstack[bufferstackidx].char_number = pp_status.char_number;
|
||||
@@ -1321,16 +1214,11 @@ static void push_buffer(pp_entry_t *ppp, char *filename, char *incname, int pop)
|
||||
pp_status.input = filename;
|
||||
ncontinuations = 0;
|
||||
}
|
||||
else if(!pop)
|
||||
pp_internal_error(__FILE__, __LINE__, "Pushing buffer without knowing where to go to");
|
||||
bufferstackidx++;
|
||||
}
|
||||
|
||||
static bufferstackentry_t *pop_buffer(void)
|
||||
{
|
||||
if(bufferstackidx < 0)
|
||||
pp_internal_error(__FILE__, __LINE__, "Bufferstack underflow?");
|
||||
|
||||
if(bufferstackidx == 0)
|
||||
return NULL;
|
||||
|
||||
@@ -1344,8 +1232,8 @@ static bufferstackentry_t *pop_buffer(void)
|
||||
|
||||
if(!bufferstack[bufferstackidx].should_pop)
|
||||
{
|
||||
wpp_callbacks->close(pp_status.file);
|
||||
pp_writestring("# %d \"%s\" 2\n", bufferstack[bufferstackidx].line_number, bufferstack[bufferstackidx].filename);
|
||||
fclose(pp_status.file);
|
||||
fprintf(ppy_out, "# %d \"%s\" 2\n", bufferstack[bufferstackidx].line_number, bufferstack[bufferstackidx].filename);
|
||||
|
||||
/* We have EOF, check the include logic */
|
||||
if(pp_incl_state.state == 2 && !pp_incl_state.seen_junk && pp_incl_state.ppp)
|
||||
@@ -1353,21 +1241,14 @@ static bufferstackentry_t *pop_buffer(void)
|
||||
pp_entry_t *ppp = pplookup(pp_incl_state.ppp);
|
||||
if(ppp)
|
||||
{
|
||||
iep = pp_xmalloc(sizeof(includelogicentry_t));
|
||||
if (iep)
|
||||
{
|
||||
iep->ppp = ppp;
|
||||
ppp->iep = iep;
|
||||
iep->filename = bufferstack[bufferstackidx].include_filename;
|
||||
iep->prev = NULL;
|
||||
iep->next = pp_includelogiclist;
|
||||
if(iep->next)
|
||||
iep->next->prev = iep;
|
||||
pp_includelogiclist = iep;
|
||||
if(pp_status.debug)
|
||||
fprintf(stderr, "pop_buffer: %s:%d: includelogic added, include_ppp='%s', file='%s'\n",
|
||||
bufferstack[bufferstackidx].filename, bufferstack[bufferstackidx].line_number, pp_incl_state.ppp, iep->filename);
|
||||
}
|
||||
iep = xmalloc(sizeof(includelogicentry_t));
|
||||
iep->ppp = ppp;
|
||||
ppp->iep = iep;
|
||||
iep->filename = bufferstack[bufferstackidx].include_filename;
|
||||
list_add_head( &pp_includelogiclist, &iep->entry );
|
||||
if(pp_status.debug)
|
||||
fprintf(stderr, "pop_buffer: %s:%d: includelogic added, include_ppp='%s', file='%s'\n",
|
||||
bufferstack[bufferstackidx].filename, bufferstack[bufferstackidx].line_number, pp_incl_state.ppp, iep->filename);
|
||||
}
|
||||
}
|
||||
free(pp_incl_state.ppp);
|
||||
@@ -1397,15 +1278,13 @@ static bufferstackentry_t *pop_buffer(void)
|
||||
bufferstack[bufferstackidx].filename,
|
||||
bufferstack[bufferstackidx].should_pop);
|
||||
|
||||
pp_status.file = bufferstack[bufferstackidx].filehandle;
|
||||
pp_status.file = bufferstack[bufferstackidx].file;
|
||||
ppy__switch_to_buffer(bufferstack[bufferstackidx].bufferstate);
|
||||
|
||||
if(bufferstack[bufferstackidx].should_pop)
|
||||
{
|
||||
if(yy_current_state() == pp_macexp)
|
||||
macro_add_expansion();
|
||||
else
|
||||
pp_internal_error(__FILE__, __LINE__, "Pop buffer and state without macro expansion state");
|
||||
assert( yy_current_state() == pp_macexp );
|
||||
macro_add_expansion();
|
||||
yy_pop_state();
|
||||
}
|
||||
|
||||
@@ -1426,9 +1305,7 @@ static void push_macro(pp_entry_t *ppp)
|
||||
return;
|
||||
}
|
||||
|
||||
macexpstack[macexpstackidx] = pp_xmalloc(sizeof(macexpstack[0][0]));
|
||||
if(!macexpstack[macexpstackidx])
|
||||
return;
|
||||
macexpstack[macexpstackidx] = xmalloc(sizeof(macexpstack[0][0]));
|
||||
memset( macexpstack[macexpstackidx], 0, sizeof(macexpstack[0][0]));
|
||||
macexpstack[macexpstackidx]->ppp = ppp;
|
||||
macexpstackidx++;
|
||||
@@ -1441,8 +1318,7 @@ static macexpstackentry_t *top_macro(void)
|
||||
|
||||
static macexpstackentry_t *pop_macro(void)
|
||||
{
|
||||
if(macexpstackidx <= 0)
|
||||
pp_internal_error(__FILE__, __LINE__, "Macro expansion stack underflow\n");
|
||||
assert(macexpstackidx > 0);
|
||||
return macexpstack[--macexpstackidx];
|
||||
}
|
||||
|
||||
@@ -1466,13 +1342,8 @@ static void add_text_to_macro(const char *text, int len)
|
||||
|
||||
if(mep->curargalloc - mep->curargsize <= len+1) /* +1 for '\0' */
|
||||
{
|
||||
char *new_curarg;
|
||||
int new_alloc = mep->curargalloc + ((ALLOCBLOCKSIZE > len+1) ? ALLOCBLOCKSIZE : len+1);
|
||||
new_curarg = pp_xrealloc(mep->curarg, new_alloc * sizeof(mep->curarg[0]));
|
||||
if(!new_curarg)
|
||||
return;
|
||||
mep->curarg = new_curarg;
|
||||
mep->curargalloc = new_alloc;
|
||||
mep->curargalloc += (ALLOCBLOCKSIZE > len+1) ? ALLOCBLOCKSIZE : len+1;
|
||||
mep->curarg = xrealloc(mep->curarg, mep->curargalloc * sizeof(mep->curarg[0]));
|
||||
}
|
||||
memcpy(mep->curarg + mep->curargsize, text, len);
|
||||
mep->curargsize += len;
|
||||
@@ -1483,30 +1354,15 @@ static void macro_add_arg(int last)
|
||||
{
|
||||
int nnl = 0;
|
||||
char *cptr;
|
||||
char **new_args, **new_ppargs;
|
||||
int *new_nnls;
|
||||
macexpstackentry_t *mep = top_macro();
|
||||
|
||||
assert(mep->ppp->expanding == 0);
|
||||
|
||||
new_args = pp_xrealloc(mep->args, (mep->nargs+1) * sizeof(mep->args[0]));
|
||||
if(!new_args)
|
||||
return;
|
||||
mep->args = new_args;
|
||||
mep->args = xrealloc(mep->args, (mep->nargs+1) * sizeof(mep->args[0]));
|
||||
mep->ppargs = xrealloc(mep->ppargs, (mep->nargs+1) * sizeof(mep->ppargs[0]));
|
||||
mep->nnls = xrealloc(mep->nnls, (mep->nargs+1) * sizeof(mep->nnls[0]));
|
||||
|
||||
new_ppargs = pp_xrealloc(mep->ppargs, (mep->nargs+1) * sizeof(mep->ppargs[0]));
|
||||
if(!new_ppargs)
|
||||
return;
|
||||
mep->ppargs = new_ppargs;
|
||||
|
||||
new_nnls = pp_xrealloc(mep->nnls, (mep->nargs+1) * sizeof(mep->nnls[0]));
|
||||
if(!new_nnls)
|
||||
return;
|
||||
mep->nnls = new_nnls;
|
||||
|
||||
mep->args[mep->nargs] = pp_xstrdup(mep->curarg ? mep->curarg : "");
|
||||
if(!mep->args[mep->nargs])
|
||||
return;
|
||||
mep->args[mep->nargs] = xstrdup(mep->curarg ? mep->curarg : "");
|
||||
cptr = mep->args[mep->nargs]-1;
|
||||
while((cptr = strchr(cptr+1, '\n')))
|
||||
{
|
||||
@@ -1541,7 +1397,7 @@ static void macro_add_expansion(void)
|
||||
|
||||
assert(mep->ppp->expanding == 0);
|
||||
|
||||
mep->ppargs[mep->nargs-1] = pp_xstrdup(mep->curarg ? mep->curarg : "");
|
||||
mep->ppargs[mep->nargs-1] = xstrdup(mep->curarg ? mep->curarg : "");
|
||||
free(mep->curarg);
|
||||
mep->curargalloc = mep->curargsize = 0;
|
||||
mep->curarg = NULL;
|
||||
@@ -1565,7 +1421,7 @@ static void put_buffer(const char *s, int len)
|
||||
if(top_macro())
|
||||
add_text_to_macro(s, len);
|
||||
else
|
||||
wpp_callbacks->write(s, len);
|
||||
fwrite(s, 1, len, ppy_out);
|
||||
}
|
||||
|
||||
|
||||
@@ -1584,7 +1440,7 @@ void pp_do_include(char *fname, int type)
|
||||
if(!fname)
|
||||
return;
|
||||
|
||||
for(iep = pp_includelogiclist; iep; iep = iep->next)
|
||||
LIST_FOR_EACH_ENTRY( iep, &pp_includelogiclist, includelogicentry_t, entry )
|
||||
{
|
||||
if(!strcmp(iep->filename, fname))
|
||||
{
|
||||
@@ -1624,12 +1480,12 @@ void pp_do_include(char *fname, int type)
|
||||
pp_incl_state.ppp = NULL;
|
||||
|
||||
if(pp_status.debug)
|
||||
fprintf(stderr, "pp_do_include: %s:%d: include_state=%d, include_ppp='%s', include_ifdepth=%d\n",
|
||||
pp_status.input, pp_status.line_number, pp_incl_state.state, pp_incl_state.ppp, pp_incl_state.ifdepth);
|
||||
fprintf(stderr, "pp_do_include: %s:%d: include_state=%d, include_ifdepth=%d\n",
|
||||
pp_status.input, pp_status.line_number, pp_incl_state.state, pp_incl_state.ifdepth);
|
||||
pp_status.file = fp;
|
||||
ppy__switch_to_buffer(ppy__create_buffer(NULL, YY_BUF_SIZE));
|
||||
|
||||
pp_writestring("# 1 \"%s\" 1%s\n", newpath, type ? "" : " 3");
|
||||
fprintf(ppy_out, "# 1 \"%s\" 1%s\n", newpath, type ? "" : " 3");
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+47
-104
@@ -3,7 +3,6 @@
|
||||
*
|
||||
* Copyright 1999-2000 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
|
||||
@@ -18,18 +17,10 @@
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
* History:
|
||||
* 24-Apr-2000 BS Restructured the lot to fit the new scanner
|
||||
* and reintegrate into the wine-tree.
|
||||
* 01-Jan-2000 BS FIXME: win16 preprocessor calculates with
|
||||
* 16 bit ints and overflows...?
|
||||
* 26-Dec-1999 BS Started this file
|
||||
*
|
||||
*/
|
||||
|
||||
%{
|
||||
#include "config.h"
|
||||
#include "wine/port.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -38,6 +29,8 @@
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../tools.h"
|
||||
#include "utils.h"
|
||||
#include "wpp_private.h"
|
||||
|
||||
|
||||
@@ -81,9 +74,9 @@
|
||||
if(cv_signed(v1) && cv_signed(v2)) \
|
||||
r.val.sll = v1.val.sll OP v2.val.sll; \
|
||||
else if(cv_signed(v1) && !cv_signed(v2)) \
|
||||
r.val.sll = v1.val.sll OP (wrc_sll_t) v2.val.ull; \
|
||||
r.val.sll = v1.val.sll OP (__int64) v2.val.ull; \
|
||||
else if(!cv_signed(v1) && cv_signed(v2)) \
|
||||
r.val.sll = (wrc_sll_t) v1.val.ull OP v2.val.sll; \
|
||||
r.val.sll = (__int64) v1.val.ull OP v2.val.sll; \
|
||||
else \
|
||||
r.val.ull = v1.val.ull OP v2.val.ull;
|
||||
|
||||
@@ -93,7 +86,7 @@
|
||||
case SIZE_INT: BIN_OP_INT(r, v1, v2, OP); break; \
|
||||
case SIZE_LONG: BIN_OP_LONG(r, v1, v2, OP); break; \
|
||||
case SIZE_LONGLONG: BIN_OP_LONGLONG(r, v1, v2, OP); break; \
|
||||
default: pp_internal_error(__FILE__, __LINE__, "Invalid type indicator (0x%04x)", v1.type); \
|
||||
default: assert(0); \
|
||||
}
|
||||
|
||||
|
||||
@@ -108,8 +101,7 @@ static void cast_to_slong(cval_t *v);
|
||||
static void cast_to_ulong(cval_t *v);
|
||||
static void cast_to_sll(cval_t *v);
|
||||
static void cast_to_ull(cval_t *v);
|
||||
static marg_t *new_marg(char *str, def_arg_t type);
|
||||
static marg_t *add_new_marg(char *str, def_arg_t type);
|
||||
static char *add_new_marg(char *str);
|
||||
static int marg_index(char *id);
|
||||
static mtext_t *new_mtext(char *str, int idx, def_exp_t type);
|
||||
static mtext_t *combine_mtext(mtext_t *tail, mtext_t *mtp);
|
||||
@@ -118,29 +110,32 @@ static char *merge_text(char *s1, char *s2);
|
||||
/*
|
||||
* Local variables
|
||||
*/
|
||||
static marg_t **macro_args; /* Macro parameters array while parsing */
|
||||
static char **macro_args; /* Macro parameters array while parsing */
|
||||
static int nmacro_args;
|
||||
static int macro_variadic; /* Macro arguments end with (or consist entirely of) '...' */
|
||||
|
||||
%}
|
||||
|
||||
%define api.prefix {ppy_}
|
||||
|
||||
%union{
|
||||
int sint;
|
||||
unsigned int uint;
|
||||
long slong;
|
||||
unsigned long ulong;
|
||||
wrc_sll_t sll;
|
||||
wrc_ull_t ull;
|
||||
__int64 sll;
|
||||
unsigned __int64 ull;
|
||||
int *iptr;
|
||||
char *cptr;
|
||||
cval_t cval;
|
||||
marg_t *marg;
|
||||
char *marg;
|
||||
mtext_t *mtext;
|
||||
}
|
||||
|
||||
%token tRCINCLUDE
|
||||
%token tIF tIFDEF tIFNDEF tELSE tELIF tENDIF tDEFINED tNL
|
||||
%token tINCLUDE tLINE tGCCLINE tERROR tWARNING tPRAGMA tPPIDENT
|
||||
%token tUNDEF tMACROEND tCONCAT tELIPSIS tSTRINGIZE
|
||||
%token tUNDEF tMACROEND tCONCAT tELLIPSIS tSTRINGIZE
|
||||
%token <cptr> tIDENT tLITERAL tMACRO tDEFINE
|
||||
%token <cptr> tDQSTRING tSQSTRING tIQSTRING
|
||||
%token <uint> tUINT
|
||||
@@ -227,8 +222,6 @@ preprocessor
|
||||
break;
|
||||
case if_error:
|
||||
break;
|
||||
default:
|
||||
pp_internal_error(__FILE__, __LINE__, "Invalid pp_if_state (%d) in #elif directive", s);
|
||||
}
|
||||
}
|
||||
| tELSE tNL {
|
||||
@@ -253,8 +246,6 @@ preprocessor
|
||||
break;
|
||||
case if_error:
|
||||
break;
|
||||
default:
|
||||
pp_internal_error(__FILE__, __LINE__, "Invalid pp_if_state (%d) in #else directive", s);
|
||||
}
|
||||
}
|
||||
| tENDIF tNL {
|
||||
@@ -277,35 +268,25 @@ preprocessor
|
||||
| tUNDEF tIDENT tNL { pp_del_define($2); free($2); }
|
||||
| tDEFINE opt_text tNL { pp_add_define($1, $2); free($1); free($2); }
|
||||
| tMACRO res_arg allmargs tMACROEND opt_mtexts tNL {
|
||||
pp_add_macro($1, macro_args, nmacro_args, $5);
|
||||
pp_add_macro($1, macro_args, nmacro_args, macro_variadic, $5);
|
||||
}
|
||||
| tLINE tSINT tDQSTRING tNL { if($3) pp_writestring("# %d %s\n", $2 , $3); free($3); }
|
||||
| tGCCLINE tSINT tDQSTRING tNL { if($3) pp_writestring("# %d %s\n", $2 , $3); free($3); }
|
||||
| tLINE tSINT tDQSTRING tNL { if($3) fprintf(ppy_out, "# %d %s\n", $2 , $3); free($3); }
|
||||
| tGCCLINE tSINT tDQSTRING tNL { if($3) fprintf(ppy_out, "# %d %s\n", $2 , $3); free($3); }
|
||||
| tGCCLINE tSINT tDQSTRING tSINT tNL
|
||||
{ if($3) pp_writestring("# %d %s %d\n", $2, $3, $4); free($3); }
|
||||
{ if($3) fprintf(ppy_out, "# %d %s %d\n", $2, $3, $4); free($3); }
|
||||
| tGCCLINE tSINT tDQSTRING tSINT tSINT tNL
|
||||
{ if($3) pp_writestring("# %d %s %d %d\n", $2 ,$3, $4, $5); free($3); }
|
||||
{ if($3) fprintf(ppy_out, "# %d %s %d %d\n", $2 ,$3, $4, $5); free($3); }
|
||||
| tGCCLINE tSINT tDQSTRING tSINT tSINT tSINT tNL
|
||||
{ if($3) pp_writestring("# %d %s %d %d %d\n", $2 ,$3 ,$4 ,$5, $6); free($3); }
|
||||
{ if($3) fprintf(ppy_out, "# %d %s %d %d %d\n", $2 ,$3 ,$4 ,$5, $6); free($3); }
|
||||
| tGCCLINE tSINT tDQSTRING tSINT tSINT tSINT tSINT tNL
|
||||
{ if($3) pp_writestring("# %d %s %d %d %d %d\n", $2 ,$3 ,$4 ,$5, $6, $7); free($3); }
|
||||
{ if($3) fprintf(ppy_out, "# %d %s %d %d %d %d\n", $2 ,$3 ,$4 ,$5, $6, $7); free($3); }
|
||||
| tGCCLINE tNL /* The null-token */
|
||||
| tERROR opt_text tNL { ppy_error("#error directive: '%s'", $2); free($2); }
|
||||
| tWARNING opt_text tNL { ppy_warning("#warning directive: '%s'", $2); free($2); }
|
||||
| tPRAGMA opt_text tNL { pp_writestring("#pragma %s\n", $2 ? $2 : ""); free($2); }
|
||||
| tPPIDENT opt_text tNL { if(pp_status.pedantic) ppy_warning("#ident ignored (arg: '%s')", $2); free($2); }
|
||||
| tPRAGMA opt_text tNL { fprintf(ppy_out, "#pragma %s\n", $2 ? $2 : ""); free($2); }
|
||||
| tPPIDENT opt_text tNL { if(pedantic) ppy_warning("#ident ignored (arg: '%s')", $2); free($2); }
|
||||
| tRCINCLUDE tRCINCLUDEPATH {
|
||||
if($2)
|
||||
{
|
||||
int nl=strlen($2) +3;
|
||||
char *fn=pp_xmalloc(nl);
|
||||
if(fn)
|
||||
{
|
||||
sprintf(fn,"\"%s\"",$2);
|
||||
pp_do_include(fn,1);
|
||||
}
|
||||
free($2);
|
||||
}
|
||||
pp_do_include(strmake( "\"%s\"", $2 ),1);
|
||||
}
|
||||
| tRCINCLUDE tDQSTRING {
|
||||
pp_do_include($2,1);
|
||||
@@ -325,19 +306,20 @@ text : tLITERAL { $$ = $1; }
|
||||
| text tSQSTRING { $$ = merge_text($1, $2); }
|
||||
;
|
||||
|
||||
res_arg : /* Empty */ { macro_args = NULL; nmacro_args = 0; }
|
||||
res_arg : /* Empty */ { macro_args = NULL; nmacro_args = 0; macro_variadic = 0; }
|
||||
;
|
||||
|
||||
allmargs: /* Empty */ { $$ = 0; macro_args = NULL; nmacro_args = 0; }
|
||||
allmargs: /* Empty */ { $$ = 0; macro_args = NULL; nmacro_args = 0; macro_variadic = 0; }
|
||||
| emargs { $$ = nmacro_args; }
|
||||
;
|
||||
|
||||
emargs : margs { $$ = $1; }
|
||||
| margs ',' tELIPSIS { $$ = add_new_marg(NULL, arg_list); nmacro_args *= -1; }
|
||||
| margs ',' tELLIPSIS { macro_variadic = 1; }
|
||||
| tELLIPSIS { macro_args = NULL; nmacro_args = 0; macro_variadic = 1; }
|
||||
;
|
||||
|
||||
margs : margs ',' tIDENT { $$ = add_new_marg($3, arg_single); }
|
||||
| tIDENT { $$ = add_new_marg($1, arg_single); }
|
||||
margs : margs ',' tIDENT { $$ = add_new_marg($3); }
|
||||
| tIDENT { $$ = add_new_marg($1); }
|
||||
;
|
||||
|
||||
opt_mtexts
|
||||
@@ -539,42 +521,21 @@ static int boolean(cval_t *v)
|
||||
{
|
||||
switch(v->type)
|
||||
{
|
||||
case cv_sint: return v->val.si != (int)0;
|
||||
case cv_uint: return v->val.ui != (unsigned int)0;
|
||||
case cv_slong: return v->val.sl != (long)0;
|
||||
case cv_ulong: return v->val.ul != (unsigned long)0;
|
||||
case cv_sll: return v->val.sll != (wrc_sll_t)0;
|
||||
case cv_ull: return v->val.ull != (wrc_ull_t)0;
|
||||
case cv_sint: return v->val.si != 0;
|
||||
case cv_uint: return v->val.ui != 0;
|
||||
case cv_slong: return v->val.sl != 0;
|
||||
case cv_ulong: return v->val.ul != 0;
|
||||
case cv_sll: return v->val.sll != 0;
|
||||
case cv_ull: return v->val.ull != 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static marg_t *new_marg(char *str, def_arg_t type)
|
||||
static char *add_new_marg(char *str)
|
||||
{
|
||||
marg_t *ma = pp_xmalloc(sizeof(marg_t));
|
||||
if(!ma)
|
||||
return NULL;
|
||||
ma->arg = str;
|
||||
ma->type = type;
|
||||
ma->nnl = 0;
|
||||
return ma;
|
||||
}
|
||||
|
||||
static marg_t *add_new_marg(char *str, def_arg_t type)
|
||||
{
|
||||
marg_t **new_macro_args;
|
||||
marg_t *ma;
|
||||
if(!str)
|
||||
return NULL;
|
||||
new_macro_args = pp_xrealloc(macro_args, (nmacro_args+1) * sizeof(macro_args[0]));
|
||||
if(!new_macro_args)
|
||||
return NULL;
|
||||
macro_args = new_macro_args;
|
||||
ma = new_marg(str, type);
|
||||
if(!ma)
|
||||
return NULL;
|
||||
macro_args[nmacro_args] = ma;
|
||||
nmacro_args++;
|
||||
char *ma;
|
||||
macro_args = xrealloc(macro_args, (nmacro_args+1) * sizeof(macro_args[0]));
|
||||
macro_args[nmacro_args++] = ma = xstrdup(str);
|
||||
return ma;
|
||||
}
|
||||
|
||||
@@ -585,7 +546,7 @@ static int marg_index(char *id)
|
||||
return -1;
|
||||
for(t = 0; t < nmacro_args; t++)
|
||||
{
|
||||
if(!strcmp(id, macro_args[t]->arg))
|
||||
if(!strcmp(id, macro_args[t]))
|
||||
break;
|
||||
}
|
||||
return t < nmacro_args ? t : -1;
|
||||
@@ -593,9 +554,8 @@ static int marg_index(char *id)
|
||||
|
||||
static mtext_t *new_mtext(char *str, int idx, def_exp_t type)
|
||||
{
|
||||
mtext_t *mt = pp_xmalloc(sizeof(mtext_t));
|
||||
if(!mt)
|
||||
return NULL;
|
||||
mtext_t *mt = xmalloc(sizeof(mtext_t));
|
||||
|
||||
if(str == NULL)
|
||||
mt->subst.argidx = idx;
|
||||
else
|
||||
@@ -615,11 +575,7 @@ static mtext_t *combine_mtext(mtext_t *tail, mtext_t *mtp)
|
||||
|
||||
if(tail->type == exp_text && mtp->type == exp_text)
|
||||
{
|
||||
char *new_text;
|
||||
new_text = pp_xrealloc(tail->subst.text, strlen(tail->subst.text)+strlen(mtp->subst.text)+1);
|
||||
if(!new_text)
|
||||
return mtp;
|
||||
tail->subst.text = new_text;
|
||||
tail->subst.text = xrealloc(tail->subst.text, strlen(tail->subst.text)+strlen(mtp->subst.text)+1);
|
||||
strcat(tail->subst.text, mtp->subst.text);
|
||||
free(mtp->subst.text);
|
||||
free(mtp);
|
||||
@@ -683,22 +639,9 @@ static mtext_t *combine_mtext(mtext_t *tail, mtext_t *mtp)
|
||||
|
||||
static char *merge_text(char *s1, char *s2)
|
||||
{
|
||||
int l1;
|
||||
int l2;
|
||||
char *snew;
|
||||
if(!s1)
|
||||
return s2;
|
||||
if(!s2)
|
||||
return s1;
|
||||
l1 = strlen(s1);
|
||||
l2 = strlen(s2);
|
||||
snew = pp_xrealloc(s1, l1+l2+1);
|
||||
if(!snew)
|
||||
{
|
||||
free(s2);
|
||||
return s1;
|
||||
}
|
||||
s1 = snew;
|
||||
int l1 = strlen(s1);
|
||||
int l2 = strlen(s2);
|
||||
s1 = xrealloc(s1, l1+l2+1);
|
||||
memcpy(s1+l1, s2, l2+1);
|
||||
free(s2);
|
||||
return s1;
|
||||
|
||||
@@ -1,763 +0,0 @@
|
||||
/*
|
||||
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "wine/port.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_IO_H
|
||||
# include <io.h>
|
||||
#endif
|
||||
|
||||
#include "wine/wpp.h"
|
||||
#include "wpp_private.h"
|
||||
|
||||
struct pp_status pp_status;
|
||||
|
||||
#define HASHKEY 2039
|
||||
|
||||
typedef struct pp_def_state
|
||||
{
|
||||
struct pp_def_state *next;
|
||||
pp_entry_t *defines[HASHKEY];
|
||||
} pp_def_state_t;
|
||||
|
||||
static pp_def_state_t *pp_def_state;
|
||||
|
||||
#define MAXIFSTACK 64
|
||||
static pp_if_state_t if_stack[MAXIFSTACK];
|
||||
static int if_stack_idx = 0;
|
||||
|
||||
#if 0
|
||||
void pp_print_status(void) __attribute__((destructor));
|
||||
void pp_print_status(void)
|
||||
{
|
||||
int i;
|
||||
int sum;
|
||||
int total = 0;
|
||||
pp_entry_t *ppp;
|
||||
|
||||
fprintf(stderr, "Defines statistics:\n");
|
||||
for(i = 0; i < HASHKEY; i++)
|
||||
{
|
||||
sum = 0;
|
||||
for(ppp = pp_def_state->defines[i]; ppp; ppp = ppp->next)
|
||||
sum++;
|
||||
total += sum;
|
||||
if (sum) fprintf(stderr, "%4d, %3d\n", i, sum);
|
||||
}
|
||||
fprintf(stderr, "Total defines: %d\n", total);
|
||||
}
|
||||
#endif
|
||||
|
||||
void *pp_xmalloc(size_t size)
|
||||
{
|
||||
void *res;
|
||||
|
||||
assert(size > 0);
|
||||
res = malloc(size);
|
||||
if(res == NULL)
|
||||
{
|
||||
/* Set the error flag */
|
||||
pp_status.state = 1;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void *pp_xrealloc(void *p, size_t size)
|
||||
{
|
||||
void *res;
|
||||
|
||||
assert(size > 0);
|
||||
res = realloc(p, size);
|
||||
if(res == NULL)
|
||||
{
|
||||
/* Set the error flag */
|
||||
pp_status.state = 1;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
char *pp_xstrdup(const char *str)
|
||||
{
|
||||
char *s;
|
||||
int len;
|
||||
|
||||
assert(str != NULL);
|
||||
len = strlen(str)+1;
|
||||
s = pp_xmalloc(len);
|
||||
if(!s)
|
||||
return NULL;
|
||||
return memcpy(s, str, len);
|
||||
}
|
||||
|
||||
static char *wpp_default_lookup(const char *name, int type, const char *parent_name,
|
||||
char **include_path, int include_path_count)
|
||||
{
|
||||
char *cpy;
|
||||
char *cptr;
|
||||
char *path;
|
||||
const char *ccptr;
|
||||
int i, fd;
|
||||
|
||||
cpy = pp_xmalloc(strlen(name)+1);
|
||||
if(!cpy)
|
||||
return NULL;
|
||||
cptr = cpy;
|
||||
|
||||
for(ccptr = name; *ccptr; ccptr++)
|
||||
{
|
||||
/* Convert to forward slash */
|
||||
if(*ccptr == '\\') {
|
||||
/* kill double backslash */
|
||||
if(ccptr[1] == '\\')
|
||||
ccptr++;
|
||||
*cptr = '/';
|
||||
}else {
|
||||
*cptr = *ccptr;
|
||||
}
|
||||
cptr++;
|
||||
}
|
||||
*cptr = '\0';
|
||||
|
||||
if(type && parent_name)
|
||||
{
|
||||
/* Search directory of parent include and then -I path */
|
||||
const char *p;
|
||||
|
||||
if ((p = strrchr( parent_name, '/' ))) p++;
|
||||
else p = parent_name;
|
||||
path = pp_xmalloc( (p - parent_name) + strlen(cpy) + 1 );
|
||||
if(!path)
|
||||
{
|
||||
free(cpy);
|
||||
return NULL;
|
||||
}
|
||||
memcpy( path, parent_name, p - parent_name );
|
||||
strcpy( path + (p - parent_name), cpy );
|
||||
fd = open( path, O_RDONLY );
|
||||
if (fd != -1)
|
||||
{
|
||||
close( fd );
|
||||
free( cpy );
|
||||
return path;
|
||||
}
|
||||
free( path );
|
||||
}
|
||||
/* Search -I path */
|
||||
for(i = 0; i < include_path_count; i++)
|
||||
{
|
||||
path = pp_xmalloc(strlen(include_path[i]) + strlen(cpy) + 2);
|
||||
if(!path)
|
||||
{
|
||||
free(cpy);
|
||||
return NULL;
|
||||
}
|
||||
strcpy(path, include_path[i]);
|
||||
strcat(path, "/");
|
||||
strcat(path, cpy);
|
||||
fd = open( path, O_RDONLY );
|
||||
if (fd != -1)
|
||||
{
|
||||
close( fd );
|
||||
free( cpy );
|
||||
return path;
|
||||
}
|
||||
free( path );
|
||||
}
|
||||
free( cpy );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *wpp_default_open(const char *filename, int type) {
|
||||
return fopen(filename,"rt");
|
||||
}
|
||||
|
||||
static void wpp_default_close(void *file) {
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
static int wpp_default_read(void *file, char *buffer, unsigned int len){
|
||||
return fread(buffer, 1, len, file);
|
||||
}
|
||||
|
||||
static void wpp_default_write( const char *buffer, unsigned int len ) {
|
||||
fwrite(buffer, 1, len, ppy_out);
|
||||
}
|
||||
|
||||
/* Don't comment on the hash, it's primitive but functional... */
|
||||
static int pphash(const char *str)
|
||||
{
|
||||
int sum = 0;
|
||||
while(*str)
|
||||
sum += *str++;
|
||||
return sum % HASHKEY;
|
||||
}
|
||||
|
||||
pp_entry_t *pplookup(const char *ident)
|
||||
{
|
||||
int idx;
|
||||
pp_entry_t *ppp;
|
||||
|
||||
if(!ident)
|
||||
return NULL;
|
||||
idx = pphash(ident);
|
||||
for(ppp = pp_def_state->defines[idx]; ppp; ppp = ppp->next)
|
||||
{
|
||||
if(!strcmp(ident, ppp->ident))
|
||||
return ppp;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void free_pp_entry( pp_entry_t *ppp, int idx )
|
||||
{
|
||||
if(ppp->iep)
|
||||
{
|
||||
if(ppp->iep == pp_includelogiclist)
|
||||
{
|
||||
pp_includelogiclist = ppp->iep->next;
|
||||
if(pp_includelogiclist)
|
||||
pp_includelogiclist->prev = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
ppp->iep->prev->next = ppp->iep->next;
|
||||
if(ppp->iep->next)
|
||||
ppp->iep->next->prev = ppp->iep->prev;
|
||||
}
|
||||
free(ppp->iep->filename);
|
||||
free(ppp->iep);
|
||||
}
|
||||
|
||||
if(pp_def_state->defines[idx] == ppp)
|
||||
{
|
||||
pp_def_state->defines[idx] = ppp->next;
|
||||
if(pp_def_state->defines[idx])
|
||||
pp_def_state->defines[idx]->prev = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
ppp->prev->next = ppp->next;
|
||||
if(ppp->next)
|
||||
ppp->next->prev = ppp->prev;
|
||||
}
|
||||
|
||||
free(ppp);
|
||||
}
|
||||
|
||||
/* push a new (empty) define state */
|
||||
int pp_push_define_state(void)
|
||||
{
|
||||
pp_def_state_t *state = pp_xmalloc( sizeof(*state) );
|
||||
if(!state)
|
||||
return 1;
|
||||
|
||||
memset( state->defines, 0, sizeof(state->defines) );
|
||||
state->next = pp_def_state;
|
||||
pp_def_state = state;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* pop the current define state */
|
||||
void pp_pop_define_state(void)
|
||||
{
|
||||
int i;
|
||||
pp_entry_t *ppp;
|
||||
pp_def_state_t *state;
|
||||
|
||||
for (i = 0; i < HASHKEY; i++)
|
||||
{
|
||||
while ((ppp = pp_def_state->defines[i]) != NULL) pp_del_define( ppp->ident );
|
||||
}
|
||||
state = pp_def_state;
|
||||
pp_def_state = state->next;
|
||||
free( state );
|
||||
}
|
||||
|
||||
void pp_del_define(const char *name)
|
||||
{
|
||||
pp_entry_t *ppp;
|
||||
int idx = pphash(name);
|
||||
|
||||
if((ppp = pplookup(name)) == NULL)
|
||||
{
|
||||
if(pp_status.pedantic)
|
||||
ppy_warning("%s was not defined", name);
|
||||
return;
|
||||
}
|
||||
|
||||
if(pp_status.debug)
|
||||
printf("Deleting (%s, %d) <%s>\n", pp_status.input, pp_status.line_number, name);
|
||||
|
||||
free( ppp->ident );
|
||||
free( ppp->subst.text );
|
||||
free( ppp->filename );
|
||||
free_pp_entry( ppp, idx );
|
||||
}
|
||||
|
||||
pp_entry_t *pp_add_define(const char *def, const char *text)
|
||||
{
|
||||
int len;
|
||||
char *cptr;
|
||||
int idx;
|
||||
pp_entry_t *ppp;
|
||||
|
||||
if(!def)
|
||||
return NULL;
|
||||
idx = pphash(def);
|
||||
if((ppp = pplookup(def)) != NULL)
|
||||
{
|
||||
if(pp_status.pedantic)
|
||||
ppy_warning("Redefinition of %s\n\tPrevious definition: %s:%d", def, ppp->filename, ppp->linenumber);
|
||||
pp_del_define(def);
|
||||
}
|
||||
ppp = pp_xmalloc(sizeof(pp_entry_t));
|
||||
if(!ppp)
|
||||
return NULL;
|
||||
memset( ppp, 0, sizeof(*ppp) );
|
||||
ppp->ident = pp_xstrdup(def);
|
||||
if(!ppp->ident)
|
||||
goto error;
|
||||
ppp->type = def_define;
|
||||
ppp->subst.text = text ? pp_xstrdup(text) : NULL;
|
||||
if(text && !ppp->subst.text)
|
||||
goto error;
|
||||
ppp->filename = pp_xstrdup(pp_status.input ? pp_status.input : "<internal or cmdline>");
|
||||
if(!ppp->filename)
|
||||
goto error;
|
||||
ppp->linenumber = pp_status.input ? pp_status.line_number : 0;
|
||||
ppp->next = pp_def_state->defines[idx];
|
||||
pp_def_state->defines[idx] = ppp;
|
||||
if(ppp->next)
|
||||
ppp->next->prev = ppp;
|
||||
if(ppp->subst.text)
|
||||
{
|
||||
/* Strip trailing white space from subst text */
|
||||
len = strlen(ppp->subst.text);
|
||||
while(len && strchr(" \t\r\n", ppp->subst.text[len-1]))
|
||||
{
|
||||
ppp->subst.text[--len] = '\0';
|
||||
}
|
||||
/* Strip leading white space from subst text */
|
||||
for(cptr = ppp->subst.text; *cptr && strchr(" \t\r", *cptr); cptr++)
|
||||
;
|
||||
if(ppp->subst.text != cptr)
|
||||
memmove(ppp->subst.text, cptr, strlen(cptr)+1);
|
||||
}
|
||||
if(pp_status.debug)
|
||||
printf("Added define (%s, %d) <%s> to <%s>\n", pp_status.input, pp_status.line_number, ppp->ident, ppp->subst.text ? ppp->subst.text : "(null)");
|
||||
|
||||
return ppp;
|
||||
|
||||
error:
|
||||
free(ppp->ident);
|
||||
free(ppp->subst.text);
|
||||
free(ppp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pp_entry_t *pp_add_macro(char *id, marg_t *args[], int nargs, mtext_t *exp)
|
||||
{
|
||||
int idx;
|
||||
pp_entry_t *ppp;
|
||||
|
||||
if(!id)
|
||||
return NULL;
|
||||
idx = pphash(id);
|
||||
if((ppp = pplookup(id)) != NULL)
|
||||
{
|
||||
if(pp_status.pedantic)
|
||||
ppy_warning("Redefinition of %s\n\tPrevious definition: %s:%d", id, ppp->filename, ppp->linenumber);
|
||||
pp_del_define(id);
|
||||
}
|
||||
ppp = pp_xmalloc(sizeof(pp_entry_t));
|
||||
if(!ppp)
|
||||
return NULL;
|
||||
memset( ppp, 0, sizeof(*ppp) );
|
||||
ppp->ident = id;
|
||||
ppp->type = def_macro;
|
||||
ppp->margs = args;
|
||||
ppp->nargs = nargs;
|
||||
ppp->subst.mtext= exp;
|
||||
ppp->filename = pp_xstrdup(pp_status.input ? pp_status.input : "<internal or cmdline>");
|
||||
if(!ppp->filename)
|
||||
{
|
||||
free(ppp);
|
||||
return NULL;
|
||||
}
|
||||
ppp->linenumber = pp_status.input ? pp_status.line_number : 0;
|
||||
ppp->next = pp_def_state->defines[idx];
|
||||
pp_def_state->defines[idx] = ppp;
|
||||
if(ppp->next)
|
||||
ppp->next->prev = ppp;
|
||||
|
||||
if(pp_status.debug)
|
||||
{
|
||||
fprintf(stderr, "Added macro (%s, %d) <%s(%d)> to <", pp_status.input, pp_status.line_number, ppp->ident, nargs);
|
||||
for(; exp; exp = exp->next)
|
||||
{
|
||||
switch(exp->type)
|
||||
{
|
||||
case exp_text:
|
||||
fprintf(stderr, " \"%s\" ", exp->subst.text);
|
||||
break;
|
||||
case exp_stringize:
|
||||
fprintf(stderr, " #(%d) ", exp->subst.argidx);
|
||||
break;
|
||||
case exp_concat:
|
||||
fprintf(stderr, "##");
|
||||
break;
|
||||
case exp_subst:
|
||||
fprintf(stderr, " <%d> ", exp->subst.argidx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fprintf(stderr, ">\n");
|
||||
}
|
||||
return ppp;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-------------------------------------------------------------------------
|
||||
* Include management
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#if defined(_WIN32) || defined(__MSDOS__)
|
||||
#define INCLUDESEPARATOR ";"
|
||||
#else
|
||||
#define INCLUDESEPARATOR ":"
|
||||
#endif
|
||||
|
||||
static char **includepath;
|
||||
static int nincludepath = 0;
|
||||
|
||||
int wpp_add_include_path(const char *path)
|
||||
{
|
||||
char *tok;
|
||||
char *cpy = pp_xstrdup(path);
|
||||
if(!cpy)
|
||||
return 1;
|
||||
|
||||
tok = strtok(cpy, INCLUDESEPARATOR);
|
||||
while(tok)
|
||||
{
|
||||
if(*tok) {
|
||||
char *dir;
|
||||
char *cptr;
|
||||
char **new_path;
|
||||
|
||||
dir = pp_xstrdup(tok);
|
||||
if(!dir)
|
||||
{
|
||||
free(cpy);
|
||||
return 1;
|
||||
}
|
||||
for(cptr = dir; *cptr; cptr++)
|
||||
{
|
||||
/* Convert to forward slash */
|
||||
if(*cptr == '\\')
|
||||
*cptr = '/';
|
||||
}
|
||||
/* Kill eventual trailing '/' */
|
||||
if(*(cptr = dir + strlen(dir)-1) == '/')
|
||||
*cptr = '\0';
|
||||
|
||||
/* Add to list */
|
||||
new_path = pp_xrealloc(includepath, (nincludepath+1) * sizeof(*includepath));
|
||||
if(!new_path)
|
||||
{
|
||||
free(dir);
|
||||
free(cpy);
|
||||
return 1;
|
||||
}
|
||||
includepath = new_path;
|
||||
includepath[nincludepath] = dir;
|
||||
nincludepath++;
|
||||
}
|
||||
tok = strtok(NULL, INCLUDESEPARATOR);
|
||||
}
|
||||
free(cpy);
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *wpp_find_include(const char *name, const char *parent_name)
|
||||
{
|
||||
return wpp_default_lookup(name, !!parent_name, parent_name, includepath, nincludepath);
|
||||
}
|
||||
|
||||
void *pp_open_include(const char *name, int type, const char *parent_name, char **newpath)
|
||||
{
|
||||
char *path;
|
||||
void *fp;
|
||||
|
||||
if (!(path = wpp_callbacks->lookup(name, type, parent_name, includepath,
|
||||
nincludepath))) return NULL;
|
||||
fp = wpp_callbacks->open(path, type);
|
||||
|
||||
if (fp)
|
||||
{
|
||||
if (pp_status.debug)
|
||||
printf("Going to include <%s>\n", path);
|
||||
if (newpath) *newpath = path;
|
||||
else free( path );
|
||||
return fp;
|
||||
}
|
||||
free( path );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
*-------------------------------------------------------------------------
|
||||
* #if, #ifdef, #ifndef, #else, #elif and #endif state management
|
||||
*
|
||||
* #if state transitions are made on basis of the current TOS and the next
|
||||
* required state. The state transitions are required to housekeep because
|
||||
* #if:s can be nested. The ignore case is activated to prevent output from
|
||||
* within a false clause.
|
||||
* Some special cases come from the fact that the #elif cases are not
|
||||
* binary, but three-state. The problem is that all other elif-cases must
|
||||
* be false when one true one has been found. A second problem is that the
|
||||
* #else clause is a final clause. No extra #else:s may follow.
|
||||
*
|
||||
* The states mean:
|
||||
* if_true Process input to output
|
||||
* if_false Process input but no output
|
||||
* if_ignore Process input but no output
|
||||
* if_elif Process input but no output
|
||||
* if_elsefalse Process input but no output
|
||||
* if_elsettrue Process input to output
|
||||
*
|
||||
* The possible state-sequences are [state(stack depth)] (rest can be deduced):
|
||||
* TOS #if 1 #else #endif
|
||||
* if_true(n) if_true(n+1) if_elsefalse(n+1)
|
||||
* if_false(n) if_ignore(n+1) if_ignore(n+1)
|
||||
* if_elsetrue(n) if_true(n+1) if_elsefalse(n+1)
|
||||
* if_elsefalse(n) if_ignore(n+1) if_ignore(n+1)
|
||||
* if_elif(n) if_ignore(n+1) if_ignore(n+1)
|
||||
* if_ignore(n) if_ignore(n+1) if_ignore(n+1)
|
||||
*
|
||||
* TOS #if 1 #elif 0 #else #endif
|
||||
* if_true(n) if_true(n+1) if_elif(n+1) if_elif(n+1)
|
||||
* if_false(n) if_ignore(n+1) if_ignore(n+1) if_ignore(n+1)
|
||||
* if_elsetrue(n) if_true(n+1) if_elif(n+1) if_elif(n+1)
|
||||
* if_elsefalse(n) if_ignore(n+1) if_ignore(n+1) if_ignore(n+1)
|
||||
* if_elif(n) if_ignore(n+1) if_ignore(n+1) if_ignore(n+1)
|
||||
* if_ignore(n) if_ignore(n+1) if_ignore(n+1) if_ignore(n+1)
|
||||
*
|
||||
* TOS #if 0 #elif 1 #else #endif
|
||||
* if_true(n) if_false(n+1) if_true(n+1) if_elsefalse(n+1)
|
||||
* if_false(n) if_ignore(n+1) if_ignore(n+1) if_ignore(n+1)
|
||||
* if_elsetrue(n) if_false(n+1) if_true(n+1) if_elsefalse(n+1)
|
||||
* if_elsefalse(n) if_ignore(n+1) if_ignore(n+1) if_ignore(n+1)
|
||||
* if_elif(n) if_ignore(n+1) if_ignore(n+1) if_ignore(n+1)
|
||||
* if_ignore(n) if_ignore(n+1) if_ignore(n+1) if_ignore(n+1)
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static const char * const pp_if_state_str[] = {
|
||||
"if_false",
|
||||
"if_true",
|
||||
"if_elif",
|
||||
"if_elsefalse",
|
||||
"if_elsetrue",
|
||||
"if_ignore"
|
||||
};
|
||||
|
||||
void pp_push_if(pp_if_state_t s)
|
||||
{
|
||||
if(if_stack_idx >= MAXIFSTACK)
|
||||
pp_internal_error(__FILE__, __LINE__, "#if-stack overflow; #{if,ifdef,ifndef} nested too deeply (> %d)", MAXIFSTACK);
|
||||
|
||||
if(pp_flex_debug)
|
||||
fprintf(stderr, "Push if %s:%d: %s(%d) -> %s(%d)\n", pp_status.input, pp_status.line_number, pp_if_state_str[pp_if_state()], if_stack_idx, pp_if_state_str[s], if_stack_idx+1);
|
||||
|
||||
if_stack[if_stack_idx++] = s;
|
||||
|
||||
switch(s)
|
||||
{
|
||||
case if_true:
|
||||
case if_elsetrue:
|
||||
break;
|
||||
case if_false:
|
||||
case if_elsefalse:
|
||||
case if_elif:
|
||||
case if_ignore:
|
||||
pp_push_ignore_state();
|
||||
break;
|
||||
default:
|
||||
pp_internal_error(__FILE__, __LINE__, "Invalid pp_if_state (%d)", (int)pp_if_state());
|
||||
}
|
||||
}
|
||||
|
||||
pp_if_state_t pp_pop_if(void)
|
||||
{
|
||||
if(if_stack_idx <= 0)
|
||||
{
|
||||
ppy_error("#{endif,else,elif} without #{if,ifdef,ifndef} (#if-stack underflow)");
|
||||
return if_error;
|
||||
}
|
||||
|
||||
switch(pp_if_state())
|
||||
{
|
||||
case if_true:
|
||||
case if_elsetrue:
|
||||
break;
|
||||
case if_false:
|
||||
case if_elsefalse:
|
||||
case if_elif:
|
||||
case if_ignore:
|
||||
pp_pop_ignore_state();
|
||||
break;
|
||||
default:
|
||||
pp_internal_error(__FILE__, __LINE__, "Invalid pp_if_state (%d)", (int)pp_if_state());
|
||||
}
|
||||
|
||||
if(pp_flex_debug)
|
||||
fprintf(stderr, "Pop if %s:%d: %s(%d) -> %s(%d)\n",
|
||||
pp_status.input,
|
||||
pp_status.line_number,
|
||||
pp_if_state_str[pp_if_state()],
|
||||
if_stack_idx,
|
||||
pp_if_state_str[if_stack[if_stack_idx <= 1 ? if_true : if_stack_idx-2]],
|
||||
if_stack_idx-1);
|
||||
|
||||
return if_stack[--if_stack_idx];
|
||||
}
|
||||
|
||||
pp_if_state_t pp_if_state(void)
|
||||
{
|
||||
if(!if_stack_idx)
|
||||
return if_true;
|
||||
else
|
||||
return if_stack[if_stack_idx-1];
|
||||
}
|
||||
|
||||
|
||||
void pp_next_if_state(int i)
|
||||
{
|
||||
switch(pp_if_state())
|
||||
{
|
||||
case if_true:
|
||||
case if_elsetrue:
|
||||
pp_push_if(i ? if_true : if_false);
|
||||
break;
|
||||
case if_false:
|
||||
case if_elsefalse:
|
||||
case if_elif:
|
||||
case if_ignore:
|
||||
pp_push_if(if_ignore);
|
||||
break;
|
||||
default:
|
||||
pp_internal_error(__FILE__, __LINE__, "Invalid pp_if_state (%d) in #{if,ifdef,ifndef} directive", (int)pp_if_state());
|
||||
}
|
||||
}
|
||||
|
||||
int pp_get_if_depth(void)
|
||||
{
|
||||
return if_stack_idx;
|
||||
}
|
||||
|
||||
/* #define WANT_NEAR_INDICATION */
|
||||
|
||||
static void generic_msg(const char *s, const char *t, const char *n, va_list ap)
|
||||
{
|
||||
fprintf(stderr, "%s:%d:%d: %s: ", pp_status.input ? pp_status.input : "stdin",
|
||||
pp_status.line_number, pp_status.char_number, t);
|
||||
vfprintf(stderr, s, ap);
|
||||
#ifdef WANT_NEAR_INDICATION
|
||||
{
|
||||
char *cpy, *p;
|
||||
if(n)
|
||||
{
|
||||
cpy = pp_xstrdup(n);
|
||||
if(!cpy)
|
||||
goto end;
|
||||
for (p = cpy; *p; p++) if(!isprint(*p)) *p = ' ';
|
||||
fprintf(stderr, " near '%s'", cpy);
|
||||
free(cpy);
|
||||
}
|
||||
}
|
||||
end:
|
||||
#endif
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
static void wpp_default_error(const char *file, int line, int col, const char *near, const char *msg, va_list ap)
|
||||
{
|
||||
generic_msg(msg, "Error", near, ap);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void wpp_default_warning(const char *file, int line, int col, const char *near, const char *msg, va_list ap)
|
||||
{
|
||||
generic_msg(msg, "Warning", near, ap);
|
||||
}
|
||||
|
||||
static const struct wpp_callbacks default_callbacks =
|
||||
{
|
||||
wpp_default_lookup,
|
||||
wpp_default_open,
|
||||
wpp_default_close,
|
||||
wpp_default_read,
|
||||
wpp_default_write,
|
||||
wpp_default_error,
|
||||
wpp_default_warning,
|
||||
};
|
||||
|
||||
const struct wpp_callbacks *wpp_callbacks = &default_callbacks;
|
||||
|
||||
int ppy_error(const char *s, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, s);
|
||||
wpp_callbacks->error(pp_status.input, pp_status.line_number, pp_status.char_number, ppy_text, s, ap);
|
||||
va_end(ap);
|
||||
pp_status.state = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ppy_warning(const char *s, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, s);
|
||||
wpp_callbacks->warning(pp_status.input, pp_status.line_number, pp_status.char_number, ppy_text, s, ap);
|
||||
va_end(ap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pp_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);
|
||||
}
|
||||
+501
-94
@@ -20,45 +20,510 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "wine/port.h"
|
||||
|
||||
#include <time.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "../tools.h"
|
||||
#include "utils.h"
|
||||
#include "wpp_private.h"
|
||||
#include "wine/wpp.h"
|
||||
|
||||
struct pp_status pp_status;
|
||||
|
||||
#define HASHKEY 2039
|
||||
|
||||
static struct list pp_defines[HASHKEY];
|
||||
|
||||
#define MAXIFSTACK 64
|
||||
static pp_if_state_t if_stack[MAXIFSTACK];
|
||||
static int if_stack_idx = 0;
|
||||
|
||||
int ppy_debug, pp_flex_debug;
|
||||
|
||||
struct define
|
||||
{
|
||||
struct define *next;
|
||||
struct list entry;
|
||||
char *name;
|
||||
char *value;
|
||||
};
|
||||
|
||||
static struct define *cmdline_defines;
|
||||
static struct list cmdline_defines = LIST_INIT( cmdline_defines );
|
||||
static struct strarray includes;
|
||||
|
||||
static char *wpp_lookup(const char *name, int type, const char *parent_name)
|
||||
{
|
||||
char *cpy;
|
||||
char *cptr;
|
||||
char *path;
|
||||
const char *ccptr;
|
||||
int i, fd;
|
||||
|
||||
cpy = xmalloc(strlen(name)+1);
|
||||
cptr = cpy;
|
||||
|
||||
for(ccptr = name; *ccptr; ccptr++)
|
||||
{
|
||||
/* Convert to forward slash */
|
||||
if(*ccptr == '\\') {
|
||||
/* kill double backslash */
|
||||
if(ccptr[1] == '\\')
|
||||
ccptr++;
|
||||
*cptr = '/';
|
||||
}else {
|
||||
*cptr = *ccptr;
|
||||
}
|
||||
cptr++;
|
||||
}
|
||||
*cptr = '\0';
|
||||
|
||||
if(type && parent_name)
|
||||
{
|
||||
/* Search directory of parent include and then -I path */
|
||||
path = strmake( "%s/%s", get_dirname(parent_name), cpy );
|
||||
fd = open( path, O_RDONLY );
|
||||
if (fd != -1)
|
||||
{
|
||||
close( fd );
|
||||
free( cpy );
|
||||
return path;
|
||||
}
|
||||
free( path );
|
||||
}
|
||||
/* Search -I path */
|
||||
for(i = 0; i < includes.count; i++)
|
||||
{
|
||||
path = strmake("%s/%s", includes.str[i], cpy);
|
||||
fd = open( path, O_RDONLY );
|
||||
if (fd != -1)
|
||||
{
|
||||
close( fd );
|
||||
free( cpy );
|
||||
return path;
|
||||
}
|
||||
free( path );
|
||||
}
|
||||
free( cpy );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Don't comment on the hash, it's primitive but functional... */
|
||||
static int pphash(const char *str)
|
||||
{
|
||||
int sum = 0;
|
||||
while(*str)
|
||||
sum += *str++;
|
||||
return sum % HASHKEY;
|
||||
}
|
||||
|
||||
pp_entry_t *pplookup(const char *ident)
|
||||
{
|
||||
int idx;
|
||||
pp_entry_t *ppp;
|
||||
|
||||
if(!ident)
|
||||
return NULL;
|
||||
idx = pphash(ident);
|
||||
LIST_FOR_EACH_ENTRY( ppp, &pp_defines[idx], pp_entry_t, entry )
|
||||
{
|
||||
if(!strcmp(ident, ppp->ident))
|
||||
return ppp;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void free_pp_entry( pp_entry_t *ppp, int idx )
|
||||
{
|
||||
if(ppp->iep)
|
||||
{
|
||||
list_remove( &ppp->iep->entry );
|
||||
free(ppp->iep->filename);
|
||||
free(ppp->iep);
|
||||
}
|
||||
list_remove( &ppp->entry );
|
||||
free(ppp);
|
||||
}
|
||||
|
||||
/* initialize the define state */
|
||||
static void pp_init_define_state(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < HASHKEY; i++) list_init( &pp_defines[i] );
|
||||
}
|
||||
|
||||
/* free the current define state */
|
||||
static void pp_free_define_state(void)
|
||||
{
|
||||
int i;
|
||||
pp_entry_t *ppp, *ppp2;
|
||||
|
||||
for (i = 0; i < HASHKEY; i++)
|
||||
{
|
||||
LIST_FOR_EACH_ENTRY_SAFE( ppp, ppp2, &pp_defines[i], pp_entry_t, entry )
|
||||
{
|
||||
free( ppp->ident );
|
||||
free( ppp->subst.text );
|
||||
free( ppp->filename );
|
||||
free_pp_entry( ppp, i );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pp_del_define(const char *name)
|
||||
{
|
||||
pp_entry_t *ppp;
|
||||
int idx = pphash(name);
|
||||
|
||||
if((ppp = pplookup(name)) == NULL)
|
||||
{
|
||||
if(pedantic)
|
||||
ppy_warning("%s was not defined", name);
|
||||
return;
|
||||
}
|
||||
|
||||
if(pp_status.debug)
|
||||
printf("Deleting (%s, %d) <%s>\n", pp_status.input, pp_status.line_number, name);
|
||||
|
||||
free( ppp->ident );
|
||||
free( ppp->subst.text );
|
||||
free( ppp->filename );
|
||||
free_pp_entry( ppp, idx );
|
||||
}
|
||||
|
||||
pp_entry_t *pp_add_define(const char *def, const char *text)
|
||||
{
|
||||
int len;
|
||||
char *cptr;
|
||||
int idx;
|
||||
pp_entry_t *ppp;
|
||||
|
||||
idx = pphash(def);
|
||||
if((ppp = pplookup(def)) != NULL)
|
||||
{
|
||||
if(pedantic)
|
||||
ppy_warning("Redefinition of %s\n%s:%d: note: previous definition was here",
|
||||
def, ppp->filename, ppp->linenumber);
|
||||
pp_del_define(def);
|
||||
}
|
||||
ppp = xmalloc(sizeof(pp_entry_t));
|
||||
memset( ppp, 0, sizeof(*ppp) );
|
||||
ppp->ident = xstrdup(def);
|
||||
ppp->type = def_define;
|
||||
ppp->subst.text = text ? xstrdup(text) : NULL;
|
||||
ppp->filename = xstrdup(pp_status.input ? pp_status.input : "<internal or cmdline>");
|
||||
ppp->linenumber = pp_status.input ? pp_status.line_number : 0;
|
||||
list_add_head( &pp_defines[idx], &ppp->entry );
|
||||
if(ppp->subst.text)
|
||||
{
|
||||
/* Strip trailing white space from subst text */
|
||||
len = strlen(ppp->subst.text);
|
||||
while(len && strchr(" \t\r\n", ppp->subst.text[len-1]))
|
||||
{
|
||||
ppp->subst.text[--len] = '\0';
|
||||
}
|
||||
/* Strip leading white space from subst text */
|
||||
for(cptr = ppp->subst.text; *cptr && strchr(" \t\r", *cptr); cptr++)
|
||||
;
|
||||
if(ppp->subst.text != cptr)
|
||||
memmove(ppp->subst.text, cptr, strlen(cptr)+1);
|
||||
}
|
||||
if(pp_status.debug)
|
||||
printf("Added define (%s, %d) <%s> to <%s>\n", pp_status.input, pp_status.line_number, ppp->ident, ppp->subst.text ? ppp->subst.text : "(null)");
|
||||
|
||||
return ppp;
|
||||
}
|
||||
|
||||
pp_entry_t *pp_add_macro(char *id, char *args[], int nargs, int variadic, mtext_t *exp)
|
||||
{
|
||||
int idx;
|
||||
pp_entry_t *ppp;
|
||||
|
||||
idx = pphash(id);
|
||||
if((ppp = pplookup(id)) != NULL)
|
||||
{
|
||||
if(pedantic)
|
||||
ppy_warning("Redefinition of %s\n%s:%d: note: previous definition was here",
|
||||
id, ppp->filename, ppp->linenumber);
|
||||
pp_del_define(id);
|
||||
}
|
||||
ppp = xmalloc(sizeof(pp_entry_t));
|
||||
memset( ppp, 0, sizeof(*ppp) );
|
||||
ppp->ident = id;
|
||||
ppp->type = def_macro;
|
||||
ppp->margs = args;
|
||||
ppp->nargs = nargs;
|
||||
ppp->variadic = variadic;
|
||||
ppp->subst.mtext= exp;
|
||||
ppp->filename = xstrdup(pp_status.input ? pp_status.input : "<internal or cmdline>");
|
||||
ppp->linenumber = pp_status.input ? pp_status.line_number : 0;
|
||||
list_add_head( &pp_defines[idx], &ppp->entry );
|
||||
if(pp_status.debug)
|
||||
{
|
||||
fprintf(stderr, "Added macro (%s, %d) <%s(%d%s)> to <", pp_status.input, pp_status.line_number, ppp->ident, nargs, variadic ? ",va" : "");
|
||||
for(; exp; exp = exp->next)
|
||||
{
|
||||
switch(exp->type)
|
||||
{
|
||||
case exp_text:
|
||||
fprintf(stderr, " \"%s\" ", exp->subst.text);
|
||||
break;
|
||||
case exp_stringize:
|
||||
fprintf(stderr, " #(%d) ", exp->subst.argidx);
|
||||
break;
|
||||
case exp_concat:
|
||||
fprintf(stderr, "##");
|
||||
break;
|
||||
case exp_subst:
|
||||
fprintf(stderr, " <%d> ", exp->subst.argidx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fprintf(stderr, ">\n");
|
||||
}
|
||||
return ppp;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*-------------------------------------------------------------------------
|
||||
* Include management
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
void wpp_add_include_path(const char *path)
|
||||
{
|
||||
char *dir = xstrdup(path);
|
||||
char *cptr;
|
||||
|
||||
for(cptr = dir; *cptr; cptr++)
|
||||
{
|
||||
/* Convert to forward slash */
|
||||
if(*cptr == '\\')
|
||||
*cptr = '/';
|
||||
}
|
||||
/* Kill eventual trailing '/' */
|
||||
if(*(cptr = dir + strlen(dir)-1) == '/') *cptr = '\0';
|
||||
|
||||
strarray_add( &includes, dir );
|
||||
}
|
||||
|
||||
char *wpp_find_include(const char *name, const char *parent_name)
|
||||
{
|
||||
return wpp_lookup(name, !!parent_name, parent_name);
|
||||
}
|
||||
|
||||
void *pp_open_include(const char *name, int type, const char *parent_name, char **newpath)
|
||||
{
|
||||
char *path;
|
||||
void *fp;
|
||||
|
||||
if (!(path = wpp_lookup(name, type, parent_name))) return NULL;
|
||||
fp = fopen(path, "rt");
|
||||
|
||||
if (fp)
|
||||
{
|
||||
if (pp_status.debug)
|
||||
printf("Going to include <%s>\n", path);
|
||||
if (newpath) *newpath = path;
|
||||
else free( path );
|
||||
return fp;
|
||||
}
|
||||
free( path );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
*-------------------------------------------------------------------------
|
||||
* #if, #ifdef, #ifndef, #else, #elif and #endif state management
|
||||
*
|
||||
* #if state transitions are made on basis of the current TOS and the next
|
||||
* required state. The state transitions are required to housekeep because
|
||||
* #if:s can be nested. The ignore case is activated to prevent output from
|
||||
* within a false clause.
|
||||
* Some special cases come from the fact that the #elif cases are not
|
||||
* binary, but three-state. The problem is that all other elif-cases must
|
||||
* be false when one true one has been found. A second problem is that the
|
||||
* #else clause is a final clause. No extra #else:s may follow.
|
||||
*
|
||||
* The states mean:
|
||||
* if_true Process input to output
|
||||
* if_false Process input but no output
|
||||
* if_ignore Process input but no output
|
||||
* if_elif Process input but no output
|
||||
* if_elsefalse Process input but no output
|
||||
* if_elsettrue Process input to output
|
||||
*
|
||||
* The possible state-sequences are [state(stack depth)] (rest can be deduced):
|
||||
* TOS #if 1 #else #endif
|
||||
* if_true(n) if_true(n+1) if_elsefalse(n+1)
|
||||
* if_false(n) if_ignore(n+1) if_ignore(n+1)
|
||||
* if_elsetrue(n) if_true(n+1) if_elsefalse(n+1)
|
||||
* if_elsefalse(n) if_ignore(n+1) if_ignore(n+1)
|
||||
* if_elif(n) if_ignore(n+1) if_ignore(n+1)
|
||||
* if_ignore(n) if_ignore(n+1) if_ignore(n+1)
|
||||
*
|
||||
* TOS #if 1 #elif 0 #else #endif
|
||||
* if_true(n) if_true(n+1) if_elif(n+1) if_elif(n+1)
|
||||
* if_false(n) if_ignore(n+1) if_ignore(n+1) if_ignore(n+1)
|
||||
* if_elsetrue(n) if_true(n+1) if_elif(n+1) if_elif(n+1)
|
||||
* if_elsefalse(n) if_ignore(n+1) if_ignore(n+1) if_ignore(n+1)
|
||||
* if_elif(n) if_ignore(n+1) if_ignore(n+1) if_ignore(n+1)
|
||||
* if_ignore(n) if_ignore(n+1) if_ignore(n+1) if_ignore(n+1)
|
||||
*
|
||||
* TOS #if 0 #elif 1 #else #endif
|
||||
* if_true(n) if_false(n+1) if_true(n+1) if_elsefalse(n+1)
|
||||
* if_false(n) if_ignore(n+1) if_ignore(n+1) if_ignore(n+1)
|
||||
* if_elsetrue(n) if_false(n+1) if_true(n+1) if_elsefalse(n+1)
|
||||
* if_elsefalse(n) if_ignore(n+1) if_ignore(n+1) if_ignore(n+1)
|
||||
* if_elif(n) if_ignore(n+1) if_ignore(n+1) if_ignore(n+1)
|
||||
* if_ignore(n) if_ignore(n+1) if_ignore(n+1) if_ignore(n+1)
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static const char * const pp_if_state_str[] = {
|
||||
"if_false",
|
||||
"if_true",
|
||||
"if_elif",
|
||||
"if_elsefalse",
|
||||
"if_elsetrue",
|
||||
"if_ignore"
|
||||
};
|
||||
|
||||
void pp_push_if(pp_if_state_t s)
|
||||
{
|
||||
if(if_stack_idx >= MAXIFSTACK)
|
||||
error("#if-stack overflow; #{if,ifdef,ifndef} nested too deeply (> %d)\n", MAXIFSTACK);
|
||||
|
||||
if(pp_flex_debug)
|
||||
fprintf(stderr, "Push if %s:%d: %s(%d) -> %s(%d)\n", pp_status.input, pp_status.line_number, pp_if_state_str[pp_if_state()], if_stack_idx, pp_if_state_str[s], if_stack_idx+1);
|
||||
|
||||
if_stack[if_stack_idx++] = s;
|
||||
|
||||
switch(s)
|
||||
{
|
||||
case if_true:
|
||||
case if_elsetrue:
|
||||
break;
|
||||
case if_false:
|
||||
case if_elsefalse:
|
||||
case if_elif:
|
||||
case if_ignore:
|
||||
pp_push_ignore_state();
|
||||
break;
|
||||
case if_error:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
pp_if_state_t pp_pop_if(void)
|
||||
{
|
||||
if(if_stack_idx <= 0)
|
||||
{
|
||||
ppy_error("#{endif,else,elif} without #{if,ifdef,ifndef} (#if-stack underflow)");
|
||||
return if_error;
|
||||
}
|
||||
|
||||
switch(pp_if_state())
|
||||
{
|
||||
case if_true:
|
||||
case if_elsetrue:
|
||||
break;
|
||||
case if_false:
|
||||
case if_elsefalse:
|
||||
case if_elif:
|
||||
case if_ignore:
|
||||
pp_pop_ignore_state();
|
||||
break;
|
||||
case if_error:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
if(pp_flex_debug)
|
||||
fprintf(stderr, "Pop if %s:%d: %s(%d) -> %s(%d)\n",
|
||||
pp_status.input,
|
||||
pp_status.line_number,
|
||||
pp_if_state_str[pp_if_state()],
|
||||
if_stack_idx,
|
||||
pp_if_state_str[if_stack[if_stack_idx <= 1 ? if_true : if_stack_idx-2]],
|
||||
if_stack_idx-1);
|
||||
|
||||
return if_stack[--if_stack_idx];
|
||||
}
|
||||
|
||||
pp_if_state_t pp_if_state(void)
|
||||
{
|
||||
if(!if_stack_idx)
|
||||
return if_true;
|
||||
else
|
||||
return if_stack[if_stack_idx-1];
|
||||
}
|
||||
|
||||
|
||||
void pp_next_if_state(int i)
|
||||
{
|
||||
switch(pp_if_state())
|
||||
{
|
||||
case if_true:
|
||||
case if_elsetrue:
|
||||
pp_push_if(i ? if_true : if_false);
|
||||
break;
|
||||
case if_false:
|
||||
case if_elsefalse:
|
||||
case if_elif:
|
||||
case if_ignore:
|
||||
pp_push_if(if_ignore);
|
||||
break;
|
||||
case if_error:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
int pp_get_if_depth(void)
|
||||
{
|
||||
return if_stack_idx;
|
||||
}
|
||||
|
||||
static void generic_msg(const char *s, const char *t, const char *n, va_list ap)
|
||||
{
|
||||
fprintf(stderr, "%s:%d:%d: %s: ", pp_status.input ? pp_status.input : "stdin",
|
||||
pp_status.line_number, pp_status.char_number, t);
|
||||
vfprintf(stderr, s, ap);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
int ppy_error(const char *s, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, s);
|
||||
generic_msg(s, "error", ppy_text, ap);
|
||||
va_end(ap);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int ppy_warning(const char *s, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, s);
|
||||
generic_msg(s, "warning", ppy_text, ap);
|
||||
va_end(ap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void add_cmdline_defines(void)
|
||||
{
|
||||
struct define *def;
|
||||
|
||||
for (def = cmdline_defines; def; def = def->next)
|
||||
LIST_FOR_EACH_ENTRY( def, &cmdline_defines, struct define, entry )
|
||||
{
|
||||
if (def->value) pp_add_define( def->name, def->value );
|
||||
}
|
||||
}
|
||||
|
||||
static void del_cmdline_defines(void)
|
||||
{
|
||||
struct define *def;
|
||||
|
||||
for (def = cmdline_defines; def; def = def->next)
|
||||
{
|
||||
if (def->value) pp_del_define( def->name );
|
||||
}
|
||||
}
|
||||
|
||||
static void add_special_defines(void)
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
@@ -72,63 +537,33 @@ static void add_special_defines(void)
|
||||
pp_add_define( "__TIME__", buf );
|
||||
|
||||
ppp = pp_add_define( "__FILE__", "" );
|
||||
if(ppp)
|
||||
ppp->type = def_special;
|
||||
ppp->type = def_special;
|
||||
|
||||
ppp = pp_add_define( "__LINE__", "" );
|
||||
if(ppp)
|
||||
ppp->type = def_special;
|
||||
ppp->type = def_special;
|
||||
}
|
||||
|
||||
static void del_special_defines(void)
|
||||
{
|
||||
pp_del_define( "__DATE__" );
|
||||
pp_del_define( "__TIME__" );
|
||||
pp_del_define( "__FILE__" );
|
||||
pp_del_define( "__LINE__" );
|
||||
}
|
||||
|
||||
|
||||
/* add a define to the preprocessor list */
|
||||
int wpp_add_define( const char *name, const char *value )
|
||||
static void wpp_add_define( const char *name, const char *value )
|
||||
{
|
||||
struct define *def;
|
||||
|
||||
if (!value) value = "";
|
||||
|
||||
for (def = cmdline_defines; def; def = def->next)
|
||||
LIST_FOR_EACH_ENTRY( def, &cmdline_defines, struct define, entry )
|
||||
{
|
||||
if (!strcmp( def->name, name ))
|
||||
{
|
||||
char *new_value = pp_xstrdup(value);
|
||||
if(!new_value)
|
||||
return 1;
|
||||
free( def->value );
|
||||
def->value = new_value;
|
||||
|
||||
return 0;
|
||||
def->value = xstrdup(value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
def = pp_xmalloc( sizeof(*def) );
|
||||
if(!def)
|
||||
return 1;
|
||||
def->next = cmdline_defines;
|
||||
def->name = pp_xstrdup(name);
|
||||
if(!def->name)
|
||||
{
|
||||
free(def);
|
||||
return 1;
|
||||
}
|
||||
def->value = pp_xstrdup(value);
|
||||
if(!def->value)
|
||||
{
|
||||
free(def->name);
|
||||
free(def);
|
||||
return 1;
|
||||
}
|
||||
cmdline_defines = def;
|
||||
return 0;
|
||||
def = xmalloc( sizeof(*def) );
|
||||
def->name = xstrdup(name);
|
||||
def->value = xstrdup(value);
|
||||
list_add_head( &cmdline_defines, &def->entry );
|
||||
}
|
||||
|
||||
|
||||
@@ -137,7 +572,7 @@ void wpp_del_define( const char *name )
|
||||
{
|
||||
struct define *def;
|
||||
|
||||
for (def = cmdline_defines; def; def = def->next)
|
||||
LIST_FOR_EACH_ENTRY( def, &cmdline_defines, struct define, entry )
|
||||
{
|
||||
if (!strcmp( def->name, name ))
|
||||
{
|
||||
@@ -150,17 +585,15 @@ void wpp_del_define( const char *name )
|
||||
|
||||
|
||||
/* add a command-line define of the form NAME=VALUE */
|
||||
int wpp_add_cmdline_define( const char *value )
|
||||
void wpp_add_cmdline_define( const char *value )
|
||||
{
|
||||
char *p;
|
||||
char *str = pp_xstrdup(value);
|
||||
if(!str)
|
||||
return 1;
|
||||
char *str = xstrdup(value);
|
||||
|
||||
p = strchr( str, '=' );
|
||||
if (p) *p++ = 0;
|
||||
wpp_add_define( str, p );
|
||||
free( str );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -173,13 +606,6 @@ void wpp_set_debug( int lex_debug, int parser_debug, int msg_debug )
|
||||
}
|
||||
|
||||
|
||||
/* set the pedantic mode */
|
||||
void wpp_set_pedantic( int on )
|
||||
{
|
||||
pp_status.pedantic = on;
|
||||
}
|
||||
|
||||
|
||||
/* the main preprocessor parsing loop */
|
||||
int wpp_parse( const char *input, FILE *output )
|
||||
{
|
||||
@@ -188,48 +614,29 @@ int wpp_parse( const char *input, FILE *output )
|
||||
pp_status.input = NULL;
|
||||
pp_status.line_number = 1;
|
||||
pp_status.char_number = 1;
|
||||
pp_status.state = 0;
|
||||
|
||||
ret = pp_push_define_state();
|
||||
if(ret)
|
||||
return ret;
|
||||
pp_init_define_state();
|
||||
add_cmdline_defines();
|
||||
add_special_defines();
|
||||
|
||||
if (!input) pp_status.file = stdin;
|
||||
else if (!(pp_status.file = wpp_callbacks->open(input, 1)))
|
||||
{
|
||||
else if (!(pp_status.file = fopen(input, "rt")))
|
||||
ppy_error("Could not open %s\n", input);
|
||||
del_special_defines();
|
||||
del_cmdline_defines();
|
||||
pp_pop_define_state();
|
||||
return 2;
|
||||
}
|
||||
|
||||
pp_status.input = input ? pp_xstrdup(input) : NULL;
|
||||
pp_status.input = input ? xstrdup(input) : NULL;
|
||||
|
||||
ppy_out = output;
|
||||
pp_writestring("# 1 \"%s\" 1\n", input ? input : "");
|
||||
fprintf(ppy_out, "# 1 \"%s\" 1\n", input ? input : "");
|
||||
|
||||
ret = ppy_parse();
|
||||
/* If there were errors during processing, return an error code */
|
||||
if (!ret && pp_status.state) ret = pp_status.state;
|
||||
|
||||
if (input)
|
||||
{
|
||||
wpp_callbacks->close(pp_status.file);
|
||||
fclose(pp_status.file);
|
||||
free(pp_status.input);
|
||||
}
|
||||
/* Clean if_stack, it could remain dirty on errors */
|
||||
while (pp_get_if_depth()) pp_pop_if();
|
||||
del_special_defines();
|
||||
del_cmdline_defines();
|
||||
pp_pop_define_state();
|
||||
pp_free_define_state();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void wpp_set_callbacks( const struct wpp_callbacks *callbacks )
|
||||
{
|
||||
wpp_callbacks = callbacks;
|
||||
}
|
||||
|
||||
+23
-76
@@ -20,12 +20,17 @@
|
||||
#ifndef __WINE_WPP_PRIVATE_H
|
||||
#define __WINE_WPP_PRIVATE_H
|
||||
|
||||
#ifndef __WINE_CONFIG_H
|
||||
# error You must include config.h to use this header
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "wine/list.h"
|
||||
|
||||
extern void wpp_del_define( const char *name );
|
||||
extern void wpp_add_cmdline_define( const char *value );
|
||||
extern void wpp_set_debug( int lex_debug, int parser_debug, int msg_debug );
|
||||
extern void wpp_add_include_path( const char *path );
|
||||
extern char *wpp_find_include( const char *name, const char *parent_name );
|
||||
/* Return value == 0 means successful execution */
|
||||
extern int wpp_parse( const char *input, FILE *output );
|
||||
|
||||
struct pp_entry; /* forward */
|
||||
/*
|
||||
@@ -34,26 +39,11 @@ struct pp_entry; /* forward */
|
||||
* are protected in the #ifndef/#endif way.
|
||||
*/
|
||||
typedef struct includelogicentry {
|
||||
struct includelogicentry *next;
|
||||
struct includelogicentry *prev;
|
||||
struct list entry;
|
||||
struct pp_entry *ppp; /* The define which protects the file */
|
||||
char *filename; /* The filename of the include */
|
||||
} includelogicentry_t;
|
||||
|
||||
/*
|
||||
* The arguments of a macrodefinition
|
||||
*/
|
||||
typedef enum {
|
||||
arg_single,
|
||||
arg_list
|
||||
} def_arg_t;
|
||||
|
||||
typedef struct marg {
|
||||
def_arg_t type; /* Normal or ... argument */
|
||||
char *arg; /* The textual argument */
|
||||
int nnl; /* Number of newlines in the text to subst */
|
||||
} marg_t;
|
||||
|
||||
/*
|
||||
* The expansiontext of a macro
|
||||
*/
|
||||
@@ -85,12 +75,12 @@ typedef enum {
|
||||
} def_type_t;
|
||||
|
||||
typedef struct pp_entry {
|
||||
struct pp_entry *next;
|
||||
struct pp_entry *prev;
|
||||
struct list entry;
|
||||
def_type_t type; /* Define or macro */
|
||||
char *ident; /* The key */
|
||||
marg_t **margs; /* Macro arguments array or NULL if none */
|
||||
char **margs; /* Macro arguments array or NULL if none */
|
||||
int nargs;
|
||||
int variadic;
|
||||
union {
|
||||
mtext_t *mtext; /* The substitution sequence or NULL if none */
|
||||
char *text;
|
||||
@@ -136,40 +126,13 @@ typedef struct
|
||||
int seen_junk; /* Set when junk is seen */
|
||||
} include_state_t;
|
||||
|
||||
|
||||
/*
|
||||
* If the configure says we have long long then we can use it. Presumably
|
||||
* if we have long long then we have strtoull and strtoll too. If that is
|
||||
* not the case we will need to add to the configure tests.
|
||||
* If we do not have long long , then we revert to a simple 'long' for now.
|
||||
* This should prevent most unexpected things with other compilers than
|
||||
* gcc and egcs for now.
|
||||
* In the future it should be possible to use another way, like a
|
||||
* structure, so that we can emulate the MS compiler.
|
||||
*/
|
||||
#ifdef HAVE_LONG_LONG
|
||||
typedef long long wrc_sll_t;
|
||||
typedef unsigned long long wrc_ull_t;
|
||||
#else
|
||||
typedef long wrc_sll_t;
|
||||
typedef unsigned long wrc_ull_t;
|
||||
#endif
|
||||
|
||||
#define SIZE_CHAR 1
|
||||
#define SIZE_SHORT 2
|
||||
#define SIZE_INT 3
|
||||
#define SIZE_LONG 4
|
||||
#define SIZE_LONGLONG 5
|
||||
#define SIZE_INT 1
|
||||
#define SIZE_LONG 2
|
||||
#define SIZE_LONGLONG 3
|
||||
#define SIZE_MASK 0x00ff
|
||||
#define FLAG_SIGNED 0x0100
|
||||
|
||||
typedef enum {
|
||||
#if 0
|
||||
cv_schar = SIZE_CHAR + FLAG_SIGNED,
|
||||
cv_uchar = SIZE_CHAR,
|
||||
cv_sshort = SIZE_SHORT + FLAG_SIGNED,
|
||||
cv_ushort = SIZE_SHORT,
|
||||
#endif
|
||||
cv_sint = SIZE_INT + FLAG_SIGNED,
|
||||
cv_uint = SIZE_INT,
|
||||
cv_slong = SIZE_LONG + FLAG_SIGNED,
|
||||
@@ -181,31 +144,20 @@ typedef enum {
|
||||
typedef struct cval {
|
||||
ctype_t type;
|
||||
union {
|
||||
#if 0
|
||||
signed char sc; /* Explicitly signed because compilers are stupid */
|
||||
unsigned char uc;
|
||||
short ss;
|
||||
unsigned short us;
|
||||
#endif
|
||||
int si;
|
||||
unsigned int ui;
|
||||
long sl;
|
||||
unsigned long ul;
|
||||
wrc_sll_t sll;
|
||||
wrc_ull_t ull;
|
||||
__int64 sll;
|
||||
unsigned __int64 ull;
|
||||
} val;
|
||||
} cval_t;
|
||||
|
||||
|
||||
|
||||
void *pp_xmalloc(size_t);
|
||||
void *pp_xrealloc(void *, size_t);
|
||||
char *pp_xstrdup(const char *str);
|
||||
pp_entry_t *pplookup(const char *ident);
|
||||
int pp_push_define_state(void);
|
||||
void pp_pop_define_state(void);
|
||||
pp_entry_t *pp_add_define(const char *def, const char *text);
|
||||
pp_entry_t *pp_add_macro(char *ident, marg_t *args[], int nargs, mtext_t *exp);
|
||||
pp_entry_t *pp_add_macro(char *ident, char *args[], int nargs, int variadic, mtext_t *exp);
|
||||
void pp_del_define(const char *name);
|
||||
void *pp_open_include(const char *name, int type, const char *parent_name, char **newpath);
|
||||
void pp_push_if(pp_if_state_t s);
|
||||
@@ -214,32 +166,29 @@ pp_if_state_t pp_pop_if(void);
|
||||
pp_if_state_t pp_if_state(void);
|
||||
int pp_get_if_depth(void);
|
||||
|
||||
#ifdef __REACTOS__
|
||||
#ifndef __GNUC__
|
||||
#define __attribute__(x) /*nothing*/
|
||||
#endif
|
||||
|
||||
extern const struct wpp_callbacks *wpp_callbacks;
|
||||
#endif
|
||||
|
||||
int ppy_error(const char *s, ...) __attribute__((format (printf, 1, 2)));
|
||||
int ppy_warning(const char *s, ...) __attribute__((format (printf, 1, 2)));
|
||||
void pp_internal_error(const char *file, int line, const char *s, ...) __attribute__((format (printf, 3, 4)));
|
||||
|
||||
/* current preprocessor state */
|
||||
/* everything is in this structure to avoid polluting the global symbol space */
|
||||
struct pp_status
|
||||
{
|
||||
char *input; /* current input file name */
|
||||
void *file; /* current input file descriptor */
|
||||
FILE *file; /* current input file descriptor */
|
||||
int line_number; /* current line number */
|
||||
int char_number; /* current char number in line */
|
||||
int state; /* current error state */
|
||||
int pedantic; /* pedantic option */
|
||||
int debug; /* debug messages flag */
|
||||
};
|
||||
|
||||
extern struct pp_status pp_status;
|
||||
extern include_state_t pp_incl_state;
|
||||
extern includelogicentry_t *pp_includelogiclist;
|
||||
extern int pedantic;
|
||||
|
||||
/*
|
||||
* From ppl.l
|
||||
@@ -254,8 +203,6 @@ void pp_do_include(char *fname, int type);
|
||||
void pp_push_ignore_state(void);
|
||||
void pp_pop_ignore_state(void);
|
||||
|
||||
void pp_writestring(const char *format, ...) __attribute__((format (printf, 1, 2)));
|
||||
|
||||
/*
|
||||
* From ppy.y
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user