diff --git a/reactos/tools/widl_new/ChangeLog b/reactos/tools/widl_new/ChangeLog new file mode 100644 index 00000000000..40c0dcb94e6 --- /dev/null +++ b/reactos/tools/widl_new/ChangeLog @@ -0,0 +1,298 @@ +ChangeLog + +2007-05-17 ekohl + + tools/widl/lex.yy.c + tools/widl/parser.l + tools/widl/typelib.c + +- Update wpp and fix the wpp_find_include issue! + + +2006-07-30 ekohl + +- Synchronized with WINE widl 20060729. + + The only difference is one call to wpp_find_include in parser.l. + We'll need to fix this issue! + + +2006-02-27 ekohl + + tools/widl/client.c + tools/widl/server.c + +- Dereference type declarations properly. + +2006-02-27 ekohl + + tools/widl/client.c + tools/widl/server.c + +- Move proc string offset calculation to a separate function. +- Replace all __FUNCTION__ by __FILE__. + +2006-01-01 ekohl + + tools/widl/client.c + tools/widl/server.c + +- Generate static MIDL_PROC_FORMAT_STRING, MIDL_TYPE_FORMAT_STRING and + MIDL_STUB_DESC variables. + +2005-12-05 ekohl + + tools/widl/widl.c + tools/widl/widl.man + +- Change oldnames option from '-o' to '--oldnames'. + +2005-11-26 ekohl + + tools/widl/client.c + tools/widl/server.c + +- Allocate another 4 bytes for unique pointers to simple types. + +2005-10-16 ekohl + + tools/widl/client.c + tools/widl/server.c + +- Fix [out, size_is, unique] parameter issues. + +2005-10-09 ekohl + + tools/widl/client.c + tools/widl/server.c + +- Support [out, unique] base type parameters. + +2005-08-07 ekohl + + tools/widl/server.c + +- Support size_is(*Length) attributes for strings. + +2005-07-30 ekohl + + tools/widl/client.c + tools/widl/server.c + +- Support conformant arrays as in and out parameters. +- Fix message buffer size calculation for client and server. + +2005-07-25 ekohl + + tools/widl/client.c + tools/widl/lex.yy.c + tools/widl/parser.y + tools/widl/proxy.c + tools/widl/server.c + tools/widl/y.tab.c + tools/widl/y.tab.h + +- Fix grammar of the size_is attribute so that size_is(*Length) gets accepted. + +2005-07-23 ekohl + + tools/widl/client.c + tools/widl/server.c + +- Fix offset calculation bug in the ProcFormatString. +- Fix offset calculation bug in the marshalling and unmarshalling code. +- Fix typos in the TypeFormatString. +This makes the [string, out, size_is()] parameters work properly. + +2005-07-17 ekohl + + tools/widl/client.c + tools/widl/server.c + +Fix bugs for in-string parameters. +Implement out-string parameters (untested). + +2005-05-08 weiden + + tools/widl/server.c + +Don't generate lvalue assignment code. + +2005-05-08 weiden + + tools/widl/client.c + tools/widl/proxy.c + tools/widl/server.c + +Generate code GCC4.x accepts. + +2005-04-18 navaraf + + tools/widl/parser.y + +Don't use pointer to freed memory. + +2005-04-17 ekohl + + tools/widl/server.c + +Support out-pointers to structs. + +2005-04-15 ekohl + + tools/widl/client.c + tools/widl/parser.y + tools/widl/server.c + +Support in-pointers to structs. + +2005-04-03 ekohl + + tools/widl/client.c + tools/widl/parser.l + tools/widl/parser.y + tools/widl/server.c + tools/widl/widltypes.h + +Support 'ref' and 'unique' attributes for pointers. + +2005-03-27 Jacek Caban (from WINE) + + tools/widl/parser.y + tools/widl/y.tab.c + +Added handling of unsigned type + +2005-03-25 ekohl + + tools/widl/client.c + tools/widl/server.c + +Generate code without L-value casts. Fix remaining issues. + +2005-03-21 navaraf + + tools/widl/client.c + +Fix a typo in write_function_stubs. + +2005-03-20 navaraf + + tools/widl/client.c + tools/widl/server.c + +Generate code without L-value casts. + +2005-03-20 ekohl + + tools/widl/client.c + tools/widl/server.c + +Improve error messages. +Don't start counting the type_offset for each new fuction. It is a global offset. +Use only basic types in type- and proc-strings (e.g. unsigned long -> long). + + +2005-03-13 ekohl + + tools/widl/server.c + +Remove debug printf(). + + +2005-03-13 jimtabor + + tools/widl/write_msft.c + +Fixup *nix port, added include fcntl.h and unistd.h. + + +2005-03-13 royce3 + + tools/widl/hash.c + tools/widl/Makefile + tools/widl/write_msft.c + +-Wall -Werror and fix warnings + + +2005-03-13 ekohl + + tools/widl/client.c + tools/widl/server.c + +Implement [string] attribute for pointers to char and wchar_t. + + +2005-03-12 ekohl + + tools/widl/client.c + tools/widl/server.c + +Implement [in], [out] and [in, out] support for pointers to basic types. + + +2005-03-10 ekohl + + tools/widl/client.c + tools/widl/header.c + tools/widl/server.c + tools/widl/widl.c + tools/widl/widl.h + +Implement '-o' option. This is equivalent to MIDLs '/oldnames' option. + + +2005-03-06 ekohl + + tools/widl/client.c + tools/widl/header.c + tools/widl/header.h + tools/widl/server.c + +Support pointers to simple types as input arguments. + + +2005-02-27 sedwards + + tools/widl/y.tab.c + tools/widl/parser.y + tools/widl/widl.c + tools/widl/widl.h + tools/widl/server.c + tools/widl/typelib.c + +Merge in Winehq changes to reduce noise. + + tools/widl/server.h + tools/widl/client.h + tools/widl/proxy.h + +Deleted unneeded headers. + +2005-02-26 ekohl + tools/widl/server.c + +Server stubs are void functions. +Fix a warning in the server stub descriptor. + + +2005-02-25 ekohl + tools/widl/client.c + tools/widl/header.c + tools/widl/header.h + tools/widl/server.c + +Support multiple interfaces per idl file. +Support explicit binding handles. + + +2005-02-24 ekohl + include/wine/rpcfc.h + tools/widl/client.c + tools/widl/header.c + tools/widl/parser.l + tools/widl/parser.y + tools/widl/server.c + +Support remaining basic types (float, double, small, wchar_t and handle_t). diff --git a/reactos/tools/widl_new/Makefile.in b/reactos/tools/widl_new/Makefile.in new file mode 100644 index 00000000000..e2bd0cc887f --- /dev/null +++ b/reactos/tools/widl_new/Makefile.in @@ -0,0 +1,53 @@ +TOPSRCDIR = @top_srcdir@ +TOPOBJDIR = ../.. +SRCDIR = @srcdir@ +VPATH = @srcdir@ +EXEEXT = @EXEEXT@ + +PROGRAMS = widl$(EXEEXT) +MANPAGES = widl.man +MODULE = none + +C_SRCS = \ + client.c \ + hash.c \ + header.c \ + proxy.c \ + server.c \ + typegen.c \ + typelib.c \ + utils.c \ + widl.c \ + write_msft.c + +EXTRA_SRCS = parser.y parser.l +EXTRA_OBJS = parser.tab.o @LEX_OUTPUT_ROOT@.o + +all: $(PROGRAMS) $(MANPAGES) + +@MAKE_RULES@ + +widl$(EXEEXT): $(OBJS) $(LIBWPP) + $(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBWPP) $(LIBPORT) $(LEXLIB) $(LDFLAGS) + +parser.tab.c parser.tab.h: parser.y + $(BISON) -d -t $(SRCDIR)/parser.y -o parser.tab.c + +# hack to allow parallel make +parser.tab.h: parser.tab.c +parser.tab.o: parser.tab.h + +@LEX_OUTPUT_ROOT@.c: parser.l + $(LEX) $(SRCDIR)/parser.l + +@LEX_OUTPUT_ROOT@.o: parser.tab.h + +install:: $(PROGRAMS) $(MANPAGES) + $(MKINSTALLDIRS) $(DESTDIR)$(bindir) $(DESTDIR)$(mandir)/man$(prog_manext) + $(INSTALL_PROGRAM) widl$(EXEEXT) $(DESTDIR)$(bindir)/widl$(EXEEXT) + $(INSTALL_DATA) widl.man $(DESTDIR)$(mandir)/man$(prog_manext)/widl.$(prog_manext) + +uninstall:: + $(RM) $(DESTDIR)$(bindir)/widl$(EXEEXT) $(DESTDIR)$(mandir)/man$(prog_manext)/widl.$(prog_manext) + +### Dependencies: diff --git a/reactos/tools/widl_new/client.c b/reactos/tools/widl_new/client.c new file mode 100644 index 00000000000..6f8773e3957 --- /dev/null +++ b/reactos/tools/widl_new/client.c @@ -0,0 +1,524 @@ +/* + * IDL Compiler + * + * Copyright 2005-2006 Eric Kohl + * + * 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 +#include +#include +#include +#include +#include +#include + +#include "windef.h" + +#include "widl.h" +#include "utils.h" +#include "parser.h" +#include "header.h" + +#include "widltypes.h" +#include "typelib.h" +#include "typelib_struct.h" +#include "typegen.h" + +static FILE* client; +static int indent = 0; + +static int print_client( const char *format, ... ) +{ + va_list va; + int i, r; + + va_start(va, format); + for (i = 0; i < indent; i++) + fprintf(client, " "); + r = vfprintf(client, format, va); + va_end(va); + return r; +} + + +static void print_message_buffer_size(const func_t *func) +{ + unsigned int total_size = 0; + + if (func->args) + { + const var_t *var = func->args; + while (NEXT_LINK(var)) var = NEXT_LINK(var); + while (var) + { + unsigned int alignment; + + total_size += get_required_buffer_size(var, &alignment, PASS_IN); + total_size += alignment; + + var = PREV_LINK(var); + } + } + fprintf(client, " %u", total_size); +} + +static void check_pointers(const func_t *func) +{ + var_t *var; + int pointer_type; + + if (!func->args) + return; + + var = func->args; + while (NEXT_LINK(var)) var = NEXT_LINK(var); + while (var) + { + pointer_type = get_attrv(var->attrs, ATTR_POINTERTYPE); + if (!pointer_type) + pointer_type = RPC_FC_RP; + + if (pointer_type == RPC_FC_RP) + { + if (var->ptr_level >= 1) + { + print_client("if (!%s)\n", var->name); + print_client("{\n"); + indent++; + print_client("RpcRaiseException(RPC_X_NULL_REF_POINTER);\n"); + indent--; + print_client("}\n\n"); + } + } + + var = PREV_LINK(var); + } +} + +static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsigned int *type_offset) +{ + const func_t *func = iface->funcs; + const char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE); + int explicit_handle = is_attr(iface->attrs, ATTR_EXPLICIT_HANDLE); + var_t *var; + int method_count = 0; + + while (NEXT_LINK(func)) func = NEXT_LINK(func); + while (func) + { + const var_t *def = func->def; + const var_t* explicit_handle_var; + unsigned int type_offset_func; + + /* check for a defined binding handle */ + explicit_handle_var = get_explicit_handle_var(func); + if (explicit_handle) + { + if (!explicit_handle_var) + { + error("%s() does not define an explicit binding handle!\n", def->name); + return; + } + } + else if (implicit_handle) + { + if (explicit_handle_var) + { + error("%s() must not define a binding handle!\n", def->name); + return; + } + } + + write_type(client, def->type, def, def->tname); + fprintf(client, " "); + write_name(client, def); + fprintf(client, "(\n"); + indent++; + if (func->args) + write_args(client, func->args, iface->name, 0, TRUE); + else + print_client("void"); + fprintf(client, ")\n"); + indent--; + + /* write the functions body */ + fprintf(client, "{\n"); + indent++; + + /* declare return value '_RetVal' */ + if (!is_void(def->type, NULL)) + { + print_client(""); + write_type(client, def->type, def, def->tname); + fprintf(client, " _RetVal;\n"); + } + + if (implicit_handle || explicit_handle_var) + print_client("RPC_BINDING_HANDLE _Handle = 0;\n"); + + print_client("RPC_MESSAGE _RpcMessage;\n"); + print_client("MIDL_STUB_MESSAGE _StubMsg;\n"); + fprintf(client, "\n"); + + /* check pointers */ + check_pointers(func); + + print_client("RpcTryFinally\n"); + print_client("{\n"); + indent++; + + print_client("NdrClientInitializeNew(\n"); + indent++; + print_client("(PRPC_MESSAGE)&_RpcMessage,\n"); + print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n"); + print_client("(PMIDL_STUB_DESC)&%s_StubDesc,\n", iface->name); + print_client("%d);\n", method_count); + indent--; + fprintf(client, "\n"); + + if (implicit_handle) + { + print_client("_Handle = %s;\n", implicit_handle); + fprintf(client, "\n"); + } + else if (explicit_handle_var) + { + print_client("_Handle = %s;\n", explicit_handle_var->name); + fprintf(client, "\n"); + } + + /* emit the message buffer size */ + print_client("_StubMsg.BufferLength ="); + print_message_buffer_size(func); + fprintf(client, ";\n"); + + type_offset_func = *type_offset; + write_remoting_arguments(client, indent, func, &type_offset_func, PASS_IN, PHASE_BUFFERSIZE); + + print_client("NdrGetBuffer(\n"); + indent++; + print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n"); + print_client("_StubMsg.BufferLength,\n"); + if (implicit_handle || explicit_handle_var) + print_client("_Handle);\n"); + else + print_client("%s__MIDL_AutoBindHandle);\n", iface->name); + indent--; + fprintf(client, "\n"); + + + /* make a copy so we don't increment the type offset twice */ + type_offset_func = *type_offset; + + /* marshal arguments */ + write_remoting_arguments(client, indent, func, &type_offset_func, PASS_IN, PHASE_MARSHAL); + + /* send/receive message */ + /* print_client("NdrNsSendReceive(\n"); */ + /* print_client("(unsigned char *)_StubMsg.Buffer,\n"); */ + /* print_client("(RPC_BINDING_HANDLE *) &%s__MIDL_AutoBindHandle);\n", iface->name); */ + print_client("NdrSendReceive(\n"); + indent++; + print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n"); + print_client("(unsigned char *)_StubMsg.Buffer);\n\n"); + indent--; + + print_client("_StubMsg.BufferStart = (unsigned char *)_RpcMessage.Buffer;\n"); + print_client("_StubMsg.BufferEnd = _StubMsg.BufferStart + _RpcMessage.BufferLength;\n"); + + if (has_out_arg_or_return(func)) + { + fprintf(client, "\n"); + + print_client("if ((_RpcMessage.DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION)\n"); + indent++; + print_client("NdrConvert(\n"); + indent++; + print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n"); + print_client("(PFORMAT_STRING)&__MIDL_ProcFormatString.Format[%u]);\n", *proc_offset); + indent -= 2; + } + + /* unmarshall arguments */ + fprintf(client, "\n"); + write_remoting_arguments(client, indent, func, type_offset, PASS_OUT, PHASE_UNMARSHAL); + + /* unmarshal return value */ + if (!is_void(def->type, NULL)) + print_phase_basetype(client, indent, PHASE_UNMARSHAL, PASS_RETURN, def, "_RetVal"); + + /* update proc_offset */ + if (func->args) + { + var = func->args; + while (NEXT_LINK(var)) var = NEXT_LINK(var); + while (var) + { + *proc_offset += get_size_procformatstring_var(var); + var = PREV_LINK(var); + } + } + if (!is_void(def->type, NULL)) + *proc_offset += get_size_procformatstring_var(def); + else + *proc_offset += 2; /* FC_END and FC_PAD */ + + indent--; + print_client("}\n"); + print_client("RpcFinally\n"); + print_client("{\n"); + indent++; + + + /* FIXME: emit client finally code */ + + print_client("NdrFreeBuffer((PMIDL_STUB_MESSAGE)&_StubMsg);\n"); + + indent--; + print_client("}\n"); + print_client("RpcEndFinally\n"); + + + /* emit return code */ + if (!is_void(def->type, NULL)) + { + fprintf(client, "\n"); + print_client("return _RetVal;\n"); + } + + indent--; + fprintf(client, "}\n"); + fprintf(client, "\n"); + + method_count++; + func = PREV_LINK(func); + } +} + + +static void write_bindinghandledecl(type_t *iface) +{ + print_client("static RPC_BINDING_HANDLE %s__MIDL_AutoBindHandle;\n", iface->name); + fprintf(client, "\n"); +} + + +static void write_stubdescdecl(type_t *iface) +{ + print_client("static const MIDL_STUB_DESC %s_StubDesc;\n", iface->name); + fprintf(client, "\n"); +} + + +static void write_stubdescriptor(type_t *iface, int expr_eval_routines) +{ + const char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE); + + print_client("static const MIDL_STUB_DESC %s_StubDesc =\n", iface->name); + print_client("{\n"); + indent++; + print_client("(void *)& %s___RpcClientInterface,\n", iface->name); + print_client("MIDL_user_allocate,\n"); + print_client("MIDL_user_free,\n"); + print_client("{\n"); + indent++; + if (implicit_handle) + print_client("&%s,\n", implicit_handle); + else + print_client("&%s__MIDL_AutoBindHandle,\n", iface->name); + indent--; + print_client("},\n"); + print_client("0,\n"); + print_client("0,\n"); + if (expr_eval_routines) + print_client("ExprEvalRoutines,\n"); + else + print_client("0,\n"); + print_client("0,\n"); + print_client("__MIDL_TypeFormatString.Format,\n"); + print_client("1, /* -error bounds_check flag */\n"); + print_client("0x10001, /* Ndr library version */\n"); + print_client("0,\n"); + print_client("0x50100a4, /* MIDL Version 5.1.164 */\n"); + print_client("0,\n"); + print_client("0,\n"); + print_client("0, /* notify & notify_flag routine table */\n"); + print_client("1, /* Flags */\n"); + print_client("0, /* Reserved3 */\n"); + print_client("0, /* Reserved4 */\n"); + print_client("0 /* Reserved5 */\n"); + indent--; + print_client("};\n"); + fprintf(client, "\n"); +} + + +static void write_clientinterfacedecl(type_t *iface) +{ + unsigned long ver = get_attrv(iface->attrs, ATTR_VERSION); + const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID); + + print_client("static const RPC_CLIENT_INTERFACE %s___RpcClientInterface =\n", iface->name ); + print_client("{\n"); + indent++; + print_client("sizeof(RPC_CLIENT_INTERFACE),\n"); + print_client("{{0x%08lx,0x%04x,0x%04x,{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x}},{%d,%d}},\n", + 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], LOWORD(ver), HIWORD(ver)); + print_client("{{0x8a885d04,0x1ceb,0x11c9,{0x9f,0xe8,0x08,0x00,0x2b,0x10,0x48,0x60}},{2,0}},\n"); /* FIXME */ + print_client("0,\n"); + print_client("0,\n"); + print_client("0,\n"); + print_client("0,\n"); + print_client("0,\n"); + print_client("0,\n"); + indent--; + print_client("};\n"); + if (old_names) + print_client("RPC_IF_HANDLE %s_ClientIfHandle = (RPC_IF_HANDLE)& %s___RpcClientInterface;\n", + iface->name, iface->name); + else + print_client("RPC_IF_HANDLE %s_v%d_%d_c_ifspec = (RPC_IF_HANDLE)& %s___RpcClientInterface;\n", + iface->name, LOWORD(ver), HIWORD(ver), iface->name); + fprintf(client, "\n"); +} + + +static void write_formatdesc( const char *str ) +{ + print_client("typedef struct _MIDL_%s_FORMAT_STRING\n", str ); + print_client("{\n"); + indent++; + print_client("short Pad;\n"); + print_client("unsigned char Format[%s_FORMAT_STRING_SIZE];\n", str); + indent--; + print_client("} MIDL_%s_FORMAT_STRING;\n", str); + print_client("\n"); +} + + +static void write_formatstringsdecl(ifref_t *ifaces) +{ + print_client("#define TYPE_FORMAT_STRING_SIZE %d\n", + get_size_typeformatstring(ifaces)); + + print_client("#define PROC_FORMAT_STRING_SIZE %d\n", + get_size_procformatstring(ifaces)); + + fprintf(client, "\n"); + write_formatdesc("TYPE"); + write_formatdesc("PROC"); + fprintf(client, "\n"); + print_client("static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString;\n"); + print_client("static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString;\n"); + print_client("\n"); +} + + +static void write_implicithandledecl(type_t *iface) +{ + const char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE); + + if (implicit_handle) + { + fprintf(client, "handle_t %s;\n", implicit_handle); + fprintf(client, "\n"); + } +} + + +static void init_client(void) +{ + if (client) return; + if (!(client = fopen(client_name, "w"))) + error("Could not open %s for output\n", client_name); + + print_client("/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n", WIDL_FULLVERSION, input_name); + print_client("#include \n"); + print_client("#ifdef _ALPHA_\n"); + print_client("#include \n"); + print_client("#endif\n"); + fprintf(client, "\n"); + print_client("#include \"%s\"\n", header_name); + fprintf(client, "\n"); +} + + +void write_client(ifref_t *ifaces) +{ + unsigned int proc_offset = 0; + unsigned int type_offset = 2; + ifref_t *iface = ifaces; + + if (!do_client) + return; + if (!iface) + return; + END_OF_LIST(iface); + + init_client(); + if (!client) + return; + + write_formatstringsdecl(ifaces); + + for (; iface; iface = PREV_LINK(iface)) + { + if (is_object(iface->iface->attrs) || is_local(iface->iface->attrs)) + continue; + + fprintf(client, "/*****************************************************************************\n"); + fprintf(client, " * %s interface\n", iface->iface->name); + fprintf(client, " */\n"); + fprintf(client, "\n"); + + if (iface->iface->funcs) + { + int expr_eval_routines; + + write_implicithandledecl(iface->iface); + + write_clientinterfacedecl(iface->iface); + write_stubdescdecl(iface->iface); + write_bindinghandledecl(iface->iface); + + write_function_stubs(iface->iface, &proc_offset, &type_offset); + + print_client("#if !defined(__RPC_WIN32__)\n"); + print_client("#error Invalid build platform for this stub.\n"); + print_client("#endif\n"); + + fprintf(client, "\n"); + + expr_eval_routines = write_expr_eval_routines(client, iface->iface->name); + if (expr_eval_routines) + write_expr_eval_routine_list(client, iface->iface->name); + write_stubdescriptor(iface->iface, expr_eval_routines); + } + } + + fprintf(client, "\n"); + + write_procformatstring(client, ifaces); + write_typeformatstring(client, ifaces); + + fclose(client); +} diff --git a/reactos/tools/widl_new/hash.c b/reactos/tools/widl_new/hash.c new file mode 100644 index 00000000000..d67cb6b16a0 --- /dev/null +++ b/reactos/tools/widl_new/hash.c @@ -0,0 +1,621 @@ +/* + * Oleaut32 hash functions + * + * Copyright 1999 Corel Corporation + * Copyright 2001-2003 Jon Griffiths + * + * 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 +#include + +#include "windef.h" +#include "winbase.h" +#include "winnls.h" + +#include "hash.h" + +static const unsigned char Lookup_16[128 * 3] = { + /* Common */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, + 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x00, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, + 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x56, 0x58, 0x55, 0x5A, + 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x56, 0x58, 0x55, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + + /* Windows */ + 0x7F, 0x7F, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x7F, 0x89, 0x53, 0x8B, 0x8C, + 0x7F, 0x7F, 0x7F, 0x7F, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x96, 0x98, 0x99, + 0x53, 0x9B, 0x8C, 0x7F, 0x7F, 0x55, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x96, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, + 0x49, 0x49, 0x44, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0xD7, 0x4F, 0x55, 0x55, + 0x55, 0x55, 0x55, 0xDE, 0xDF, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x43, + 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0x44, 0x4E, 0x4F, 0x4F, 0x4F, + 0x4F, 0x4F, 0xF7, 0x4F, 0x55, 0x55, 0x55, 0x55, 0x55, 0xDE, 0x55, + + /* Mac */ + 0x41, 0x41, 0x43, 0x45, 0x4E, 0x4F, 0x55, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0x4E, 0x4F, 0x4F, 0x4F, + 0x4F, 0x4F, 0x55, 0x55, 0x55, 0x55, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0x41, 0x4F, 0xB0, 0xB1, 0xB2, 0xB3, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0x41, 0x4F, 0xBD, 0x41, 0x4F, 0xC0, + 0xC1, 0xC2, 0xC3, 0x46, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0x41, 0x41, 0x4F, + 0xCE, 0xCE, 0xD0, 0xD0, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0x55, 0x55, 0xDA, + 0xDB, 0xDC, 0xDD, 0x3F, 0x3F, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0x41, 0x45, 0x41, + 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0x4F, 0x4F, 0x3F, 0x4F, 0x55, 0x55, 0x55, + 0x49, 0x7F, 0xF7, 0x7F, 0xF9, 0xFA, 0xFB, 0x3F, 0xFD, 0xFE, 0x7F +}; + +static const unsigned char Lookup_32[128 * 3] = { + /* Common */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, + 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x00, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, + 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, + 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + + /* Windows */ + 0x7F, 0x7F, 0x82, 0x7F, 0x84, 0x85, 0x86, 0x87, 0x7F, 0x89, 0x53, 0x8B, 0x53, + 0x54, 0x5A, 0x5A, 0x7F, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x96, 0x7F, 0x99, + 0x53, 0x9B, 0x53, 0x54, 0x5A, 0x5A, 0xA0, 0x7F, 0xA2, 0x4C, 0xA4, 0x41, 0xA6, + 0xA7, 0xA8, 0xA9, 0x53, 0xAB, 0xAC, 0x96, 0xAE, 0x5A, 0xB0, 0xB1, 0xB2, 0x4C, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x41, 0x53, 0xBB, 0x4C, 0xBD, 0x4C, 0x5A, 0x52, + 0x41, 0x41, 0x41, 0x41, 0x4C, 0x43, 0x43, 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, + 0x49, 0x44, 0xD0, 0x4E, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0xD7, 0x52, 0x55, 0x55, + 0x55, 0x55, 0x59, 0x54, 0xDF, 0x52, 0x41, 0x41, 0x41, 0x41, 0x4C, 0x43, 0x43, + 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x44, 0xD0, 0x4E, 0x4E, 0x4F, 0x4F, + 0x4F, 0x4F, 0xF7, 0x52, 0x55, 0x55, 0x55, 0x55, 0x59, 0x54, 0xFF, + + /* Mac */ + 0x41, 0x41, 0x41, 0x45, 0x41, 0x4F, 0x55, 0x41, 0x41, 0x43, 0x41, 0x43, 0x43, + 0x43, 0x45, 0x5A, 0x5A, 0x44, 0x49, 0x44, 0x45, 0x45, 0x45, 0x4F, 0x45, 0x4F, + 0x4F, 0x4F, 0x55, 0x45, 0x45, 0x55, 0xA0, 0xA1, 0x45, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0xAA, 0x45, 0xAC, 0xAD, 0x47, 0x49, 0x49, 0x49, 0xB2, 0xB3, + 0x49, 0x4B, 0xB6, 0xB7, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4E, 0x4E, + 0x4E, 0xC2, 0xC3, 0x4E, 0x4E, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0x4E, 0x4F, 0x4F, + 0x4F, 0x4F, 0xD0, 0xD0, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0x4F, 0x52, 0x52, + 0x52, 0xDC, 0xDD, 0x52, 0x52, 0x52, 0x53, 0xE2, 0xE3, 0x53, 0x53, 0x53, 0x41, + 0x54, 0x54, 0x49, 0x5A, 0x5A, 0x55, 0x4F, 0x4F, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x59, 0x59, 0x4B, 0x5A, 0x4C, 0x4C, 0x47, 0xFF +}; + +static const unsigned char Lookup_48[128 * 3] = { + /* Common */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, + 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x00, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, + 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, + 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + + /* Windows */ + 0x7F, 0x7F, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x7F, 0x89, 0x53, 0x8B, 0x8C, + 0x7F, 0x7F, 0x7F, 0x7F, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x96, 0x98, 0x99, + 0x53, 0x9B, 0x8C, 0x7F, 0x7F, 0x59, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x96, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0xC6, 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, + 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0xD7, 0x4F, 0x55, 0x55, + 0x55, 0x55, 0x59, 0xDE, 0xDF, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0xC6, 0x43, + 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0x4F, 0x4F, + 0x4F, 0x4F, 0xF7, 0x4F, 0x55, 0x55, 0x55, 0x55, 0x59, 0xDE, 0x59, + + /* Mac */ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, + 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, + 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAB, 0xAD, 0xAE, 0xAE, 0xB0, 0xB1, 0xB2, 0xB3, + 0xA7, 0xB5, 0xB6, 0xB7, 0xB8, 0xB8, 0xBA, 0xBA, 0xBC, 0xBC, 0xBE, 0xBE, 0xB7, + 0xC1, 0xC2, 0xC3, 0x46, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCB, 0xCD, + 0xCD, 0xC1, 0xD0, 0xD0, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD8, 0xDA, + 0xDA, 0xDC, 0xDD, 0xDD, 0x9F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, + 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F +}; + +static const unsigned char Lookup_64[128 * 3] = { + /* Common */ + 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x00, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, + 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x56, 0x58, 0x55, 0x5A, + 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x56, 0x58, 0x55, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + +/* Windows */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x96, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, + 0x49, 0x49, 0x44, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0xD7, 0x4F, 0x55, 0x55, + 0x55, 0x55, 0x55, 0xDE, 0xDF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* Mac */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x96, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, + 0x49, 0x49, 0x44, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0xD7, 0x4F, 0x55, 0x55, + 0x55, 0x55, 0x55, 0xDE, 0xDF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +static const unsigned char Lookup_80[128 * 3] = { + /* Common */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, + 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x00, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, + 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x56, 0x58, 0x55, 0x5A, + 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x56, 0x58, 0x55, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + +/* Windows */ + 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, + + /* Mac */ + 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, +}; + +static const unsigned char Lookup_112[128 * 3] = { + /* Common */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, + 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x00, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, + 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x56, 0x58, 0x55, 0x5A, + 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x56, 0x58, 0x55, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + +/* Windows */ + 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, + + /* Mac */ + 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, +}; + +static const unsigned char Lookup_128[128 * 3] = { + /* Common */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, + 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, + 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, + 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x00, + +/* Windows */ + 0x00, 0x00, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x00, 0x89, 0x00, 0x8B, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x91, 0x92, 0x93, 0x94, 0x95, 0x2D, 0x2D, 0x00, 0x99, + 0x00, 0x9B, 0x00, 0x00, 0x00, 0x00, 0x09, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0x00, 0xAB, 0xAC, 0x2D, 0xAE, 0x2D, 0xB0, 0xB1, 0x32, 0x33, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xBA, + 0xA2, 0xC2, 0xC3, 0xC4, 0xB8, 0xC6, 0xB9, 0xC8, 0xBA, 0xCA, 0xCB, 0xCC, 0xCD, + 0xCE, 0xBC, 0xD0, 0xD1, 0x00, 0xD3, 0xD4, 0xBE, 0xD6, 0xD7, 0xD8, 0xBF, 0xBA, + 0xBE, 0xA2, 0xB8, 0xB9, 0xBA, 0xBE, 0xA2, 0xC2, 0xC3, 0xC4, 0xB8, 0xC6, 0xB9, + 0xC8, 0xBA, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xBC, 0xD0, 0xD1, 0xD3, 0xD3, 0xD4, + 0xBE, 0xD6, 0xD7, 0xD8, 0xBF, 0xBA, 0xBE, 0xBC, 0xBE, 0xBF, 0x00, + + /* Mac */ + 0x41, 0x31, 0x32, 0x45, 0x33, 0x4F, 0x55, 0x87, 0x41, 0x41, 0x41, 0x00, 0x8C, + 0x43, 0x45, 0x45, 0x45, 0x45, 0x92, 0x93, 0x49, 0x49, 0x96, 0x97, 0x98, 0x4F, + 0x4F, 0x9B, 0x3F, 0x55, 0x55, 0x55, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xAB, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xB0, + 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0x09, 0xBD, 0xCC, 0xB0, + 0xB6, 0xCF, 0x2D, 0x2D, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xB8, 0xAB, 0xC3, 0xBD, + 0xB6, 0xB8, 0xAB, 0xC3, 0xBF, 0xBD, 0xB0, 0xB5, 0xBE, 0xA2, 0xB6, 0xBC, 0xA1, + 0xB8, 0xAB, 0xA5, 0xBA, 0xA4, 0xBB, 0xC1, 0xC3, 0xA6, 0xBF, 0xC4, 0xAA, 0xC6, + 0xA3, 0xBF, 0xAA, 0xCC, 0xBD, 0xB7, 0xAB, 0xBD, 0xAB, 0xBD, 0x3F, +}; + +static const unsigned char Lookup_144[128 * 3] = { + /* Common */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, + 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, + 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, + 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x00, + +/* Windows */ + 0x00, 0x00, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x00, 0x89, 0x53, 0x8B, 0x8C, + 0x00, 0x00, 0x00, 0x00, 0x91, 0x92, 0x93, 0x94, 0x95, 0x2D, 0x2D, 0x98, 0x99, + 0x53, 0x9B, 0x8C, 0x00, 0x00, 0x59, 0x09, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x2D, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, + 0xC1, 0x41, 0x41, 0x41, 0x41, 0xC6, 0x43, 0x45, 0xC9, 0x45, 0x45, 0x49, 0xCD, + 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0xD3, 0x4F, 0x4F, 0xD6, 0xD7, 0xD6, 0x55, 0xDA, + 0x55, 0x55, 0xDD, 0xDE, 0xDF, 0x41, 0xC1, 0x41, 0x41, 0x41, 0x41, 0xC6, 0x43, + 0x45, 0xC9, 0x45, 0x45, 0x49, 0xCD, 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0xD3, 0x4F, + 0x4F, 0xD6, 0xF7, 0xD6, 0x55, 0xDA, 0x55, 0x55, 0xDD, 0xDE, 0x59, + + /* Mac */ + 0x00, 0x00, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x00, 0x89, 0x53, 0x8B, 0x8C, + 0x00, 0x00, 0x00, 0x00, 0x91, 0x92, 0x93, 0x94, 0x95, 0x2D, 0x2D, 0x98, 0x99, + 0x53, 0x9B, 0x8C, 0x00, 0x00, 0x59, 0x09, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x2D, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, + 0xC1, 0x41, 0x41, 0x41, 0x41, 0xC6, 0x43, 0x45, 0xC9, 0x45, 0x45, 0x49, 0xCD, + 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0xD3, 0x4F, 0x4F, 0xD6, 0xD7, 0xD6, 0x55, 0xDA, + 0x55, 0x55, 0xDD, 0xDE, 0xDF, 0x41, 0xC1, 0x41, 0x41, 0x41, 0x41, 0xC6, 0x43, + 0x45, 0xC9, 0x45, 0x45, 0x49, 0xCD, 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0xD3, 0x4F, + 0x4F, 0xD6, 0xF7, 0xD6, 0x55, 0xDA, 0x55, 0x55, 0xDD, 0xDE, 0x59, +}; + +static const unsigned char Lookup_160[128 * 3] = { + /* Common */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, + 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, + 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, + 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x00, + +/* Windows */ + 0x00, 0x00, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x00, 0x89, 0x53, 0x8B, 0x8C, + 0x00, 0x00, 0x00, 0x00, 0x91, 0x92, 0x93, 0x94, 0x95, 0x2D, 0x2D, 0x98, 0x99, + 0x53, 0x9B, 0x8C, 0x00, 0x00, 0x59, 0x09, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x2D, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0xC6, 0xC7, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, + 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0xD6, 0xD7, 0x4F, 0x55, 0x55, + 0x55, 0xDC, 0xDD, 0xDE, 0xDF, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0xC6, 0xC7, + 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0x4F, 0x4F, + 0x4F, 0xD6, 0xF7, 0x4F, 0x55, 0x55, 0x55, 0xDC, 0xDD, 0xDE, 0x59, + + /* Mac */ + 0x00, 0x00, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x00, 0x89, 0x53, 0x8B, 0x8C, + 0x00, 0x00, 0x00, 0x00, 0x91, 0x92, 0x93, 0x94, 0x95, 0x2D, 0x2D, 0x98, 0x99, + 0x53, 0x9B, 0x8C, 0x00, 0x00, 0x59, 0x09, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x2D, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0xC6, 0xC7, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, + 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0xD6, 0xD7, 0x4F, 0x55, 0x55, + 0x55, 0xDC, 0xDD, 0xDE, 0xDF, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0xC6, 0xC7, + 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0x4F, 0x4F, + 0x4F, 0xD6, 0xF7, 0x4F, 0x55, 0x55, 0x55, 0xDC, 0xDD, 0xDE, 0x59, +}; + +static const unsigned char Lookup_176[128 * 3] = { + /* Common */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, + 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, + 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, + 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x00, + + /* Windows */ + 0x00, 0x00, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x00, 0x89, 0x53, 0x8B, 0x8C, + 0x00, 0x00, 0x00, 0x00, 0x91, 0x92, 0x93, 0x94, 0x95, 0x2D, 0x2D, 0x98, 0x99, + 0x53, 0x9B, 0x8C, 0x00, 0x00, 0x59, 0x09, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x2D, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, + 0x41, 0x41, 0x41, 0xC4, 0xC5, 0xC4, 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, + 0x49, 0x49, 0x44, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0xD6, 0xD7, 0xD6, 0x55, 0x55, + 0x55, 0x59, 0x59, 0xDE, 0xDF, 0x41, 0x41, 0x41, 0x41, 0xC4, 0xC5, 0xC4, 0x43, + 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0x44, 0x4E, 0x4F, 0x4F, 0x4F, + 0x4F, 0xD6, 0xF7, 0xD6, 0x55, 0x55, 0x55, 0x59, 0x59, 0xDE, 0x59, + + /* Mac */ + 0x80, 0x81, 0x43, 0x45, 0x4E, 0x85, 0x59, 0x41, 0x41, 0x41, 0x80, 0x41, 0x81, + 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0x4E, 0x4F, 0x4F, 0x4F, + 0x85, 0x4F, 0x55, 0x55, 0x55, 0x59, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0x80, 0x85, 0xB0, 0xB1, 0xB2, 0xB3, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0x41, 0x4F, 0xBD, 0x80, 0x85, 0xC0, + 0xC1, 0xC2, 0xC3, 0x46, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0x09, 0x41, 0x41, 0x4F, + 0xCE, 0xCE, 0x2D, 0x2D, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0x59, 0x59, 0xDA, + 0xDB, 0xDC, 0xDD, 0x3F, 0x3F, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0x41, 0x45, 0x41, + 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0x4F, 0x4F, 0x3F, 0x4F, 0x55, 0x55, 0x55, + 0x49, 0x00, 0xF7, 0x00, 0xF9, 0xFA, 0xFB, 0x3F, 0xFD, 0xFE, 0x00 +}; + +static const unsigned char Lookup_208[128 * 3] = { + /* Common */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, + 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, + 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, + 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + +/* Windows */ + 0x80, 0x81, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x5E, 0x89, 0x8A, 0x8B, 0x8C, + 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, + 0x9A, 0x9B, 0x8C, 0x9D, 0x00, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, + 0xC1, 0xC2, 0xC1, 0xC1, 0xC1, 0xC1, 0xC7, 0xC8, 0xC9, 0xC9, 0xCB, 0xCC, 0xCD, + 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, + 0xDB, 0x00, 0xDD, 0xDE, 0xDF, 0x41, 0xE1, 0x41, 0xE3, 0xE4, 0xE5, 0xE6, 0x43, + 0x45, 0x45, 0x45, 0x45, 0xEC, 0xEC, 0x49, 0x49, 0xF0, 0xF1, 0xF2, 0xF3, 0x4F, + 0xF5, 0xF6, 0xF7, 0xF8, 0x55, 0xFA, 0x55, 0x55, 0x00, 0x00, 0xFF, + + /* Mac */ + 0x41, 0x81, 0x43, 0x45, 0x4E, 0x4F, 0x55, 0x41, 0x41, 0x41, 0x41, 0x8B, 0x8C, + 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x93, 0x49, 0x49, 0x4E, 0x4F, 0x98, 0x4F, + 0x4F, 0x9B, 0x55, 0x55, 0x55, 0x55, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, + 0xC1, 0xC2, 0xC1, 0xC1, 0xC1, 0xC1, 0xC7, 0xC8, 0xC9, 0xC9, 0xCB, 0xCC, 0xCD, + 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, + 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0x00, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, + 0xE8, 0xE9, 0xE9, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, + 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, +}; + +static const unsigned char Lookup_224[128 * 3] = { + /* Common */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, + 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, + 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, + 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + +/* Windows */ + 0x80, 0x81, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x5E, 0x89, 0x8A, 0x8B, 0x8C, + 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, + 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, + 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, + 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, + 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, + 0xE8, 0xE9, 0xEA, 0xEA, 0xEC, 0xED, 0xED, 0xEF, 0xEF, 0xF1, 0xF2, 0xF3, 0xF3, + 0xF5, 0xF5, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0x00, 0x00, 0xFF, + + /* Mac */ + 0x41, 0x41, 0x43, 0x45, 0x4E, 0x4F, 0x55, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0x4E, 0x4F, 0x4F, 0x4F, + 0x4F, 0x4F, 0x55, 0x55, 0x55, 0x55, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, + 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, + 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, + 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, + 0xE8, 0xE9, 0xEA, 0xEA, 0xEC, 0xED, 0xED, 0xEF, 0xEF, 0xF1, 0xF2, 0xF3, 0xF3, + 0xF5, 0xF5, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, +}; + +/*********************************************************************** + * lhash_val_of_name_sys + * + * Copy of oleaut32.LHashValOfNameSysA + * Produce a string hash value. + * + * PARAMS + * skind [I] Type of the system. + * lcid [I] Locale id for the hash. + * lpStr [I] String to hash. + * + * RETURNS + * Success: The hash value of the string. + * Failure: 0, if lpStr is NULL. + * + * NOTES + * This function produces a two part hash: The high word is based on + * skind and lcid, while the low word is based on a repeated string + * hash of skind/str. + */ +unsigned long lhash_val_of_name_sys( syskind_t skind, LCID lcid, LPCSTR lpStr) +{ + ULONG nOffset, nMask = skind == SYS_MAC ? 1 : 0; + ULONG nHiWord, nLoWord = 0x0deadbee; + const unsigned char *str = (const unsigned char *)lpStr, *pnLookup = NULL; + + if (!str) + return 0; + + switch (PRIMARYLANGID(LANGIDFROMLCID(lcid))) + { + default: + fprintf(stderr, "Unknown lcid %lx, 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_GAELIC: case LANG_MALTESE: + case LANG_TAJIK: case LANG_ROMANSH: case LANG_IRISH: + case LANG_SAMI: case LANG_UPPER_SORBIAN: case LANG_SUTU: + case LANG_TSONGA: case LANG_TSWANA: case LANG_VENDA: + case LANG_XHOSA: case LANG_ZULU: case LANG_ESPERANTO: + case LANG_WALON: case LANG_CORNISH: case LANG_WELSH: + case LANG_BRETON: + nOffset = 16; + pnLookup = Lookup_16; + break; + case LANG_CZECH: case LANG_HUNGARIAN: case LANG_POLISH: + case LANG_SLOVAK: case LANG_SPANISH: + nOffset = 32; + pnLookup = Lookup_32; + break; + case LANG_HEBREW: + nOffset = 48; + pnLookup = Lookup_48; + break; + case LANG_JAPANESE: + nOffset = 64; + pnLookup = Lookup_64; + break; + case LANG_KOREAN: + nOffset = 80; + pnLookup = Lookup_80; + break; + case LANG_CHINESE: + nOffset = 112; + pnLookup = Lookup_112; + break; + case LANG_GREEK: + nOffset = 128; + pnLookup = Lookup_128; + break; + case LANG_ICELANDIC: + nOffset = 144; + pnLookup = Lookup_144; + break; + case LANG_TURKISH: + nOffset = 160; + pnLookup = Lookup_160; + break; + case LANG_NORWEGIAN: + if (SUBLANGID(LANGIDFROMLCID(lcid)) == SUBLANG_NORWEGIAN_NYNORSK) + { + nOffset = 176; + pnLookup = Lookup_176; + } + else + { + nOffset = 16; + pnLookup = Lookup_16; + } + break; + case LANG_ARABIC: + case LANG_FARSI: + nOffset = 208; + pnLookup = Lookup_208; + break; + case LANG_RUSSIAN: + nOffset = 224; + pnLookup = Lookup_224; + break; + } + + nHiWord = (nOffset | nMask) << 16; + + while (*str) + { + ULONG newLoWord = 0, i; + + /* Cumulative prime multiplication (*37) with modulo 2^32 wrap-around */ + for (i = 0; i < 37; i++) + newLoWord += nLoWord; + + nLoWord = newLoWord + pnLookup[*str > 0x7f && nMask ? *str + 0x80 : *str]; + str++; + } + /* Constrain to a prime modulo and sizeof(WORD) */ + nLoWord = (nLoWord % 65599) & 0xffff; + + return nHiWord | nLoWord; +} diff --git a/reactos/tools/widl_new/hash.h b/reactos/tools/widl_new/hash.h new file mode 100644 index 00000000000..bb787abab83 --- /dev/null +++ b/reactos/tools/widl_new/hash.h @@ -0,0 +1,33 @@ +/* + * Hash definitions + * + * Copyright 2005 Huw Davies + * + * 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 __WIDL_HASH_H +#define __WIDL_HASH_H + +typedef enum tag_syskind_t { + SYS_WIN16 = 0, + SYS_WIN32, + SYS_MAC +} syskind_t; + +extern unsigned long lhash_val_of_name_sys( syskind_t skind, LCID lcid, LPCSTR lpStr); + +#endif diff --git a/reactos/tools/widl_new/header.c b/reactos/tools/widl_new/header.c new file mode 100644 index 00000000000..c807691c594 --- /dev/null +++ b/reactos/tools/widl_new/header.c @@ -0,0 +1,1024 @@ +/* + * IDL Compiler + * + * Copyright 2002 Ove Kaaven + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" + +#include +#include +#ifdef HAVE_UNISTD_H +# include +#endif +#include +#include +#include +#include + +#include "windef.h" +#include "widl.h" +#include "utils.h" +#include "parser.h" +#include "header.h" + +static int indentation = 0; + +static void indent(FILE *h, int delta) +{ + int c; + if (delta < 0) indentation += delta; + for (c=0; c 0) indentation += delta; +} + +int is_attr(const attr_t *a, enum attr_type t) +{ + while (a) { + if (a->type == t) return 1; + a = NEXT_LINK(a); + } + return 0; +} + +void *get_attrp(const attr_t *a, enum attr_type t) +{ + while (a) { + if (a->type == t) return a->u.pval; + a = NEXT_LINK(a); + } + return NULL; +} + +unsigned long get_attrv(const attr_t *a, enum attr_type t) +{ + while (a) { + if (a->type == t) return a->u.ival; + a = NEXT_LINK(a); + } + return 0; +} + +int is_void(const type_t *t, const var_t *v) +{ + if (v && v->ptr_level) return 0; + if (!t->type && !t->ref) return 1; + return 0; +} + +static void write_guid(const char *guid_prefix, const char *name, const UUID *uuid) +{ + if (!uuid) return; + fprintf(header, "DEFINE_GUID(%s_%s, 0x%08lx, 0x%04x, 0x%04x, 0x%02x,0x%02x, 0x%02x," + "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x);\n", + guid_prefix, name, 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]); +} + +static void write_pident(FILE *h, const var_t *v) +{ + int c; + for (c=0; cptr_level; c++) { + fprintf(h, "*"); + } + if (v->name) fprintf(h, "%s", v->name); +} + +void write_name(FILE *h, const var_t *v) +{ + if (is_attr( v->attrs, ATTR_PROPGET )) + fprintf(h, "get_" ); + else if (is_attr( v->attrs, ATTR_PROPPUT )) + fprintf(h, "put_" ); + else if (is_attr( v->attrs, ATTR_PROPPUTREF )) + fprintf(h, "putref_" ); + fprintf(h, "%s", v->name); +} + +const char* get_name(const var_t *v) +{ + return v->name; +} + +void write_array(FILE *h, const expr_t *v, int field) +{ + if (!v) return; + while (NEXT_LINK(v)) v = NEXT_LINK(v); + fprintf(h, "["); + while (v) { + if (v->is_const) + fprintf(h, "%ld", v->cval); /* statically sized array */ + else + if (field) fprintf(h, "1"); /* dynamically sized array */ + if (PREV_LINK(v)) + fprintf(h, ", "); + v = PREV_LINK(v); + } + fprintf(h, "]"); +} + +static void write_field(FILE *h, var_t *v) +{ + if (!v) return; + if (v->type) { + indent(h, 0); + write_type(h, v->type, NULL, v->tname); + if (get_name(v)) { + fprintf(h, " "); + write_pident(h, v); + } + else { + /* not all C/C++ compilers support anonymous structs and unions */ + switch (v->type->type) { + case RPC_FC_STRUCT: + case RPC_FC_CVSTRUCT: + case RPC_FC_CPSTRUCT: + case RPC_FC_CSTRUCT: + case RPC_FC_PSTRUCT: + case RPC_FC_BOGUS_STRUCT: + case RPC_FC_ENCAPSULATED_UNION: + fprintf(h, " DUMMYSTRUCTNAME"); + break; + case RPC_FC_NON_ENCAPSULATED_UNION: + fprintf(h, " DUMMYUNIONNAME"); + break; + default: + /* ? */ + break; + } + } + write_array(h, v->array, 1); + fprintf(h, ";\n"); + } +} + +static void write_fields(FILE *h, var_t *v) +{ + var_t *first = v; + if (!v) return; + while (NEXT_LINK(v)) v = NEXT_LINK(v); + while (v) { + write_field(h, v); + if (v == first) break; + v = PREV_LINK(v); + } +} + +static void write_enums(FILE *h, var_t *v) +{ + if (!v) return; + while (NEXT_LINK(v)) v = NEXT_LINK(v); + while (v) { + if (get_name(v)) { + indent(h, 0); + write_name(h, v); + if (v->eval) { + fprintf(h, " = "); + write_expr(h, v->eval, 0); + } + } + if (PREV_LINK(v)) + fprintf(h, ",\n"); + v = PREV_LINK(v); + } + fprintf(h, "\n"); +} + +void write_type(FILE *h, type_t *t, const var_t *v, const char *n) +{ + int c; + + if (n) fprintf(h, "%s", n); + else { + if (t->is_const) fprintf(h, "const "); + if (t->type) { + if (t->sign > 0) fprintf(h, "signed "); + else if (t->sign < 0) fprintf(h, "unsigned "); + switch (t->type) { + case RPC_FC_BYTE: + if (t->ref) fprintf(h, t->ref->name); + else fprintf(h, "byte"); + break; + case RPC_FC_CHAR: + if (t->ref) fprintf(h, t->ref->name); + else fprintf(h, "char"); + break; + case RPC_FC_WCHAR: + fprintf(h, "WCHAR"); + break; + case RPC_FC_USMALL: + case RPC_FC_SMALL: + if (t->ref) fprintf(h, t->ref->name); + else fprintf(h, "small"); + break; + case RPC_FC_USHORT: + case RPC_FC_SHORT: + if (t->ref) fprintf(h, t->ref->name); + else fprintf(h, "short"); + break; + case RPC_FC_ULONG: + case RPC_FC_LONG: + if (t->ref) fprintf(h, t->ref->name); + else fprintf(h, "long"); + break; + case RPC_FC_HYPER: + if (t->ref) fprintf(h, t->ref->name); + else fprintf(h, "hyper"); + break; + case RPC_FC_FLOAT: + fprintf(h, "float"); + break; + case RPC_FC_DOUBLE: + fprintf(h, "double"); + break; + case RPC_FC_ENUM16: + case RPC_FC_ENUM32: + if (t->defined && !t->written && !t->ignore) { + if (t->name) fprintf(h, "enum %s {\n", t->name); + else fprintf(h, "enum {\n"); + t->written = TRUE; + indentation++; + write_enums(h, t->fields); + indent(h, -1); + fprintf(h, "}"); + } + else fprintf(h, "enum %s", t->name); + break; + case RPC_FC_ERROR_STATUS_T: + if (t->ref) fprintf(h, t->ref->name); + else fprintf(h, "error_status_t"); + break; + case RPC_FC_BIND_PRIMITIVE: + if (t->ref) fprintf(h, t->ref->name); + else fprintf(h, "handle_t"); + break; + case RPC_FC_STRUCT: + case RPC_FC_CVSTRUCT: + case RPC_FC_CPSTRUCT: + case RPC_FC_CSTRUCT: + case RPC_FC_PSTRUCT: + case RPC_FC_BOGUS_STRUCT: + case RPC_FC_ENCAPSULATED_UNION: + if (t->defined && !t->written && !t->ignore) { + if (t->name) fprintf(h, "struct %s {\n", t->name); + else fprintf(h, "struct {\n"); + t->written = TRUE; + indentation++; + write_fields(h, t->fields); + indent(h, -1); + fprintf(h, "}"); + } + else fprintf(h, "struct %s", t->name); + break; + case RPC_FC_NON_ENCAPSULATED_UNION: + if (t->defined && !t->written && !t->ignore) { + if (t->name) fprintf(h, "union %s {\n", t->name); + else fprintf(h, "union {\n"); + t->written = TRUE; + indentation++; + write_fields(h, t->fields); + indent(h, -1); + fprintf(h, "}"); + } + else fprintf(h, "union %s", t->name); + break; + case RPC_FC_FP: + if (t->ref) write_type(h, t->ref, NULL, t->name); + fprintf(h, "*"); + break; + default: + fprintf(h, "(unknown-type:%d)", t->type); + } + } + else { + if (t->ref) { + write_type(h, t->ref, NULL, t->name); + } + else fprintf(h, "void"); + } + } + if (v) { + for (c=0; cptr_level; c++) { + fprintf(h, "*"); + } + } +} + + +struct user_type +{ + struct user_type *next; + char name[1]; +}; + +static struct user_type *user_type_list; + +static int user_type_registered(const char *name) +{ + struct user_type *ut; + for (ut = user_type_list; ut; ut = ut->next) + if (!strcmp(name, ut->name)) + return 1; + return 0; +} + +static void check_for_user_types(const var_t *v) +{ + while (v) { + type_t *type = v->type; + const char *name = v->tname; + for (type = v->type; type; type = type->ref) { + if (type->user_types_registered) continue; + type->user_types_registered = 1; + if (is_attr(type->attrs, ATTR_WIREMARSHAL)) { + if (!user_type_registered(name)) + { + struct user_type *ut = xmalloc(sizeof(struct user_type) + strlen(name)); + strcpy(ut->name, name); + ut->next = user_type_list; + user_type_list = ut; + } + /* don't carry on parsing fields within this type as we are already + * using a wire marshaled type */ + break; + } + else if (type->fields) + { + const var_t *fields = type->fields; + while (NEXT_LINK(fields)) fields = NEXT_LINK(fields); + check_for_user_types(fields); + } + /* the wire_marshal attribute is always at least one reference away + * from the name of the type, so update it after the rest of the + * processing above */ + if (type->name) name = type->name; + } + v = PREV_LINK(v); + } +} + +void write_user_types(void) +{ + struct user_type *ut; + for (ut = user_type_list; ut; ut = ut->next) + { + const char *name = ut->name; + fprintf(header, "unsigned long __RPC_USER %s_UserSize (unsigned long *, unsigned long, %s *);\n", name, name); + fprintf(header, "unsigned char * __RPC_USER %s_UserMarshal (unsigned long *, unsigned char *, %s *);\n", name, name); + fprintf(header, "unsigned char * __RPC_USER %s_UserUnmarshal(unsigned long *, unsigned char *, %s *);\n", name, name); + fprintf(header, "void __RPC_USER %s_UserFree (unsigned long *, %s *);\n", name, name); + } +} + +void write_typedef(type_t *type, const var_t *names) +{ + const char *tname = names->tname; + const var_t *lname; + while (NEXT_LINK(names)) names = NEXT_LINK(names); + lname = names; + fprintf(header, "typedef "); + write_type(header, type, NULL, tname); + fprintf(header, " "); + while (names) { + write_pident(header, names); + if (PREV_LINK(names)) + fprintf(header, ", "); + names = PREV_LINK(names); + } + fprintf(header, ";\n"); +} + +void write_expr(FILE *h, const expr_t *e, int brackets) +{ + switch (e->type) { + case EXPR_VOID: + break; + case EXPR_NUM: + fprintf(h, "%ld", e->u.lval); + break; + case EXPR_HEXNUM: + fprintf(h, "0x%lx", e->u.lval); + break; + case EXPR_TRUEFALSE: + if (e->u.lval == 0) + fprintf(h, "FALSE"); + else + fprintf(h, "TRUE"); + break; + case EXPR_IDENTIFIER: + fprintf(h, "%s", e->u.sval); + break; + case EXPR_NEG: + fprintf(h, "-"); + write_expr(h, e->ref, 1); + break; + case EXPR_NOT: + fprintf(h, "~"); + write_expr(h, e->ref, 1); + break; + case EXPR_PPTR: + fprintf(h, "*"); + write_expr(h, e->ref, 1); + break; + case EXPR_CAST: + fprintf(h, "("); + write_type(h, e->u.tref->ref, NULL, e->u.tref->name); + fprintf(h, ")"); + write_expr(h, e->ref, 1); + break; + case EXPR_SIZEOF: + fprintf(h, "sizeof("); + write_type(h, e->u.tref->ref, NULL, e->u.tref->name); + fprintf(h, ")"); + break; + case EXPR_SHL: + case EXPR_SHR: + case EXPR_MUL: + case EXPR_DIV: + case EXPR_ADD: + case EXPR_SUB: + case EXPR_AND: + case EXPR_OR: + if (brackets) fprintf(h, "("); + write_expr(h, e->ref, 1); + switch (e->type) { + case EXPR_SHL: fprintf(h, " << "); break; + case EXPR_SHR: fprintf(h, " >> "); break; + case EXPR_MUL: fprintf(h, " * "); break; + case EXPR_DIV: fprintf(h, " / "); break; + case EXPR_ADD: fprintf(h, " + "); break; + case EXPR_SUB: fprintf(h, " - "); break; + case EXPR_AND: fprintf(h, " & "); break; + case EXPR_OR: fprintf(h, " | "); break; + default: break; + } + write_expr(h, e->u.ext, 1); + if (brackets) fprintf(h, ")"); + break; + case EXPR_COND: + if (brackets) fprintf(h, "("); + write_expr(h, e->ref, 1); + fprintf(h, " ? "); + write_expr(h, e->u.ext, 1); + fprintf(h, " : "); + write_expr(h, e->ext2, 1); + if (brackets) fprintf(h, ")"); + break; + } +} + +void write_constdef(const var_t *v) +{ + fprintf(header, "#define %s (", get_name(v)); + write_expr(header, v->eval, 0); + fprintf(header, ")\n\n"); +} + +void write_externdef(const var_t *v) +{ + fprintf(header, "extern const "); + write_type(header, v->type, NULL, v->tname); + if (get_name(v)) { + fprintf(header, " "); + write_pident(header, v); + } + fprintf(header, ";\n\n"); +} + +void write_library(const char *name, const attr_t *attr) { + const UUID *uuid = get_attrp(attr, ATTR_UUID); + fprintf(header, "\n"); + write_guid("LIBID", name, uuid); + fprintf(header, "\n"); +} + + +const var_t* get_explicit_handle_var(const func_t* func) +{ + const var_t* var; + + if (!func->args) + return NULL; + + var = func->args; + while (NEXT_LINK(var)) var = NEXT_LINK(var); + while (var) + { + if (var->type->type == RPC_FC_BIND_PRIMITIVE) + return var; + + var = PREV_LINK(var); + } + + return NULL; +} + +int has_out_arg_or_return(const func_t *func) +{ + var_t *var; + + if (!is_void(func->def->type, NULL)) + return 1; + + if (!func->args) + return 0; + + var = func->args; + while (NEXT_LINK(var)) var = NEXT_LINK(var); + while (var) + { + if (is_attr(var->attrs, ATTR_OUT)) + return 1; + + var = PREV_LINK(var); + } + return 0; +} + + +/********** INTERFACES **********/ + +int is_object(const attr_t *a) +{ + while (a) { + if (a->type == ATTR_OBJECT || a->type == ATTR_ODL) return 1; + a = NEXT_LINK(a); + } + return 0; +} + +int is_local(const attr_t *a) +{ + return is_attr(a, ATTR_LOCAL); +} + +const var_t *is_callas(const attr_t *a) +{ + return get_attrp(a, ATTR_CALLAS); +} + +static int write_method_macro(const type_t *iface, const char *name) +{ + int idx; + func_t *cur = iface->funcs; + + if (iface->ref) idx = write_method_macro(iface->ref, name); + else idx = 0; + + if (!cur) return idx; + while (NEXT_LINK(cur)) cur = NEXT_LINK(cur); + + fprintf(header, "/*** %s methods ***/\n", iface->name); + while (cur) { + var_t *def = cur->def; + if (!is_callas(def->attrs)) { + var_t *arg = cur->args; + int argc = 0; + int c; + while (arg) { + arg = NEXT_LINK(arg); + argc++; + } + + fprintf(header, "#define %s_", name); + write_name(header,def); + fprintf(header, "(p"); + for (c=0; clpVtbl->"); + write_name(header, def); + fprintf(header, "(p"); + for (c=0; cidx == -1) cur->idx = idx; + else if (cur->idx != idx) yyerror("BUG: method index mismatch in write_method_macro"); + idx++; + } + cur = PREV_LINK(cur); + } + return idx; +} + +void write_args(FILE *h, var_t *arg, const char *name, int method, int do_indent) +{ + int count = 0; + if (arg) { + while (NEXT_LINK(arg)) + arg = NEXT_LINK(arg); + } + if (do_indent) + { + indentation++; + indent(h, 0); + } + if (method == 1) { + fprintf(h, "%s* This", name); + count++; + } + while (arg) { + if (count) { + if (do_indent) + { + fprintf(h, ",\n"); + indent(h, 0); + } + else fprintf(h, ","); + } + write_type(h, arg->type, arg, arg->tname); + if (arg->args) + { + fprintf(h, " (STDMETHODCALLTYPE *"); + write_name(h,arg); + fprintf(h, ")("); + write_args(h, arg->args, NULL, 0, FALSE); + fprintf(h, ")"); + } + else + { + fprintf(h, " "); + write_name(h, arg); + } + write_array(h, arg->array, 0); + arg = PREV_LINK(arg); + count++; + } + if (do_indent) indentation--; +} + +static void write_cpp_method_def(const type_t *iface) +{ + func_t *cur = iface->funcs; + + if (!cur) return; + while (NEXT_LINK(cur)) cur = NEXT_LINK(cur); + while (cur) { + var_t *def = cur->def; + if (!is_callas(def->attrs)) { + indent(header, 0); + fprintf(header, "virtual "); + write_type(header, def->type, def, def->tname); + fprintf(header, " STDMETHODCALLTYPE "); + write_name(header, def); + fprintf(header, "(\n"); + write_args(header, cur->args, iface->name, 2, TRUE); + fprintf(header, ") = 0;\n"); + fprintf(header, "\n"); + } + cur = PREV_LINK(cur); + } +} + +static void do_write_c_method_def(const type_t *iface, const char *name) +{ + const func_t *cur = iface->funcs; + + if (iface->ref) do_write_c_method_def(iface->ref, name); + + if (!cur) return; + while (NEXT_LINK(cur)) cur = NEXT_LINK(cur); + indent(header, 0); + fprintf(header, "/*** %s methods ***/\n", iface->name); + while (cur) { + const var_t *def = cur->def; + if (!is_callas(def->attrs)) { + indent(header, 0); + write_type(header, def->type, def, def->tname); + fprintf(header, " (STDMETHODCALLTYPE *"); + write_name(header, def); + fprintf(header, ")(\n"); + write_args(header, cur->args, name, 1, TRUE); + fprintf(header, ");\n"); + fprintf(header, "\n"); + } + cur = PREV_LINK(cur); + } +} + +static void write_c_method_def(const type_t *iface) +{ + do_write_c_method_def(iface, iface->name); +} + +static void write_c_disp_method_def(const type_t *iface) +{ + do_write_c_method_def(iface->ref, iface->name); +} + +static void write_method_proto(const type_t *iface) +{ + const func_t *cur = iface->funcs; + + if (!cur) return; + while (NEXT_LINK(cur)) cur = NEXT_LINK(cur); + while (cur) { + const var_t *def = cur->def; + const var_t *cas = is_callas(def->attrs); + const var_t *args; + if (!is_local(def->attrs)) { + /* proxy prototype */ + write_type(header, def->type, def, def->tname); + fprintf(header, " CALLBACK %s_", iface->name); + write_name(header, def); + fprintf(header, "_Proxy(\n"); + write_args(header, cur->args, iface->name, 1, TRUE); + fprintf(header, ");\n"); + /* stub prototype */ + fprintf(header, "void __RPC_STUB %s_", iface->name); + write_name(header,def); + fprintf(header, "_Stub(\n"); + fprintf(header, " IRpcStubBuffer* This,\n"); + fprintf(header, " IRpcChannelBuffer* pRpcChannelBuffer,\n"); + fprintf(header, " PRPC_MESSAGE pRpcMessage,\n"); + fprintf(header, " DWORD* pdwStubPhase);\n"); + + args = cur->args; + if (args) { + while (NEXT_LINK(args)) + args = NEXT_LINK(args); + } + check_for_user_types(args); + } + if (cas) { + const func_t *m = iface->funcs; + while (m && strcmp(get_name(m->def), cas->name)) + m = NEXT_LINK(m); + if (m) { + const var_t *mdef = m->def; + /* proxy prototype - use local prototype */ + write_type(header, mdef->type, mdef, mdef->tname); + fprintf(header, " CALLBACK %s_", iface->name); + write_name(header, mdef); + fprintf(header, "_Proxy(\n"); + write_args(header, m->args, iface->name, 1, TRUE); + fprintf(header, ");\n"); + /* stub prototype - use remotable prototype */ + write_type(header, def->type, def, def->tname); + fprintf(header, " __RPC_STUB %s_", iface->name); + write_name(header, mdef); + fprintf(header, "_Stub(\n"); + write_args(header, cur->args, iface->name, 1, TRUE); + fprintf(header, ");\n"); + } + else { + yywarning("invalid call_as attribute (%s -> %s)\n", get_name(def), cas->name); + } + } + + cur = PREV_LINK(cur); + } +} + +static void write_function_proto(const type_t *iface) +{ + const char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE); + int explicit_handle = is_attr(iface->attrs, ATTR_EXPLICIT_HANDLE); + const var_t* explicit_handle_var; + + func_t *cur = iface->funcs; + while (NEXT_LINK(cur)) cur = NEXT_LINK(cur); + while (cur) { + var_t *def = cur->def; + + /* check for a defined binding handle */ + explicit_handle_var = get_explicit_handle_var(cur); + if (explicit_handle) { + if (!explicit_handle_var) { + error("%s() does not define an explicit binding handle!\n", def->name); + return; + } + } else if (implicit_handle) { + if (explicit_handle_var) { + error("%s() must not define a binding handle!\n", def->name); + return; + } + } + + /* FIXME: do we need to handle call_as? */ + write_type(header, def->type, def, def->tname); + fprintf(header, " "); + write_name(header, def); + fprintf(header, "(\n"); + if (cur->args) + write_args(header, cur->args, iface->name, 0, TRUE); + else + fprintf(header, " void"); + fprintf(header, ");\n"); + + cur = PREV_LINK(cur); + } +} + +void write_forward(type_t *iface) +{ + /* C/C++ forwards should only be written for object interfaces, so if we + * have a full definition we only write one if we find [object] among the + * attributes - however, if we don't have a full definition at this point + * (i.e. this is an IDL forward), then we also assume that it is an object + * interface, since non-object interfaces shouldn't need forwards */ + if ((!iface->defined || is_object(iface->attrs) || is_attr(iface->attrs, ATTR_DISPINTERFACE)) + && !iface->written) { + fprintf(header, "#ifndef __%s_FWD_DEFINED__\n", iface->name); + fprintf(header, "#define __%s_FWD_DEFINED__\n", iface->name); + fprintf(header, "typedef interface %s %s;\n", iface->name, iface->name); + fprintf(header, "#endif\n\n" ); + iface->written = TRUE; + } +} + +static void write_iface_guid(const type_t *iface) +{ + const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID); + write_guid("IID", iface->name, uuid); +} + +static void write_dispiface_guid(const type_t *iface) +{ + const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID); + write_guid("DIID", iface->name, uuid); +} + +static void write_coclass_guid(type_t *cocl) +{ + const UUID *uuid = get_attrp(cocl->attrs, ATTR_UUID); + write_guid("CLSID", cocl->name, uuid); +} + +static void write_com_interface(type_t *iface) +{ + if (!iface->funcs && !iface->ref) { + yywarning("%s has no methods", iface->name); + return; + } + + fprintf(header, "/*****************************************************************************\n"); + fprintf(header, " * %s interface\n", iface->name); + fprintf(header, " */\n"); + fprintf(header,"#ifndef __%s_INTERFACE_DEFINED__\n", iface->name); + fprintf(header,"#define __%s_INTERFACE_DEFINED__\n\n", iface->name); + write_iface_guid(iface); + write_forward(iface); + /* C++ interface */ + fprintf(header, "#if defined(__cplusplus) && !defined(CINTERFACE)\n"); + if (iface->ref) + { + fprintf(header, "interface %s : public %s\n", iface->name, iface->ref->name); + fprintf(header, "{\n"); + indentation++; + write_cpp_method_def(iface); + indentation--; + fprintf(header, "};\n"); + } + else + { + fprintf(header, "interface %s\n", iface->name); + fprintf(header, "{\n"); + fprintf(header, " BEGIN_INTERFACE\n"); + fprintf(header, "\n"); + indentation++; + write_cpp_method_def(iface); + indentation--; + fprintf(header, " END_INTERFACE\n"); + fprintf(header, "};\n"); + } + fprintf(header, "#else\n"); + /* C interface */ + fprintf(header, "typedef struct %sVtbl {\n", iface->name); + indentation++; + fprintf(header, " BEGIN_INTERFACE\n"); + fprintf(header, "\n"); + write_c_method_def(iface); + indentation--; + fprintf(header, " END_INTERFACE\n"); + fprintf(header, "} %sVtbl;\n", iface->name); + fprintf(header, "interface %s {\n", iface->name); + fprintf(header, " const %sVtbl* lpVtbl;\n", iface->name); + fprintf(header, "};\n"); + fprintf(header, "\n"); + fprintf(header, "#ifdef COBJMACROS\n"); + write_method_macro(iface, iface->name); + fprintf(header, "#endif\n"); + fprintf(header, "\n"); + fprintf(header, "#endif\n"); + fprintf(header, "\n"); + write_method_proto(iface); + fprintf(header,"\n#endif /* __%s_INTERFACE_DEFINED__ */\n\n", iface->name); +} + +static void write_rpc_interface(const type_t *iface) +{ + unsigned long ver = get_attrv(iface->attrs, ATTR_VERSION); + const char *var = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE); + static int allocate_written = 0; + + if (!allocate_written) + { + allocate_written = 1; + fprintf(header, "void * __RPC_USER MIDL_user_allocate(size_t);\n"); + fprintf(header, "void __RPC_USER MIDL_user_free(void *);\n\n"); + } + + fprintf(header, "/*****************************************************************************\n"); + fprintf(header, " * %s interface (v%d.%d)\n", iface->name, LOWORD(ver), HIWORD(ver)); + fprintf(header, " */\n"); + fprintf(header,"#ifndef __%s_INTERFACE_DEFINED__\n", iface->name); + fprintf(header,"#define __%s_INTERFACE_DEFINED__\n\n", iface->name); + if (iface->funcs) + { + write_iface_guid(iface); + if (var) fprintf(header, "extern handle_t %s;\n", var); + if (old_names) + { + fprintf(header, "extern RPC_IF_HANDLE %s_ClientIfHandle;\n", iface->name); + fprintf(header, "extern RPC_IF_HANDLE %s_ServerIfHandle;\n", iface->name); + } + else + { + fprintf(header, "extern RPC_IF_HANDLE %s_v%d_%d_c_ifspec;\n", iface->name, LOWORD(ver), HIWORD(ver)); + fprintf(header, "extern RPC_IF_HANDLE %s_v%d_%d_s_ifspec;\n", iface->name, LOWORD(ver), HIWORD(ver)); + } + write_function_proto(iface); + } + fprintf(header,"\n#endif /* __%s_INTERFACE_DEFINED__ */\n\n", iface->name); + + /* FIXME: server/client code */ +} + +void write_interface(type_t *iface) +{ + if (is_object(iface->attrs)) + write_com_interface(iface); + else + write_rpc_interface(iface); +} + +void write_dispinterface(type_t *iface) +{ + fprintf(header, "/*****************************************************************************\n"); + fprintf(header, " * %s dispinterface\n", iface->name); + fprintf(header, " */\n"); + fprintf(header,"#ifndef __%s_DISPINTERFACE_DEFINED__\n", iface->name); + fprintf(header,"#define __%s_DISPINTERFACE_DEFINED__\n\n", iface->name); + write_dispiface_guid(iface); + write_forward(iface); + /* C++ interface */ + fprintf(header, "#if defined(__cplusplus) && !defined(CINTERFACE)\n"); + fprintf(header, "interface %s : public %s\n", iface->name, iface->ref->name); + fprintf(header, "{\n"); + fprintf(header, "};\n"); + fprintf(header, "#else\n"); + /* C interface */ + fprintf(header, "typedef struct %sVtbl {\n", iface->name); + indentation++; + fprintf(header, " BEGIN_INTERFACE\n"); + fprintf(header, "\n"); + write_c_disp_method_def(iface); + indentation--; + fprintf(header, " END_INTERFACE\n"); + fprintf(header, "} %sVtbl;\n", iface->name); + fprintf(header, "interface %s {\n", iface->name); + fprintf(header, " const %sVtbl* lpVtbl;\n", iface->name); + fprintf(header, "};\n"); + fprintf(header, "\n"); + fprintf(header, "#ifdef COBJMACROS\n"); + write_method_macro(iface->ref, iface->name); + fprintf(header, "#endif\n"); + fprintf(header, "\n"); + fprintf(header, "#endif\n"); + fprintf(header, "\n"); + fprintf(header,"#endif /* __%s_DISPINTERFACE_DEFINED__ */\n\n", iface->name); +} + +void write_coclass(type_t *cocl) +{ + fprintf(header, "/*****************************************************************************\n"); + fprintf(header, " * %s coclass\n", cocl->name); + fprintf(header, " */\n\n"); + write_coclass_guid(cocl); + fprintf(header, "\n"); +} + +void write_coclass_forward(type_t *cocl) +{ + fprintf(header, "#ifndef __%s_FWD_DEFINED__\n", cocl->name); + fprintf(header, "#define __%s_FWD_DEFINED__\n", cocl->name); + fprintf(header, "typedef struct %s %s;\n", cocl->name, cocl->name); + fprintf(header, "#endif /* defined __%s_FWD_DEFINED__ */\n\n", cocl->name ); +} diff --git a/reactos/tools/widl_new/header.h b/reactos/tools/widl_new/header.h new file mode 100644 index 00000000000..5863f3b0eff --- /dev/null +++ b/reactos/tools/widl_new/header.h @@ -0,0 +1,62 @@ +/* + * IDL Compiler + * + * Copyright 2002 Ove Kaaven + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __WIDL_HEADER_H +#define __WIDL_HEADER_H + +extern int is_attr(const attr_t *a, enum attr_type t); +extern void *get_attrp(const attr_t *a, enum attr_type t); +extern unsigned long get_attrv(const attr_t *a, enum attr_type t); +extern int is_void(const type_t *t, const var_t *v); +extern void write_name(FILE *h, const var_t *v); +extern const char* get_name(const var_t *v); +extern void write_type(FILE *h, type_t *t, const var_t *v, const char *n); +extern int is_object(const attr_t *a); +extern int is_local(const attr_t *a); +extern const var_t *is_callas(const attr_t *a); +extern void write_args(FILE *h, var_t *arg, const char *name, int obj, int do_indent); +extern void write_array(FILE *h, const expr_t *v, int field); +extern void write_forward(type_t *iface); +extern void write_interface(type_t *iface); +extern void write_dispinterface(type_t *iface); +extern void write_coclass(type_t *cocl); +extern void write_coclass_forward(type_t *cocl); +extern void write_typedef(type_t *type, const var_t *names); +extern void write_expr(FILE *h, const expr_t *e, int brackets); +extern void write_constdef(const var_t *v); +extern void write_externdef(const var_t *v); +extern void write_library(const char *name, const attr_t *attr); +extern void write_user_types(void); +extern const var_t* get_explicit_handle_var(const func_t* func); +extern int has_out_arg_or_return(const func_t *func); + +static inline int is_string_type(const attr_t *attrs, int ptr_level, const expr_t *array) +{ + return (is_attr(attrs, ATTR_STRING) && + ((ptr_level == 1 && !array) || (ptr_level == 0 && array))); +} + +static inline int is_array_type(const attr_t *attrs, int ptr_level, const expr_t *array) +{ + return ((ptr_level == 1 && !array && is_attr(attrs, ATTR_SIZEIS)) || + (ptr_level == 0 && array)); +} + +#endif diff --git a/reactos/tools/widl_new/lex.yy.c b/reactos/tools/widl_new/lex.yy.c new file mode 100644 index 00000000000..c5601a7d0cc --- /dev/null +++ b/reactos/tools/widl_new/lex.yy.c @@ -0,0 +1,5082 @@ +#line 2 "lex.yy.c" +/* A lexical scanner generated by flex */ + +/* Scanner skeleton version: + * $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.91 96/09/10 16:58:48 vern Exp $ + */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 + +#include + + +/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ +#ifdef c_plusplus +#ifndef __cplusplus +#define __cplusplus +#endif +#endif + + +#ifdef __cplusplus + +#include +#include + +/* Use prototypes in function declarations. */ +#define YY_USE_PROTOS + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +#if __STDC__ + +#define YY_USE_PROTOS +#define YY_USE_CONST + +#endif /* __STDC__ */ +#endif /* ! __cplusplus */ + +#ifdef __TURBOC__ + #pragma warn -rch + #pragma warn -use +#include +#include +#define YY_USE_CONST +#define YY_USE_PROTOS +#endif + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + + +#ifdef YY_USE_PROTOS +#define YY_PROTO(proto) proto +#else +#define YY_PROTO(proto) () +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN yy_start = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START ((yy_start - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart( yyin ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#define YY_BUF_SIZE 16384 + +typedef struct yy_buffer_state *YY_BUFFER_STATE; + +extern int yyleng; +extern FILE *yyin, *yyout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + +/* The funky do-while in the following #define is used to turn the definition + * int a single C statement (which needs a semi-colon terminator). This + * avoids problems with code like: + * + * if ( condition_holds ) + * yyless( 5 ); + * else + * do_something_else(); + * + * Prior to using the do-while the compiler would get upset at the + * "else" because it interpreted the "if" statement as being all + * done when it reached the ';' after the yyless() call. + */ + +/* Return all but the first 'n' matched characters back to the input stream. */ + +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + *yy_cp = yy_hold_char; \ + YY_RESTORE_YY_MORE_OFFSET \ + yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, yytext_ptr ) + +/* The following is because we cannot portably get our hands on size_t + * (without autoconf's help, which isn't available because we want + * flex-generated scanners to compile on their own). + */ +typedef unsigned int yy_size_t; + + +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + }; + +static YY_BUFFER_STATE yy_current_buffer = 0; + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + */ +#define YY_CURRENT_BUFFER yy_current_buffer + + +/* yy_hold_char holds the character lost when yytext is formed. */ +static char yy_hold_char; + +static int yy_n_chars; /* number of characters read into yy_ch_buf */ + + +int yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = (char *) 0; +static int yy_init = 1; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void yyrestart YY_PROTO(( FILE *input_file )); + +void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer )); +void yy_load_buffer_state YY_PROTO(( void )); +YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size )); +void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b )); +void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file )); +void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b )); +#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer ) + +YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size )); +YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str )); +YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len )); + +static void *yy_flex_alloc YY_PROTO(( yy_size_t )); +static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t )); +static void yy_flex_free YY_PROTO(( void * )); + +#define yy_new_buffer yy_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! yy_current_buffer ) \ + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ + yy_current_buffer->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! yy_current_buffer ) \ + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ + yy_current_buffer->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (yy_current_buffer->yy_at_bol) + + +#define FLEX_DEBUG +typedef unsigned char YY_CHAR; +FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; +typedef int yy_state_type; + +#define FLEX_DEBUG +extern char *yytext; +#define yytext_ptr yytext +static yyconst short yy_nxt[][256] = + { + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 + }, + + { + 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, + 10, 8, 9, 9, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 9, 8, 11, 8, 8, 8, 8, 8, + + 8, 8, 8, 8, 8, 8, 8, 8, 12, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 8, 8, + 14, 8, 15, 8, 8, 16, 16, 16, 16, 16, + 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 18, 17, 17, 17, 17, 17, 17, + 17, 8, 8, 8, 8, 17, 8, 16, 16, 16, + 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8 + }, + + { + 7, 8, 8, 8, 8, 8, 8, 8, 8, 19, + 10, 8, 19, 19, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 19, 8, 11, 20, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 12, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 8, 8, + 14, 8, 15, 8, 8, 16, 16, 16, 16, 16, + 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, + + 17, 17, 17, 18, 17, 17, 17, 17, 17, 17, + 17, 8, 8, 8, 8, 17, 8, 16, 16, 16, + 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8 + }, + + { + 7, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 22, 21, 21, 21, 21, 21, 21, 21, 21, 21, + + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 23, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 24, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21 + }, + + { + 7, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 22, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 23, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 24, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21 + + }, + + { + 7, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 22, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25 + }, + + { + 7, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 22, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25 + }, + + { + -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, + -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, + -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, + -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, + -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, + -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, + -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, + -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, + + -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, + -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, + -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, + -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, + -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, + -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, + -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, + -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, + -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, + -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, + + -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, + -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, + -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, + -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, + -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, + -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, + -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, + -7, -7, -7, -7, -7, -7 + }, + + { + 7, -8, -8, -8, -8, -8, -8, -8, -8, -8, + -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, + + -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, + -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, + -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, + -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, + -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, + -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, + -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, + -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, + -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, + -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, + + -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, + -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, + -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, + -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, + -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, + -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, + -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, + -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, + -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, + -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, + + -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, + -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, + -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, + -8, -8, -8, -8, -8, -8 + }, + + { + 7, -9, -9, -9, -9, -9, -9, -9, -9, -9, + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, + -9, -9, -9, -9, -9, -9 + + }, + + { + 7, -10, -10, -10, -10, -10, -10, -10, -10, -10, + -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, + -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, + -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, + -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, + -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, + -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, + -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, + -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, + -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, + + -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, + -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, + -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, + -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, + -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, + -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, + -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, + -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, + -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, + -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, + + -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, + -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, + -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, + -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, + -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, + -10, -10, -10, -10, -10, -10 + }, + + { + 7, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11 + }, + + { + 7, -12, -12, -12, -12, -12, -12, -12, -12, -12, + -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, + -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, + -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, + -12, -12, -12, -12, -12, -12, -12, -12, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, -12, -12, + -12, -12, -12, -12, -12, 27, 27, 27, 27, 27, + 27, -12, -12, -12, -12, -12, -12, -12, -12, -12, + + -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, + -12, -12, -12, -12, -12, -12, -12, 27, 27, 27, + 27, 27, 27, -12, -12, -12, -12, -12, -12, -12, + -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, + 28, -12, -12, -12, -12, -12, -12, -12, -12, -12, + -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, + -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, + -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, + -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, + -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, + + -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, + -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, + -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, + -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, + -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, + -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, + -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, + -12, -12, -12, -12, -12, -12 + }, + + { + 7, -13, -13, -13, -13, -13, -13, -13, -13, -13, + -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, + + -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, + -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, + -13, -13, -13, -13, -13, -13, -13, -13, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, -13, -13, + -13, -13, -13, -13, -13, 27, 27, 27, 27, 27, + 27, -13, -13, -13, -13, -13, -13, -13, -13, -13, + -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, + -13, -13, -13, -13, -13, -13, -13, 27, 27, 27, + 27, 27, 27, -13, -13, -13, -13, -13, -13, -13, + -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, + + -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, + -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, + -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, + -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, + -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, + -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, + -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, + -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, + -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, + -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, + + -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, + -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, + -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, + -13, -13, -13, -13, -13, -13 + }, + + { + 7, -14, -14, -14, -14, -14, -14, -14, -14, -14, + -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, + -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, + -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, + -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, + -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, + + 29, -14, -14, -14, -14, -14, -14, -14, -14, -14, + -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, + -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, + -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, + -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, + -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, + -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, + -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, + -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, + -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, + + -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, + -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, + -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, + -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, + -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, + -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, + -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, + -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, + -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, + -14, -14, -14, -14, -14, -14 + + }, + + { + 7, -15, -15, -15, -15, -15, -15, -15, -15, -15, + -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, + -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, + -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, + -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, + -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, + -15, -15, 30, -15, -15, -15, -15, -15, -15, -15, + -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, + -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, + -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, + + -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, + -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, + -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, + -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, + -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, + -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, + -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, + -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, + -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, + -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, + + -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, + -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, + -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, + -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, + -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, + -15, -15, -15, -15, -15, -15 + }, + + { + 7, -16, -16, -16, -16, -16, -16, -16, -16, -16, + -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, + -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, + -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, + + -16, -16, -16, -16, -16, -16, -16, -16, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, -16, -16, + -16, -16, -16, -16, -16, 31, 31, 31, 31, 31, + 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, -16, -16, -16, -16, 32, -16, 31, 31, 31, + 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, -16, -16, -16, -16, -16, -16, -16, + -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, + + -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, + -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, + -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, + -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, + -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, + -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, + -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, + -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, + -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, + -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, + + -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, + -16, -16, -16, -16, -16, -16 + }, + + { + 7, -17, -17, -17, -17, -17, -17, -17, -17, -17, + -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, + -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, + -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, + -17, -17, -17, -17, -17, -17, -17, -17, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, -17, -17, + -17, -17, -17, -17, -17, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, -17, -17, -17, -17, 32, -17, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, -17, -17, -17, -17, -17, -17, -17, + -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, + -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, + -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, + -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, + -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, + + -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, + -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, + -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, + -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, + -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, + -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, + -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, + -17, -17, -17, -17, -17, -17 + }, + + { + 7, -18, -18, -18, -18, -18, -18, -18, -18, -18, + -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, + + -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, + -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, + -18, -18, -18, -18, -18, -18, -18, -18, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, -18, -18, + -18, -18, -18, -18, -18, 33, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, -18, -18, -18, -18, 32, -18, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + + 32, 32, 32, -18, -18, -18, -18, -18, -18, -18, + -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, + -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, + -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, + -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, + -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, + -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, + -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, + -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, + -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, + + -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, + -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, + -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, + -18, -18, -18, -18, -18, -18 + }, + + { + 7, -19, -19, -19, -19, -19, -19, -19, -19, 34, + -19, -19, 34, 34, -19, -19, -19, -19, -19, -19, + -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, + -19, -19, 34, -19, -19, 35, -19, -19, -19, -19, + -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, + -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, + + -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, + -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, + -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, + -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, + -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, + -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, + -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, + -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, + -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, + -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, + + -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, + -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, + -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, + -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, + -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, + -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, + -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, + -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, + -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, + -19, -19, -19, -19, -19, -19 + + }, + + { + 7, -20, -20, -20, -20, -20, -20, -20, -20, 36, + -20, -20, 36, 36, -20, -20, -20, -20, -20, -20, + -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, + -20, -20, 36, -20, -20, -20, -20, -20, -20, -20, + -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, + -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, + -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, + -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, + -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, + -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, + + -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, + -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, + -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, + -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, + -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, + -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, + -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, + -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, + -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, + -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, + + -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, + -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, + -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, + -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, + -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, + -20, -20, -20, -20, -20, -20 + }, + + { + 7, -21, -21, -21, -21, -21, -21, -21, -21, -21, + -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, + -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, + -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, + + -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, + -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, + -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, + -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, + -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, + -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, + -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, + -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, + -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, + -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, + + -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, + -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, + -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, + -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, + -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, + -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, + -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, + -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, + -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, + -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, + + -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, + -21, -21, -21, -21, -21, -21 + }, + + { + 7, -22, -22, -22, -22, -22, -22, -22, -22, -22, + -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, + -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, + -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, + -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, + -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, + -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, + -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, + + -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, + -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, + -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, + -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, + -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, + -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, + -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, + -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, + -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, + -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, + + -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, + -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, + -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, + -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, + -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, + -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, + -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, + -22, -22, -22, -22, -22, -22 + }, + + { + 7, -23, -23, -23, -23, -23, -23, -23, -23, -23, + -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, + + -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, + -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, + -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, + -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, + -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, + -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, + -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, + -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, + -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, + -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, + + -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, + -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, + -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, + -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, + -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, + -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, + -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, + -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, + -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, + -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, + + -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, + -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, + -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, + -23, -23, -23, -23, -23, -23 + }, + + { + 7, 37, 37, 37, 37, 37, 37, 37, 37, 37, + -24, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 38, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 39, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37 + + }, + + { + 7, 40, 40, 40, 40, 40, 40, 40, 40, 40, + -25, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40 + }, + + { + 7, -26, -26, -26, -26, -26, -26, -26, -26, -26, + -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, + -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, + -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, + + -26, -26, -26, -26, -26, -26, -26, -26, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, -26, -26, + -26, -26, -26, -26, -26, 42, 42, 42, 42, 42, + 42, -26, -26, -26, -26, -26, -26, -26, -26, -26, + -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, + -26, -26, -26, -26, -26, -26, -26, 42, 42, 42, + 42, 42, 42, -26, -26, -26, -26, -26, -26, -26, + -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, + -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, + -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, + + -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, + -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, + -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, + -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, + -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, + -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, + -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, + -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, + -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, + -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, + + -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, + -26, -26, -26, -26, -26, -26 + }, + + { + 7, -27, -27, -27, -27, -27, -27, -27, -27, -27, + -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, + -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, + -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, + -27, -27, -27, -27, -27, -27, -27, -27, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, -27, -27, + -27, -27, -27, -27, -27, 42, 42, 42, 42, 42, + 42, -27, -27, -27, -27, -27, -27, -27, -27, -27, + + -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, + -27, -27, -27, -27, -27, -27, -27, 42, 42, 42, + 42, 42, 42, -27, -27, -27, -27, -27, -27, -27, + -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, + -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, + -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, + -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, + -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, + -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, + -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, + + -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, + -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, + -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, + -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, + -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, + -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, + -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, + -27, -27, -27, -27, -27, -27 + }, + + { + 7, -28, -28, -28, -28, -28, -28, -28, -28, -28, + -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, + + -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, + -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, + -28, -28, -28, -28, -28, -28, -28, -28, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, -28, -28, + -28, -28, -28, -28, -28, 43, 43, 43, 43, 43, + 43, -28, -28, -28, -28, -28, -28, -28, -28, -28, + -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, + -28, -28, -28, -28, -28, -28, -28, 43, 43, 43, + 43, 43, 43, -28, -28, -28, -28, -28, -28, -28, + -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, + + -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, + -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, + -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, + -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, + -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, + -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, + -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, + -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, + -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, + -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, + + -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, + -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, + -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, + -28, -28, -28, -28, -28, -28 + }, + + { + 7, -29, -29, -29, -29, -29, -29, -29, -29, -29, + -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, + -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, + -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, + -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, + -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, + + -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, + -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, + -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, + -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, + -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, + -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, + -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, + -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, + -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, + -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, + + -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, + -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, + -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, + -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, + -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, + -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, + -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, + -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, + -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, + -29, -29, -29, -29, -29, -29 + + }, + + { + 7, -30, -30, -30, -30, -30, -30, -30, -30, -30, + -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, + -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, + -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, + -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, + -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, + -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, + -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, + -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, + -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, + + -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, + -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, + -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, + -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, + -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, + -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, + -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, + -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, + -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, + -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, + + -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, + -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, + -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, + -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, + -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, + -30, -30, -30, -30, -30, -30 + }, + + { + 7, -31, -31, -31, -31, -31, -31, -31, -31, -31, + -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, + -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, + -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, + + -31, -31, -31, -31, -31, -31, -31, -31, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, -31, -31, + -31, -31, -31, -31, -31, 44, 44, 44, 44, 44, + 44, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, -31, -31, -31, -31, 32, -31, 44, 44, 44, + 44, 44, 44, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, -31, -31, -31, -31, -31, -31, -31, + -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, + + -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, + -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, + -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, + -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, + -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, + -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, + -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, + -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, + -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, + -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, + + -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, + -31, -31, -31, -31, -31, -31 + }, + + { + 7, -32, -32, -32, -32, -32, -32, -32, -32, -32, + -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, + -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, + -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, + -32, -32, -32, -32, -32, -32, -32, -32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, -32, -32, + -32, -32, -32, -32, -32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, -32, -32, -32, -32, 32, -32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, -32, -32, -32, -32, -32, -32, -32, + -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, + -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, + -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, + -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, + -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, + + -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, + -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, + -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, + -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, + -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, + -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, + -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, + -32, -32, -32, -32, -32, -32 + }, + + { + 7, -33, -33, -33, -33, -33, -33, -33, -33, -33, + -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, + + -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, + -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, + -33, -33, -33, -33, -33, -33, -33, -33, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, -33, -33, + -33, -33, -33, -33, -33, 32, 32, 32, 32, 32, + 45, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, -33, -33, -33, -33, 32, -33, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + + 32, 32, 32, -33, -33, -33, -33, -33, -33, -33, + -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, + -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, + -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, + -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, + -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, + -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, + -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, + -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, + -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, + + -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, + -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, + -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, + -33, -33, -33, -33, -33, -33 + }, + + { + 7, -34, -34, -34, -34, -34, -34, -34, -34, 34, + -34, -34, 34, 34, -34, -34, -34, -34, -34, -34, + -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, + -34, -34, 34, -34, -34, 35, -34, -34, -34, -34, + -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, + -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, + + -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, + -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, + -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, + -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, + -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, + -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, + -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, + -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, + -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, + -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, + + -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, + -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, + -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, + -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, + -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, + -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, + -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, + -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, + -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, + -34, -34, -34, -34, -34, -34 + + }, + + { + 7, -35, -35, -35, -35, -35, -35, -35, -35, 36, + -35, -35, 36, 36, -35, -35, -35, -35, -35, -35, + -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, + -35, -35, 36, -35, -35, -35, -35, -35, -35, -35, + -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, + -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, + -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, + -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, + -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, + -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, + + -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, + -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, + -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, + -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, + -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, + -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, + -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, + -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, + -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, + -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, + + -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, + -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, + -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, + -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, + -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, + -35, -35, -35, -35, -35, -35 + }, + + { + 7, -36, -36, -36, -36, -36, -36, -36, -36, 36, + -36, -36, 36, 36, -36, -36, -36, -36, -36, -36, + -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, + -36, -36, 36, -36, -36, -36, -36, -36, -36, -36, + + -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, + -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, + -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, + -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, + -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, + -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, + -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, + -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, + -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, + -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, + + -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, + -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, + -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, + -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, + -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, + -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, + -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, + -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, + -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, + -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, + + -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, + -36, -36, -36, -36, -36, -36 + }, + + { + 7, -37, -37, -37, -37, -37, -37, -37, -37, -37, + -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, + -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, + -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, + -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, + -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, + -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, + -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, + + -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, + -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, + -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, + -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, + -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, + -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, + -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, + -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, + -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, + -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, + + -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, + -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, + -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, + -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, + -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, + -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, + -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, + -37, -37, -37, -37, -37, -37 + }, + + { + 7, -38, -38, -38, -38, -38, -38, -38, -38, -38, + -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, + + -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, + -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, + -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, + -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, + -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, + -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, + -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, + -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, + -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, + -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, + + -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, + -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, + -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, + -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, + -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, + -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, + -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, + -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, + -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, + -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, + + -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, + -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, + -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, + -38, -38, -38, -38, -38, -38 + }, + + { + 7, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39 + + }, + + { + 7, 40, 40, 40, 40, 40, 40, 40, 40, 40, + -40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40 + }, + + { + 7, -41, -41, -41, -41, -41, -41, -41, -41, -41, + -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, + -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, + -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, + + -41, -41, -41, -41, -41, -41, -41, -41, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, -41, -41, + -41, -41, -41, -41, -41, 47, 47, 47, 47, 47, + 47, -41, -41, -41, -41, -41, -41, -41, -41, -41, + -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, + -41, -41, -41, -41, -41, -41, -41, 47, 47, 47, + 47, 47, 47, -41, -41, -41, -41, -41, -41, -41, + -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, + -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, + -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, + + -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, + -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, + -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, + -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, + -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, + -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, + -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, + -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, + -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, + -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, + + -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, + -41, -41, -41, -41, -41, -41 + }, + + { + 7, -42, -42, -42, -42, -42, -42, -42, -42, -42, + -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, + -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, + -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, + -42, -42, -42, -42, -42, -42, -42, -42, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, -42, -42, + -42, -42, -42, -42, -42, 47, 47, 47, 47, 47, + 47, -42, -42, -42, -42, -42, -42, -42, -42, -42, + + -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, + -42, -42, -42, -42, -42, -42, -42, 47, 47, 47, + 47, 47, 47, -42, -42, -42, -42, -42, -42, -42, + -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, + -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, + -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, + -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, + -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, + -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, + -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, + + -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, + -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, + -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, + -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, + -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, + -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, + -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, + -42, -42, -42, -42, -42, -42 + }, + + { + 7, -43, -43, -43, -43, -43, -43, -43, -43, -43, + -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, + + -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, + -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, + -43, -43, -43, -43, -43, -43, -43, -43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, -43, -43, + -43, -43, -43, -43, -43, 43, 43, 43, 43, 43, + 43, -43, -43, -43, -43, -43, -43, -43, -43, -43, + -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, + -43, -43, -43, -43, -43, -43, -43, 43, 43, 43, + 43, 43, 43, -43, -43, -43, -43, -43, -43, -43, + -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, + + -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, + -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, + -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, + -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, + -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, + -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, + -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, + -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, + -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, + -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, + + -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, + -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, + -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, + -43, -43, -43, -43, -43, -43 + }, + + { + 7, -44, -44, -44, -44, -44, -44, -44, -44, -44, + -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, + -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, + -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, + -44, -44, -44, -44, -44, -44, -44, -44, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, -44, -44, + + -44, -44, -44, -44, -44, 48, 48, 48, 48, 48, + 48, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, -44, -44, -44, -44, 32, -44, 48, 48, 48, + 48, 48, 48, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, -44, -44, -44, -44, -44, -44, -44, + -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, + -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, + -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, + + -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, + -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, + -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, + -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, + -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, + -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, + -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, + -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, + -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, + -44, -44, -44, -44, -44, -44 + + }, + + { + 7, -45, -45, -45, -45, -45, -45, -45, -45, -45, + -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, + -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, + -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, + -45, -45, -45, -45, -45, -45, -45, -45, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, -45, -45, + -45, -45, -45, -45, -45, 32, 32, 32, 32, 49, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, -45, -45, -45, -45, 32, -45, 32, 32, 32, + + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, -45, -45, -45, -45, -45, -45, -45, + -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, + -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, + -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, + -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, + -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, + -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, + -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, + + -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, + -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, + -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, + -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, + -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, + -45, -45, -45, -45, -45, -45 + }, + + { + 7, -46, -46, -46, -46, -46, -46, -46, -46, -46, + -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, + -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, + -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, + + -46, -46, -46, -46, -46, -46, -46, -46, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, -46, -46, + -46, -46, -46, -46, -46, 51, 51, 51, 51, 51, + 51, -46, -46, -46, -46, -46, -46, -46, -46, -46, + -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, + -46, -46, -46, -46, -46, -46, -46, 51, 51, 51, + 51, 51, 51, -46, -46, -46, -46, -46, -46, -46, + -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, + -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, + -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, + + -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, + -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, + -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, + -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, + -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, + -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, + -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, + -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, + -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, + -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, + + -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, + -46, -46, -46, -46, -46, -46 + }, + + { + 7, -47, -47, -47, -47, -47, -47, -47, -47, -47, + -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, + -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, + -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, + -47, -47, -47, -47, -47, -47, -47, -47, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, -47, -47, + -47, -47, -47, -47, -47, 51, 51, 51, 51, 51, + 51, -47, -47, -47, -47, -47, -47, -47, -47, -47, + + -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, + -47, -47, -47, -47, -47, -47, -47, 51, 51, 51, + 51, 51, 51, -47, -47, -47, -47, -47, -47, -47, + -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, + -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, + -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, + -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, + -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, + -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, + -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, + + -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, + -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, + -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, + -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, + -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, + -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, + -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, + -47, -47, -47, -47, -47, -47 + }, + + { + 7, -48, -48, -48, -48, -48, -48, -48, -48, -48, + -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, + + -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, + -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, + -48, -48, -48, -48, -48, -48, -48, -48, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, -48, -48, + -48, -48, -48, -48, -48, 52, 52, 52, 52, 52, + 52, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, -48, -48, -48, -48, 32, -48, 52, 52, 52, + 52, 52, 52, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + + 32, 32, 32, -48, -48, -48, -48, -48, -48, -48, + -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, + -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, + -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, + -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, + -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, + -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, + -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, + -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, + -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, + + -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, + -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, + -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, + -48, -48, -48, -48, -48, -48 + }, + + { + 7, -49, -49, -49, -49, -49, -49, -49, -49, -49, + -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, + -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, + -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, + -49, -49, -49, -49, -49, -49, -49, -49, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, -49, -49, + + -49, -49, -49, -49, -49, 53, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, -49, -49, -49, -49, 32, -49, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, -49, -49, -49, -49, -49, -49, -49, + -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, + -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, + -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, + + -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, + -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, + -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, + -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, + -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, + -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, + -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, + -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, + -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, + -49, -49, -49, -49, -49, -49 + + }, + + { + 7, -50, -50, -50, -50, -50, -50, -50, -50, -50, + -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, + -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, + -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, + -50, -50, -50, -50, -50, -50, -50, -50, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, -50, -50, + -50, -50, -50, -50, -50, 55, 55, 55, 55, 55, + 55, -50, -50, -50, -50, -50, -50, -50, -50, -50, + -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, + -50, -50, -50, -50, -50, -50, -50, 55, 55, 55, + + 55, 55, 55, -50, -50, -50, -50, -50, -50, -50, + -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, + -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, + -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, + -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, + -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, + -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, + -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, + -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, + -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, + + -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, + -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, + -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, + -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, + -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, + -50, -50, -50, -50, -50, -50 + }, + + { + 7, -51, -51, -51, -51, -51, -51, -51, -51, -51, + -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, + -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, + -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, + + -51, -51, -51, -51, -51, -51, -51, -51, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, -51, -51, + -51, -51, -51, -51, -51, 55, 55, 55, 55, 55, + 55, -51, -51, -51, -51, -51, -51, -51, -51, -51, + -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, + -51, -51, -51, -51, -51, -51, -51, 55, 55, 55, + 55, 55, 55, -51, -51, -51, -51, -51, -51, -51, + -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, + -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, + -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, + + -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, + -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, + -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, + -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, + -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, + -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, + -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, + -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, + -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, + -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, + + -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, + -51, -51, -51, -51, -51, -51 + }, + + { + 7, -52, -52, -52, -52, -52, -52, -52, -52, -52, + -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, + -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, + -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, + -52, -52, -52, -52, -52, -52, -52, -52, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, -52, -52, + -52, -52, -52, -52, -52, 56, 56, 56, 56, 56, + 56, 32, 32, 32, 32, 32, 32, 32, 32, 32, + + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, -52, -52, -52, -52, 32, -52, 56, 56, 56, + 56, 56, 56, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, -52, -52, -52, -52, -52, -52, -52, + -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, + -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, + -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, + -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, + -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, + + -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, + -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, + -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, + -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, + -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, + -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, + -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, + -52, -52, -52, -52, -52, -52 + }, + + { + 7, -53, -53, -53, -53, -53, -53, -53, -53, -53, + -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, + + -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, + -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, + -53, -53, -53, -53, -53, -53, -53, -53, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, -53, -53, + -53, -53, -53, -53, -53, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 57, 32, 32, 32, 32, 32, 32, 32, + 32, -53, -53, -53, -53, 32, -53, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + + 32, 32, 32, -53, -53, -53, -53, -53, -53, -53, + -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, + -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, + -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, + -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, + -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, + -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, + -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, + -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, + -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, + + -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, + -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, + -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, + -53, -53, -53, -53, -53, -53 + }, + + { + 7, -54, -54, -54, -54, -54, -54, -54, -54, -54, + -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, + -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, + -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, + -54, -54, -54, -54, -54, -54, -54, -54, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, -54, -54, + + -54, -54, -54, -54, -54, 59, 59, 59, 59, 59, + 59, -54, -54, -54, -54, -54, -54, -54, -54, -54, + -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, + -54, -54, -54, -54, -54, -54, -54, 59, 59, 59, + 59, 59, 59, -54, -54, -54, -54, -54, -54, -54, + -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, + -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, + -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, + -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, + -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, + + -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, + -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, + -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, + -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, + -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, + -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, + -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, + -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, + -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, + -54, -54, -54, -54, -54, -54 + + }, + + { + 7, -55, -55, -55, -55, -55, -55, -55, -55, -55, + -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, + -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, + -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, + -55, -55, -55, -55, -55, -55, -55, -55, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, -55, -55, + -55, -55, -55, -55, -55, 59, 59, 59, 59, 59, + 59, -55, -55, -55, -55, -55, -55, -55, -55, -55, + -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, + -55, -55, -55, -55, -55, -55, -55, 59, 59, 59, + + 59, 59, 59, -55, -55, -55, -55, -55, -55, -55, + -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, + -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, + -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, + -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, + -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, + -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, + -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, + -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, + -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, + + -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, + -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, + -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, + -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, + -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, + -55, -55, -55, -55, -55, -55 + }, + + { + 7, -56, -56, -56, -56, -56, -56, -56, -56, -56, + -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, + -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, + -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, + + -56, -56, -56, -56, -56, -56, -56, -56, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, -56, -56, + -56, -56, -56, -56, -56, 60, 60, 60, 60, 60, + 60, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, -56, -56, -56, -56, 32, -56, 60, 60, 60, + 60, 60, 60, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, -56, -56, -56, -56, -56, -56, -56, + -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, + + -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, + -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, + -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, + -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, + -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, + -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, + -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, + -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, + -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, + -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, + + -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, + -56, -56, -56, -56, -56, -56 + }, + + { + 7, -57, -57, -57, -57, -57, -57, -57, -57, -57, + -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, + -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, + -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, + -57, -57, -57, -57, -57, -57, -57, -57, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, -57, -57, + -57, -57, -57, -57, -57, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + + 32, 32, 61, 32, 32, 32, 32, 32, 32, 32, + 32, -57, -57, -57, -57, 32, -57, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, -57, -57, -57, -57, -57, -57, -57, + -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, + -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, + -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, + -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, + -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, + + -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, + -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, + -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, + -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, + -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, + -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, + -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, + -57, -57, -57, -57, -57, -57 + }, + + { + 7, -58, -58, -58, -58, -58, -58, -58, -58, -58, + -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, + + -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, + -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, + -58, -58, -58, -58, -58, -58, -58, -58, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, -58, -58, + -58, -58, -58, -58, -58, 63, 63, 63, 63, 63, + 63, -58, -58, -58, -58, -58, -58, -58, -58, -58, + -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, + -58, -58, -58, -58, -58, -58, -58, 63, 63, 63, + 63, 63, 63, -58, -58, -58, -58, -58, -58, -58, + -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, + + -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, + -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, + -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, + -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, + -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, + -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, + -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, + -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, + -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, + -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, + + -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, + -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, + -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, + -58, -58, -58, -58, -58, -58 + }, + + { + 7, -59, -59, -59, -59, -59, -59, -59, -59, -59, + -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, + -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, + -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, + -59, -59, -59, -59, -59, -59, -59, -59, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, -59, -59, + + -59, -59, -59, -59, -59, 63, 63, 63, 63, 63, + 63, -59, -59, -59, -59, -59, -59, -59, -59, -59, + -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, + -59, -59, -59, -59, -59, -59, -59, 63, 63, 63, + 63, 63, 63, -59, -59, -59, -59, -59, -59, -59, + -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, + -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, + -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, + -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, + -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, + + -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, + -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, + -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, + -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, + -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, + -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, + -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, + -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, + -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, + -59, -59, -59, -59, -59, -59 + + }, + + { + 7, -60, -60, -60, -60, -60, -60, -60, -60, -60, + -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, + -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, + -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, + -60, -60, -60, -60, -60, -60, -60, -60, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, -60, -60, + -60, -60, -60, -60, -60, 64, 64, 64, 64, 64, + 64, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, -60, -60, -60, -60, 32, -60, 64, 64, 64, + + 64, 64, 64, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, -60, -60, -60, -60, -60, -60, -60, + -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, + -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, + -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, + -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, + -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, + -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, + -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, + + -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, + -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, + -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, + -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, + -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, + -60, -60, -60, -60, -60, -60 + }, + + { + 7, -61, -61, -61, -61, -61, -61, -61, -61, -61, + -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, + -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, + -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, + + -61, -61, -61, -61, -61, -61, -61, -61, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, -61, -61, + -61, -61, -61, -61, -61, 65, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, -61, -61, -61, -61, 32, -61, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, -61, -61, -61, -61, -61, -61, -61, + -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, + + -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, + -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, + -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, + -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, + -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, + -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, + -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, + -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, + -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, + -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, + + -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, + -61, -61, -61, -61, -61, -61 + }, + + { + 7, -62, -62, -62, -62, -62, -62, -62, -62, -62, + -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, + -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, + -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, + -62, -62, -62, -62, -62, 66, -62, -62, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, -62, -62, + -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, + -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, + + -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, + -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, + -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, + -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, + -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, + -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, + -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, + -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, + -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, + -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, + + -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, + -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, + -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, + -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, + -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, + -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, + -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, + -62, -62, -62, -62, -62, -62 + }, + + { + 7, -63, -63, -63, -63, -63, -63, -63, -63, -63, + -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, + + -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, + -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, + -63, -63, -63, -63, -63, 66, -63, -63, -63, -63, + -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, + -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, + -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, + -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, + -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, + -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, + -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, + + -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, + -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, + -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, + -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, + -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, + -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, + -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, + -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, + -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, + -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, + + -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, + -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, + -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, + -63, -63, -63, -63, -63, -63 + }, + + { + 7, -64, -64, -64, -64, -64, -64, -64, -64, -64, + -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, + -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, + -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, + -64, -64, -64, -64, -64, 66, -64, -64, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, -64, -64, + + -64, -64, -64, -64, -64, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, -64, -64, -64, -64, 32, -64, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, -64, -64, -64, -64, -64, -64, -64, + -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, + -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, + -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, + + -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, + -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, + -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, + -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, + -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, + -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, + -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, + -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, + -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, + -64, -64, -64, -64, -64, -64 + + }, + + { + 7, -65, -65, -65, -65, -65, -65, -65, -65, -65, + -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, + -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, + -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, + -65, -65, -65, -65, -65, -65, -65, -65, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, -65, -65, + -65, -65, -65, -65, -65, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 68, + 32, -65, -65, -65, -65, 32, -65, 32, 32, 32, + + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, -65, -65, -65, -65, -65, -65, -65, + -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, + -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, + -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, + -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, + -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, + -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, + -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, + + -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, + -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, + -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, + -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, + -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, + -65, -65, -65, -65, -65, -65 + }, + + { + 7, -66, -66, -66, -66, -66, -66, -66, -66, -66, + -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, + -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, + -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, + + -66, -66, -66, -66, -66, -66, -66, -66, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, -66, -66, + -66, -66, -66, -66, -66, 69, 69, 69, 69, 69, + 69, -66, -66, -66, -66, -66, -66, -66, -66, -66, + -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, + -66, -66, -66, -66, -66, -66, -66, 69, 69, 69, + 69, 69, 69, -66, -66, -66, -66, -66, -66, -66, + -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, + -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, + -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, + + -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, + -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, + -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, + -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, + -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, + -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, + -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, + -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, + -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, + -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, + + -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, + -66, -66, -66, -66, -66, -66 + }, + + { + 7, -67, -67, -67, -67, -67, -67, -67, -67, -67, + -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, + -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, + -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, + -67, -67, -67, -67, -67, -67, -67, -67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, -67, -67, + -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, + -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, + + -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, + -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, + -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, + -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, + -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, + -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, + -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, + -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, + -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, + -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, + + -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, + -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, + -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, + -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, + -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, + -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, + -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, + -67, -67, -67, -67, -67, -67 + }, + + { + 7, -68, -68, -68, -68, -68, -68, -68, -68, 70, + -68, -68, 70, 70, -68, -68, -68, -68, -68, -68, + + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, 70, -68, -68, -68, -68, -68, -68, -68, + 71, -68, -68, -68, -68, -68, -68, -68, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, -68, -68, + -68, -68, -68, -68, -68, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, -68, -68, -68, -68, 32, -68, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + + 32, 32, 32, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, + -68, -68, -68, -68, -68, -68 + }, + + { + 7, -69, -69, -69, -69, -69, -69, -69, -69, -69, + -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, + -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, + -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, + -69, -69, -69, -69, -69, -69, -69, -69, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 72, -69, -69, + + -69, -69, -69, -69, -69, 72, 72, 72, 72, 72, + 72, -69, -69, -69, -69, -69, -69, -69, -69, -69, + -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, + -69, -69, -69, -69, -69, -69, -69, 72, 72, 72, + 72, 72, 72, -69, -69, -69, -69, -69, -69, -69, + -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, + -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, + -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, + -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, + -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, + + -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, + -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, + -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, + -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, + -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, + -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, + -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, + -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, + -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, + -69, -69, -69, -69, -69, -69 + + }, + + { + 7, -70, -70, -70, -70, -70, -70, -70, -70, 70, + -70, -70, 70, 70, -70, -70, -70, -70, -70, -70, + -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, + -70, -70, 70, -70, -70, -70, -70, -70, -70, -70, + 71, -70, -70, -70, -70, -70, -70, -70, -70, -70, + -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, + -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, + -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, + -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, + -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, + + -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, + -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, + -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, + -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, + -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, + -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, + -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, + -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, + -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, + -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, + + -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, + -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, + -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, + -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, + -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, + -70, -70, -70, -70, -70, -70 + }, + + { + 7, -71, -71, -71, -71, -71, -71, -71, -71, -71, + -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, + -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, + -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, + + -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, + -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, + -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, + -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, + -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, + -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, + -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, + -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, + -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, + -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, + + -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, + -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, + -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, + -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, + -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, + -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, + -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, + -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, + -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, + -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, + + -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, + -71, -71, -71, -71, -71, -71 + }, + + { + 7, -72, -72, -72, -72, -72, -72, -72, -72, -72, + -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, + -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, + -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, + -72, -72, -72, -72, -72, -72, -72, -72, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, -72, -72, + -72, -72, -72, -72, -72, 73, 73, 73, 73, 73, + 73, -72, -72, -72, -72, -72, -72, -72, -72, -72, + + -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, + -72, -72, -72, -72, -72, -72, -72, 73, 73, 73, + 73, 73, 73, -72, -72, -72, -72, -72, -72, -72, + -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, + -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, + -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, + -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, + -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, + -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, + -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, + + -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, + -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, + -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, + -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, + -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, + -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, + -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, + -72, -72, -72, -72, -72, -72 + }, + + { + 7, -73, -73, -73, -73, -73, -73, -73, -73, -73, + -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, + + -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, + -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, + -73, -73, -73, -73, -73, -73, -73, -73, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, -73, -73, + -73, -73, -73, -73, -73, 74, 74, 74, 74, 74, + 74, -73, -73, -73, -73, -73, -73, -73, -73, -73, + -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, + -73, -73, -73, -73, -73, -73, -73, 74, 74, 74, + 74, 74, 74, -73, -73, -73, -73, -73, -73, -73, + -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, + + -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, + -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, + -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, + -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, + -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, + -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, + -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, + -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, + -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, + -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, + + -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, + -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, + -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, + -73, -73, -73, -73, -73, -73 + }, + + { + 7, -74, -74, -74, -74, -74, -74, -74, -74, -74, + -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, + -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, + -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, + -74, -74, -74, -74, -74, 75, -74, -74, -74, -74, + -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, + + -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, + -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, + -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, + -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, + -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, + -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, + -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, + -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, + -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, + -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, + + -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, + -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, + -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, + -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, + -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, + -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, + -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, + -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, + -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, + -74, -74, -74, -74, -74, -74 + + }, + + { + 7, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, -75, -75, + -75, -75, -75, -75, -75, 76, 76, 76, 76, 76, + 76, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, 76, 76, 76, + + 76, 76, 76, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75 + }, + + { + 7, -76, -76, -76, -76, -76, -76, -76, -76, -76, + -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, + -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, + -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, + + -76, -76, -76, -76, -76, -76, -76, -76, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, -76, -76, + -76, -76, -76, -76, -76, 77, 77, 77, 77, 77, + 77, -76, -76, -76, -76, -76, -76, -76, -76, -76, + -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, + -76, -76, -76, -76, -76, -76, -76, 77, 77, 77, + 77, 77, 77, -76, -76, -76, -76, -76, -76, -76, + -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, + -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, + -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, + + -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, + -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, + -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, + -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, + -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, + -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, + -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, + -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, + -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, + -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, + + -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, + -76, -76, -76, -76, -76, -76 + }, + + { + 7, -77, -77, -77, -77, -77, -77, -77, -77, -77, + -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, + -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, + -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, + -77, -77, -77, -77, -77, -77, -77, -77, 78, 78, + 78, 78, 78, 78, 78, 78, 78, 78, -77, -77, + -77, -77, -77, -77, -77, 78, 78, 78, 78, 78, + 78, -77, -77, -77, -77, -77, -77, -77, -77, -77, + + -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, + -77, -77, -77, -77, -77, -77, -77, 78, 78, 78, + 78, 78, 78, -77, -77, -77, -77, -77, -77, -77, + -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, + -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, + -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, + -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, + -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, + -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, + -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, + + -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, + -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, + -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, + -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, + -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, + -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, + -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, + -77, -77, -77, -77, -77, -77 + }, + + { + 7, -78, -78, -78, -78, -78, -78, -78, -78, -78, + -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, + + -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, + -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, + -78, -78, -78, -78, -78, -78, -78, -78, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, -78, -78, + -78, -78, -78, -78, -78, 79, 79, 79, 79, 79, + 79, -78, -78, -78, -78, -78, -78, -78, -78, -78, + -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, + -78, -78, -78, -78, -78, -78, -78, 79, 79, 79, + 79, 79, 79, -78, -78, -78, -78, -78, -78, -78, + -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, + + -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, + -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, + -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, + -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, + -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, + -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, + -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, + -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, + -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, + -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, + + -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, + -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, + -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, + -78, -78, -78, -78, -78, -78 + }, + + { + 7, -79, -79, -79, -79, -79, -79, -79, -79, -79, + -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, + -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, + -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, + -79, -79, -79, -79, -79, 80, -79, -79, -79, -79, + -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, + + -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, + -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, + -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, + -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, + -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, + -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, + -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, + -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, + -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, + -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, + + -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, + -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, + -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, + -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, + -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, + -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, + -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, + -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, + -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, + -79, -79, -79, -79, -79, -79 + + }, + + { + 7, -80, -80, -80, -80, -80, -80, -80, -80, -80, + -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, + -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, + -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, + -80, -80, -80, -80, -80, -80, -80, -80, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, -80, -80, + -80, -80, -80, -80, -80, 81, 81, 81, 81, 81, + 81, -80, -80, -80, -80, -80, -80, -80, -80, -80, + -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, + -80, -80, -80, -80, -80, -80, -80, 81, 81, 81, + + 81, 81, 81, -80, -80, -80, -80, -80, -80, -80, + -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, + -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, + -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, + -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, + -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, + -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, + -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, + -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, + -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, + + -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, + -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, + -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, + -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, + -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, + -80, -80, -80, -80, -80, -80 + }, + + { + 7, -81, -81, -81, -81, -81, -81, -81, -81, -81, + -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, + -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, + -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, + + -81, -81, -81, -81, -81, -81, -81, -81, 82, 82, + 82, 82, 82, 82, 82, 82, 82, 82, -81, -81, + -81, -81, -81, -81, -81, 82, 82, 82, 82, 82, + 82, -81, -81, -81, -81, -81, -81, -81, -81, -81, + -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, + -81, -81, -81, -81, -81, -81, -81, 82, 82, 82, + 82, 82, 82, -81, -81, -81, -81, -81, -81, -81, + -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, + -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, + -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, + + -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, + -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, + -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, + -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, + -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, + -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, + -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, + -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, + -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, + -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, + + -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, + -81, -81, -81, -81, -81, -81 + }, + + { + 7, -82, -82, -82, -82, -82, -82, -82, -82, -82, + -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, + -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, + -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, + -82, -82, -82, -82, -82, -82, -82, -82, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, -82, -82, + -82, -82, -82, -82, -82, 83, 83, 83, 83, 83, + 83, -82, -82, -82, -82, -82, -82, -82, -82, -82, + + -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, + -82, -82, -82, -82, -82, -82, -82, 83, 83, 83, + 83, 83, 83, -82, -82, -82, -82, -82, -82, -82, + -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, + -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, + -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, + -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, + -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, + -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, + -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, + + -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, + -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, + -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, + -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, + -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, + -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, + -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, + -82, -82, -82, -82, -82, -82 + }, + + { + 7, -83, -83, -83, -83, -83, -83, -83, -83, -83, + -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, + + -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, + -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, + -83, -83, -83, -83, -83, -83, -83, -83, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, -83, -83, + -83, -83, -83, -83, -83, 84, 84, 84, 84, 84, + 84, -83, -83, -83, -83, -83, -83, -83, -83, -83, + -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, + -83, -83, -83, -83, -83, -83, -83, 84, 84, 84, + 84, 84, 84, -83, -83, -83, -83, -83, -83, -83, + -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, + + -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, + -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, + -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, + -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, + -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, + -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, + -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, + -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, + -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, + -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, + + -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, + -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, + -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, + -83, -83, -83, -83, -83, -83 + }, + + { + 7, -84, -84, -84, -84, -84, -84, -84, -84, -84, + -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, + -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, + -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, + -84, -84, -84, -84, -84, 85, -84, -84, -84, -84, + -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, + + -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, + -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, + -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, + -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, + -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, + -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, + -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, + -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, + -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, + -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, + + -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, + -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, + -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, + -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, + -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, + -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, + -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, + -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, + -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, + -84, -84, -84, -84, -84, -84 + + }, + + { + 7, -85, -85, -85, -85, -85, -85, -85, -85, -85, + -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, + -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, + -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, + -85, -85, -85, -85, -85, -85, -85, -85, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, -85, -85, + -85, -85, -85, -85, -85, 86, 86, 86, 86, 86, + 86, -85, -85, -85, -85, -85, -85, -85, -85, -85, + -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, + -85, -85, -85, -85, -85, -85, -85, 86, 86, 86, + + 86, 86, 86, -85, -85, -85, -85, -85, -85, -85, + -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, + -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, + -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, + -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, + -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, + -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, + -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, + -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, + -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, + + -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, + -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, + -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, + -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, + -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, + -85, -85, -85, -85, -85, -85 + }, + + { + 7, -86, -86, -86, -86, -86, -86, -86, -86, -86, + -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, + -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, + -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, + + -86, -86, -86, -86, -86, -86, -86, -86, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, -86, -86, + -86, -86, -86, -86, -86, 87, 87, 87, 87, 87, + 87, -86, -86, -86, -86, -86, -86, -86, -86, -86, + -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, + -86, -86, -86, -86, -86, -86, -86, 87, 87, 87, + 87, 87, 87, -86, -86, -86, -86, -86, -86, -86, + -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, + -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, + -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, + + -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, + -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, + -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, + -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, + -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, + -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, + -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, + -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, + -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, + -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, + + -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, + -86, -86, -86, -86, -86, -86 + }, + + { + 7, -87, -87, -87, -87, -87, -87, -87, -87, -87, + -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, + -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, + -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, + -87, -87, -87, -87, -87, -87, -87, -87, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, -87, -87, + -87, -87, -87, -87, -87, 88, 88, 88, 88, 88, + 88, -87, -87, -87, -87, -87, -87, -87, -87, -87, + + -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, + -87, -87, -87, -87, -87, -87, -87, 88, 88, 88, + 88, 88, 88, -87, -87, -87, -87, -87, -87, -87, + -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, + -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, + -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, + -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, + -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, + -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, + -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, + + -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, + -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, + -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, + -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, + -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, + -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, + -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, + -87, -87, -87, -87, -87, -87 + }, + + { + 7, -88, -88, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, + + -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88, -88, -88, 89, 89, + 89, 89, 89, 89, 89, 89, 89, 89, -88, -88, + -88, -88, -88, -88, -88, 89, 89, 89, 89, 89, + 89, -88, -88, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88, -88, 89, 89, 89, + 89, 89, 89, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, + + -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, + + -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88 + }, + + { + 7, -89, -89, -89, -89, -89, -89, -89, -89, -89, + -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, + -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, + -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, + -89, -89, -89, -89, -89, -89, -89, -89, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, -89, -89, + + -89, -89, -89, -89, -89, 90, 90, 90, 90, 90, + 90, -89, -89, -89, -89, -89, -89, -89, -89, -89, + -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, + -89, -89, -89, -89, -89, -89, -89, 90, 90, 90, + 90, 90, 90, -89, -89, -89, -89, -89, -89, -89, + -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, + -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, + -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, + -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, + -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, + + -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, + -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, + -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, + -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, + -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, + -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, + -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, + -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, + -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, + -89, -89, -89, -89, -89, -89 + + }, + + { + 7, -90, -90, -90, -90, -90, -90, -90, -90, -90, + -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, + -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, + -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, + -90, -90, -90, -90, -90, -90, -90, -90, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, -90, -90, + -90, -90, -90, -90, -90, 91, 91, 91, 91, 91, + 91, -90, -90, -90, -90, -90, -90, -90, -90, -90, + -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, + -90, -90, -90, -90, -90, -90, -90, 91, 91, 91, + + 91, 91, 91, -90, -90, -90, -90, -90, -90, -90, + -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, + -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, + -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, + -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, + -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, + -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, + -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, + -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, + -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, + + -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, + -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, + -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, + -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, + -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, + -90, -90, -90, -90, -90, -90 + }, + + { + 7, -91, -91, -91, -91, -91, -91, -91, -91, -91, + -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, + -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, + -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, + + -91, -91, -91, -91, -91, -91, -91, -91, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, -91, -91, + -91, -91, -91, -91, -91, 92, 92, 92, 92, 92, + 92, -91, -91, -91, -91, -91, -91, -91, -91, -91, + -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, + -91, -91, -91, -91, -91, -91, -91, 92, 92, 92, + 92, 92, 92, -91, -91, -91, -91, -91, -91, -91, + -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, + -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, + -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, + + -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, + -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, + -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, + -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, + -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, + -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, + -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, + -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, + -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, + -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, + + -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, + -91, -91, -91, -91, -91, -91 + }, + + { + 7, -92, -92, -92, -92, -92, -92, -92, -92, -92, + -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, + -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, + -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, + -92, -92, -92, -92, -92, -92, -92, -92, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, -92, -92, + -92, -92, -92, -92, -92, 93, 93, 93, 93, 93, + 93, -92, -92, -92, -92, -92, -92, -92, -92, -92, + + -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, + -92, -92, -92, -92, -92, -92, -92, 93, 93, 93, + 93, 93, 93, -92, -92, -92, -92, -92, -92, -92, + -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, + -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, + -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, + -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, + -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, + -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, + -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, + + -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, + -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, + -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, + -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, + -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, + -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, + -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, + -92, -92, -92, -92, -92, -92 + }, + + { + 7, -93, -93, -93, -93, -93, -93, -93, -93, -93, + -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, + + -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, + -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, + -93, -93, -93, -93, -93, -93, -93, -93, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, -93, -93, + -93, -93, -93, -93, -93, 94, 94, 94, 94, 94, + 94, -93, -93, -93, -93, -93, -93, -93, -93, -93, + -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, + -93, -93, -93, -93, -93, -93, -93, 94, 94, 94, + 94, 94, 94, -93, -93, -93, -93, -93, -93, -93, + -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, + + -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, + -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, + -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, + -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, + -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, + -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, + -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, + -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, + -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, + -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, + + -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, + -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, + -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, + -93, -93, -93, -93, -93, -93 + }, + + { + 7, -94, -94, -94, -94, -94, -94, -94, -94, -94, + -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, + -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, + -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, + -94, -94, -94, -94, -94, -94, -94, -94, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, -94, -94, + + -94, -94, -94, -94, -94, 95, 95, 95, 95, 95, + 95, -94, -94, -94, -94, -94, -94, -94, -94, -94, + -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, + -94, -94, -94, -94, -94, -94, -94, 95, 95, 95, + 95, 95, 95, -94, -94, -94, -94, -94, -94, -94, + -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, + -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, + -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, + -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, + -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, + + -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, + -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, + -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, + -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, + -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, + -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, + -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, + -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, + -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, + -94, -94, -94, -94, -94, -94 + + }, + + { + 7, -95, -95, -95, -95, -95, -95, -95, -95, -95, + -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, + -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, + -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, + -95, -95, -95, -95, -95, -95, -95, -95, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, -95, -95, + -95, -95, -95, -95, -95, 96, 96, 96, 96, 96, + 96, -95, -95, -95, -95, -95, -95, -95, -95, -95, + -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, + -95, -95, -95, -95, -95, -95, -95, 96, 96, 96, + + 96, 96, 96, -95, -95, -95, -95, -95, -95, -95, + -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, + -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, + -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, + -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, + -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, + -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, + -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, + -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, + -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, + + -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, + -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, + -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, + -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, + -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, + -95, -95, -95, -95, -95, -95 + }, + + { + 7, -96, -96, -96, -96, -96, -96, -96, -96, -96, + -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, + -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, + -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, + + -96, -96, -96, -96, -96, -96, -96, -96, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, -96, -96, + -96, -96, -96, -96, -96, 97, 97, 97, 97, 97, + 97, -96, -96, -96, -96, -96, -96, -96, -96, -96, + -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, + -96, -96, -96, -96, -96, -96, -96, 97, 97, 97, + 97, 97, 97, -96, -96, -96, -96, -96, -96, -96, + -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, + -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, + -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, + + -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, + -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, + -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, + -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, + -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, + -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, + -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, + -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, + -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, + -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, + + -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, + -96, -96, -96, -96, -96, -96 + }, + + { + 7, -97, -97, -97, -97, -97, -97, -97, -97, -97, + -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, + -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, + -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, + -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, + -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, + -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, + -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, + + -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, + -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, + -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, + -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, + -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, + -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, + -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, + -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, + -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, + -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, + + -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, + -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, + -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, + -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, + -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, + -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, + -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, + -97, -97, -97, -97, -97, -97 + }, + + } ; + + +static yy_state_type yy_get_previous_state YY_PROTO(( void )); +static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state )); +static int yy_get_next_buffer YY_PROTO(( void )); +static void yy_fatal_error YY_PROTO(( yyconst char msg[] )); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + yytext_ptr = yy_bp; \ + yyleng = (int) (yy_cp - yy_bp); \ + yy_hold_char = *yy_cp; \ + *yy_cp = '\0'; \ + yy_c_buf_p = yy_cp; + +#define YY_NUM_RULES 19 +#define YY_END_OF_BUFFER 20 +static yyconst short int yy_accept[98] = + { 0, + 0, 0, 0, 0, 2, 2, 20, 18, 15, 14, + 3, 11, 11, 18, 18, 13, 13, 13, 15, 1, + 8, 19, 4, 8, 2, 11, 0, 0, 16, 17, + 13, 13, 13, 0, 1, 1, 7, 6, 5, 2, + 11, 0, 10, 13, 13, 11, 0, 13, 13, 11, + 0, 13, 13, 11, 0, 13, 13, 11, 0, 13, + 13, 11, 0, 13, 13, 0, 11, 13, 0, 0, + 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9 + + } ; + +static yy_state_type yy_last_accepting_state; +static char *yy_last_accepting_cpos; + +static yyconst yy_state_type yy_NUL_trans[98] = + { 0, + 8, 8, 21, 21, 25, 25, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 37, 40, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0 + + } ; + +extern int yy_flex_debug; +int yy_flex_debug = 1; + +static yyconst short int yy_rule_linenum[19] = + { 0, + 106, 107, 126, 127, 132, 133, 134, 135, 136, 140, + 144, 148, 149, 150, 151, 152, 153, 154 + } ; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +char *yytext; +#line 1 "parser.l" +#define INITIAL 0 +/* -*-C-*- + * IDL Compiler + * + * Copyright 2002 Ove Kaaven + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ +#define YY_STACK_USED 1 +#define YY_NO_UNPUT 1 +#define YY_NO_TOP_STATE 1 +#define YY_NEVER_INTERACTIVE 1 +#define QUOTE 1 + +#define pp_line 2 + +#line 37 "parser.l" + +#include "config.h" + +#include +#include +#include +#include +#include +#ifdef HAVE_UNISTD_H +# include +#endif + +#include "widl.h" +#include "utils.h" +#include "parser.h" +#include "wine/wpp.h" + +#include "parser.tab.h" + +extern char *temp_name; + +static void addcchar(char c); +static char *get_buffered_cstring(void); + +static char *cbuffer; +static int cbufidx; +static int cbufalloc = 0; + +static int kw_token(const char *kw); + +#define MAX_IMPORT_DEPTH 10 +struct { + YY_BUFFER_STATE state; + char *input_name; + int line_number; + char *temp_name; +} import_stack[MAX_IMPORT_DEPTH]; +int import_stack_ptr = 0; + +static void pop_import(void); + +static UUID* parse_uuid(const char*u) +{ + UUID* uuid = xmalloc(sizeof(UUID)); + char b[3]; + /* it would be nice to use UuidFromStringA */ + uuid->Data1 = strtoul(u, NULL, 16); + uuid->Data2 = strtoul(u+9, NULL, 16); + uuid->Data3 = strtoul(u+14, NULL, 16); + b[2] = 0; + memcpy(b, u+19, 2); uuid->Data4[0] = strtoul(b, NULL, 16); + memcpy(b, u+21, 2); uuid->Data4[1] = strtoul(b, NULL, 16); + memcpy(b, u+24, 2); uuid->Data4[2] = strtoul(b, NULL, 16); + memcpy(b, u+26, 2); uuid->Data4[3] = strtoul(b, NULL, 16); + memcpy(b, u+28, 2); uuid->Data4[4] = strtoul(b, NULL, 16); + memcpy(b, u+30, 2); uuid->Data4[5] = strtoul(b, NULL, 16); + memcpy(b, u+32, 2); uuid->Data4[6] = strtoul(b, NULL, 16); + memcpy(b, u+34, 2); uuid->Data4[7] = strtoul(b, NULL, 16); + return uuid; +} + +/* + ************************************************************************** + * The flexer starts here + ************************************************************************** + */ +#line 3539 "lex.yy.c" + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap YY_PROTO(( void )); +#else +extern int yywrap YY_PROTO(( void )); +#endif +#endif + +#ifndef YY_NO_UNPUT +static void yyunput YY_PROTO(( int c, char *buf_ptr )); +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int )); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen YY_PROTO(( yyconst char * )); +#endif + +#ifndef YY_NO_INPUT +#ifdef __cplusplus +static int yyinput YY_PROTO(( void )); +#else +static int input YY_PROTO(( void )); +#endif +#endif + +#if YY_STACK_USED +static int yy_start_stack_ptr = 0; +static int yy_start_stack_depth = 0; +static int *yy_start_stack = 0; +#ifndef YY_NO_PUSH_STATE +static void yy_push_state YY_PROTO(( int new_state )); +#endif +#ifndef YY_NO_POP_STATE +static void yy_pop_state YY_PROTO(( void )); +#endif +#ifndef YY_NO_TOP_STATE +static int yy_top_state YY_PROTO(( void )); +#endif + +#else +#define YY_NO_PUSH_STATE 1 +#define YY_NO_POP_STATE 1 +#define YY_NO_TOP_STATE 1 +#endif + +#ifdef YY_MALLOC_DECL +YY_MALLOC_DECL +#else +#if __STDC__ +#ifndef __cplusplus +#include +#endif +#else +/* Just try to get by without declaring the routines. This will fail + * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int) + * or sizeof(void*) != sizeof(int). + */ +#endif +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ + +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( yy_current_buffer->yy_is_interactive ) \ + { \ + int c = '*', n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \ + && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL int yylex YY_PROTO(( void )) +#endif + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + if ( yyleng > 0 ) \ + yy_current_buffer->yy_at_bol = \ + (yytext[yyleng - 1] == '\n'); \ + YY_USER_ACTION + +YY_DECL + { + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + +#line 105 "parser.l" + +#line 3695 "lex.yy.c" + + if ( yy_init ) + { + yy_init = 0; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! yy_start ) + yy_start = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! yy_current_buffer ) + yy_current_buffer = + yy_create_buffer( yyin, YY_BUF_SIZE ); + + yy_load_buffer_state(); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = yy_c_buf_p; + + /* Support of yytext. */ + *yy_cp = yy_hold_char; + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = yy_start; + yy_current_state += YY_AT_BOL(); +yy_match: + while ( (yy_current_state = yy_nxt[yy_current_state][YY_SC_TO_UI(*yy_cp)]) > 0 ) + { + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + + ++yy_cp; + } + + yy_current_state = -yy_current_state; + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + + YY_DO_BEFORE_ACTION; + + +do_action: /* This label is used only to access EOF actions. */ + + if ( yy_flex_debug ) + { + if ( yy_act == 0 ) + fprintf( stderr, "--scanner backing up\n" ); + else if ( yy_act < 19 ) + fprintf( stderr, "--accepting rule at line %d (\"%s\")\n", + yy_rule_linenum[yy_act], yytext ); + else if ( yy_act == 19 ) + fprintf( stderr, "--accepting default rule (\"%s\")\n", + yytext ); + else if ( yy_act == 20 ) + fprintf( stderr, "--(end of buffer or a NUL)\n" ); + else + fprintf( stderr, "--EOF (start condition %d)\n", YY_START ); + } + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = yy_hold_char; + yy_cp = yy_last_accepting_cpos + 1; + yy_current_state = yy_last_accepting_state; + goto yy_find_action; + +case 1: +YY_RULE_SETUP +#line 106 "parser.l" +yy_push_state(pp_line); + YY_BREAK +case 2: +YY_RULE_SETUP +#line 107 "parser.l" +{ + int lineno; + char *cptr, *fname; + yy_pop_state(); + lineno = (int)strtol(yytext, &cptr, 10); + if(!lineno) + yyerror("Malformed '#...' line-directive; invalid linenumber"); + fname = strchr(cptr, '"'); + if(!fname) + yyerror("Malformed '#...' line-directive; missing filename"); + fname++; + cptr = strchr(fname, '"'); + if(!cptr) + yyerror("Malformed '#...' line-directive; missing terminating \""); + *cptr = '\0'; + line_number = lineno - 1; /* We didn't read the newline */ + free( input_name ); + input_name = xstrdup(fname); + } + YY_BREAK +case 3: +YY_RULE_SETUP +#line 126 "parser.l" +yy_push_state(QUOTE); cbufidx = 0; + YY_BREAK +case 4: +YY_RULE_SETUP +#line 127 "parser.l" +{ + yy_pop_state(); + yylval.str = get_buffered_cstring(); + return aSTRING; + } + YY_BREAK +case 5: +#line 133 "parser.l" +case 6: +YY_RULE_SETUP +#line 133 "parser.l" +addcchar(yytext[1]); + YY_BREAK +case 7: +YY_RULE_SETUP +#line 134 "parser.l" +addcchar('\\'); addcchar(yytext[1]); + YY_BREAK +case 8: +YY_RULE_SETUP +#line 135 "parser.l" +addcchar(yytext[0]); + YY_BREAK +case 9: +YY_RULE_SETUP +#line 136 "parser.l" +{ + yylval.uuid = parse_uuid(yytext); + return aUUID; + } + YY_BREAK +case 10: +YY_RULE_SETUP +#line 140 "parser.l" +{ + yylval.num = strtoul(yytext, NULL, 0); + return aHEXNUM; + } + YY_BREAK +case 11: +YY_RULE_SETUP +#line 144 "parser.l" +{ + yylval.num = strtoul(yytext, NULL, 0); + return aNUM; + } + YY_BREAK +case 12: +*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ +yy_c_buf_p = yy_cp -= 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 148 "parser.l" +return tSAFEARRAY; + YY_BREAK +case 13: +YY_RULE_SETUP +#line 149 "parser.l" +return kw_token(yytext); + YY_BREAK +case 14: +YY_RULE_SETUP +#line 150 "parser.l" +line_number++; + YY_BREAK +case 15: +YY_RULE_SETUP +#line 151 "parser.l" + + YY_BREAK +case 16: +YY_RULE_SETUP +#line 152 "parser.l" +return SHL; + YY_BREAK +case 17: +YY_RULE_SETUP +#line 153 "parser.l" +return SHR; + YY_BREAK +case 18: +YY_RULE_SETUP +#line 154 "parser.l" +return yytext[0]; + YY_BREAK +case YY_STATE_EOF(INITIAL): +case YY_STATE_EOF(QUOTE): +case YY_STATE_EOF(pp_line): +#line 155 "parser.l" +{ + if (import_stack_ptr) { + pop_import(); + return aEOF; + } + else yyterminate(); + } + YY_BREAK +case 19: +YY_RULE_SETUP +#line 162 "parser.l" +ECHO; + YY_BREAK +#line 3920 "lex.yy.c" + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = yy_hold_char; + YY_RESTORE_YY_MORE_OFFSET + + if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between yy_current_buffer and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + yy_n_chars = yy_current_buffer->yy_n_chars; + yy_current_buffer->yy_input_file = yyin; + yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = yytext_ptr + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++yy_c_buf_p; + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = yy_c_buf_p; + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer() ) + { + case EOB_ACT_END_OF_FILE: + { + yy_did_buffer_switch_on_eof = 0; + + if ( yywrap() ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = + yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + yy_cp = yy_c_buf_p; + yy_bp = yytext_ptr + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + yy_c_buf_p = + &yy_current_buffer->yy_ch_buf[yy_n_chars]; + + yy_current_state = yy_get_previous_state(); + + yy_cp = yy_c_buf_p; + yy_bp = yytext_ptr + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ + } /* end of yylex */ + + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ + +static int yy_get_next_buffer() + { + register char *dest = yy_current_buffer->yy_ch_buf; + register char *source = yytext_ptr; + register int number_to_move, i; + int ret_val; + + if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( yy_current_buffer->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + yy_current_buffer->yy_n_chars = yy_n_chars = 0; + + else + { + int num_to_read = + yy_current_buffer->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ +#ifdef YY_USES_REJECT + YY_FATAL_ERROR( +"input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); +#else + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = yy_current_buffer; + + int yy_c_buf_p_offset = + (int) (yy_c_buf_p - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yy_flex_realloc( (void *) b->yy_ch_buf, + b->yy_buf_size + 2 ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = yy_current_buffer->yy_buf_size - + number_to_move - 1; +#endif + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), + yy_n_chars, num_to_read ); + + yy_current_buffer->yy_n_chars = yy_n_chars; + } + + if ( yy_n_chars == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart( yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + yy_current_buffer->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + yy_n_chars += number_to_move; + yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; + yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; + + yytext_ptr = &yy_current_buffer->yy_ch_buf[0]; + + return ret_val; + } + + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + +static yy_state_type yy_get_previous_state() + { + register yy_state_type yy_current_state; + register char *yy_cp; + + yy_current_state = yy_start; + yy_current_state += YY_AT_BOL(); + + for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) + { + if ( *yy_cp ) + { + yy_current_state = yy_nxt[yy_current_state][YY_SC_TO_UI(*yy_cp)]; + } + else + yy_current_state = yy_NUL_trans[yy_current_state]; + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + } + + return yy_current_state; + } + + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + +#ifdef YY_USE_PROTOS +static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state ) +#else +static yy_state_type yy_try_NUL_trans( yy_current_state ) +yy_state_type yy_current_state; +#endif + { + register int yy_is_jam; + register char *yy_cp = yy_c_buf_p; + + yy_current_state = yy_NUL_trans[yy_current_state]; + yy_is_jam = (yy_current_state == 0); + + if ( ! yy_is_jam ) + { + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + } + + return yy_is_jam ? 0 : yy_current_state; + } + + +#ifndef YY_NO_UNPUT +#ifdef YY_USE_PROTOS +static void yyunput( int c, register char *yy_bp ) +#else +static void yyunput( c, yy_bp ) +int c; +register char *yy_bp; +#endif + { + register char *yy_cp = yy_c_buf_p; + + /* undo effects of setting up yytext */ + *yy_cp = yy_hold_char; + + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register int number_to_move = yy_n_chars + 2; + register char *dest = &yy_current_buffer->yy_ch_buf[ + yy_current_buffer->yy_buf_size + 2]; + register char *source = + &yy_current_buffer->yy_ch_buf[number_to_move]; + + while ( source > yy_current_buffer->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + yy_current_buffer->yy_n_chars = + yy_n_chars = yy_current_buffer->yy_buf_size; + + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + + + yytext_ptr = yy_bp; + yy_hold_char = *yy_cp; + yy_c_buf_p = yy_cp; + } +#endif /* ifndef YY_NO_UNPUT */ + + +#ifdef __cplusplus +static int yyinput() +#else +static int input() +#endif + { + int c; + + *yy_c_buf_p = yy_hold_char; + + if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + /* This was really a NUL. */ + *yy_c_buf_p = '\0'; + + else + { /* need more input */ + int offset = yy_c_buf_p - yytext_ptr; + ++yy_c_buf_p; + + switch ( yy_get_next_buffer() ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart( yyin ); + + /* fall through */ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap() ) + return EOF; + + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = yytext_ptr + offset; + break; + } + } + } + + c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */ + *yy_c_buf_p = '\0'; /* preserve yytext */ + yy_hold_char = *++yy_c_buf_p; + + yy_current_buffer->yy_at_bol = (c == '\n'); + + return c; + } + + +#ifdef YY_USE_PROTOS +void yyrestart( FILE *input_file ) +#else +void yyrestart( input_file ) +FILE *input_file; +#endif + { + if ( ! yy_current_buffer ) + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); + + yy_init_buffer( yy_current_buffer, input_file ); + yy_load_buffer_state(); + } + + +#ifdef YY_USE_PROTOS +void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) +#else +void yy_switch_to_buffer( new_buffer ) +YY_BUFFER_STATE new_buffer; +#endif + { + if ( yy_current_buffer == new_buffer ) + return; + + if ( yy_current_buffer ) + { + /* Flush out information for old buffer. */ + *yy_c_buf_p = yy_hold_char; + yy_current_buffer->yy_buf_pos = yy_c_buf_p; + yy_current_buffer->yy_n_chars = yy_n_chars; + } + + yy_current_buffer = new_buffer; + yy_load_buffer_state(); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + yy_did_buffer_switch_on_eof = 1; + } + + +#ifdef YY_USE_PROTOS +void yy_load_buffer_state( void ) +#else +void yy_load_buffer_state() +#endif + { + yy_n_chars = yy_current_buffer->yy_n_chars; + yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos; + yyin = yy_current_buffer->yy_input_file; + yy_hold_char = *yy_c_buf_p; + } + + +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) +#else +YY_BUFFER_STATE yy_create_buffer( file, size ) +FILE *file; +int size; +#endif + { + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer( b, file ); + + return b; + } + + +#ifdef YY_USE_PROTOS +void yy_delete_buffer( YY_BUFFER_STATE b ) +#else +void yy_delete_buffer( b ) +YY_BUFFER_STATE b; +#endif + { + if ( ! b ) + return; + + if ( b == yy_current_buffer ) + yy_current_buffer = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yy_flex_free( (void *) b->yy_ch_buf ); + + yy_flex_free( (void *) b ); + } + + +#ifndef YY_ALWAYS_INTERACTIVE +#ifndef YY_NEVER_INTERACTIVE +extern int isatty YY_PROTO(( int )); +#endif +#endif + +#ifdef YY_USE_PROTOS +void yy_init_buffer( YY_BUFFER_STATE b, FILE *file ) +#else +void yy_init_buffer( b, file ) +YY_BUFFER_STATE b; +FILE *file; +#endif + + + { + yy_flush_buffer( b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + +#if YY_ALWAYS_INTERACTIVE + b->yy_is_interactive = 1; +#else +#if YY_NEVER_INTERACTIVE + b->yy_is_interactive = 0; +#else + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; +#endif +#endif + } + + +#ifdef YY_USE_PROTOS +void yy_flush_buffer( YY_BUFFER_STATE b ) +#else +void yy_flush_buffer( b ) +YY_BUFFER_STATE b; +#endif + + { + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == yy_current_buffer ) + yy_load_buffer_state(); + } + + +#ifndef YY_NO_SCAN_BUFFER +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size ) +#else +YY_BUFFER_STATE yy_scan_buffer( base, size ) +char *base; +yy_size_t size; +#endif + { + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer( b ); + + return b; + } +#endif + + +#ifndef YY_NO_SCAN_STRING +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str ) +#else +YY_BUFFER_STATE yy_scan_string( yy_str ) +yyconst char *yy_str; +#endif + { + int len; + for ( len = 0; yy_str[len]; ++len ) + ; + + return yy_scan_bytes( yy_str, len ); + } +#endif + + +#ifndef YY_NO_SCAN_BYTES +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len ) +#else +YY_BUFFER_STATE yy_scan_bytes( bytes, len ) +yyconst char *bytes; +int len; +#endif + { + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = len + 2; + buf = (char *) yy_flex_alloc( n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < len; ++i ) + buf[i] = bytes[i]; + + buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer( buf, n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; + } +#endif + + +#ifndef YY_NO_PUSH_STATE +#ifdef YY_USE_PROTOS +static void yy_push_state( int new_state ) +#else +static void yy_push_state( new_state ) +int new_state; +#endif + { + if ( yy_start_stack_ptr >= yy_start_stack_depth ) + { + yy_size_t new_size; + + yy_start_stack_depth += YY_START_STACK_INCR; + new_size = yy_start_stack_depth * sizeof( int ); + + if ( ! yy_start_stack ) + yy_start_stack = (int *) yy_flex_alloc( new_size ); + + else + yy_start_stack = (int *) yy_flex_realloc( + (void *) yy_start_stack, new_size ); + + if ( ! yy_start_stack ) + YY_FATAL_ERROR( + "out of memory expanding start-condition stack" ); + } + + yy_start_stack[yy_start_stack_ptr++] = YY_START; + + BEGIN(new_state); + } +#endif + + +#ifndef YY_NO_POP_STATE +static void yy_pop_state() + { + if ( --yy_start_stack_ptr < 0 ) + YY_FATAL_ERROR( "start-condition stack underflow" ); + + BEGIN(yy_start_stack[yy_start_stack_ptr]); + } +#endif + + +#ifndef YY_NO_TOP_STATE +static int yy_top_state() + { + return yy_start_stack[yy_start_stack_ptr - 1]; + } +#endif + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +#ifdef YY_USE_PROTOS +static void yy_fatal_error( yyconst char msg[] ) +#else +static void yy_fatal_error( msg ) +char msg[]; +#endif + { + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); + } + + + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + yytext[yyleng] = yy_hold_char; \ + yy_c_buf_p = yytext + n; \ + yy_hold_char = *yy_c_buf_p; \ + *yy_c_buf_p = '\0'; \ + yyleng = n; \ + } \ + while ( 0 ) + + +/* Internal utility routines. */ + +#ifndef yytext_ptr +#ifdef YY_USE_PROTOS +static void yy_flex_strncpy( char *s1, yyconst char *s2, int n ) +#else +static void yy_flex_strncpy( s1, s2, n ) +char *s1; +yyconst char *s2; +int n; +#endif + { + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; + } +#endif + +#ifdef YY_NEED_STRLEN +#ifdef YY_USE_PROTOS +static int yy_flex_strlen( yyconst char *s ) +#else +static int yy_flex_strlen( s ) +yyconst char *s; +#endif + { + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; + } +#endif + + +#ifdef YY_USE_PROTOS +static void *yy_flex_alloc( yy_size_t size ) +#else +static void *yy_flex_alloc( size ) +yy_size_t size; +#endif + { + return (void *) malloc( size ); + } + +#ifdef YY_USE_PROTOS +static void *yy_flex_realloc( void *ptr, yy_size_t size ) +#else +static void *yy_flex_realloc( ptr, size ) +void *ptr; +yy_size_t size; +#endif + { + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); + } + +#ifdef YY_USE_PROTOS +static void yy_flex_free( void *ptr ) +#else +static void yy_flex_free( ptr ) +void *ptr; +#endif + { + free( ptr ); + } + +#if YY_MAIN +int main() + { + yylex(); + return 0; + } +#endif +#line 162 "parser.l" + + +#ifndef yywrap +int yywrap(void) +{ + return 1; +} +#endif + +static struct keyword { + const char *kw; + int token; + int val; +} keywords[] = { + {"FALSE", tFALSE}, + {"TRUE", tTRUE}, + {"__cdecl", tCDECL}, + {"__int64", tINT64}, + {"__stdcall", tSTDCALL}, + {"_stdcall", tSTDCALL}, + {"aggregatable", tAGGREGATABLE}, + {"allocate", tALLOCATE}, + {"appobject", tAPPOBJECT}, + {"async", tASYNC}, + {"async_uuid", tASYNCUUID}, + {"auto_handle", tAUTOHANDLE}, + {"bindable", tBINDABLE}, + {"boolean", tBOOLEAN}, + {"broadcast", tBROADCAST}, + {"byte", tBYTE}, + {"byte_count", tBYTECOUNT}, + {"call_as", tCALLAS}, + {"callback", tCALLBACK}, + {"case", tCASE}, + {"char", tCHAR}, + {"coclass", tCOCLASS}, + {"code", tCODE}, + {"comm_status", tCOMMSTATUS}, + {"const", tCONST}, + {"context_handle", tCONTEXTHANDLE}, + {"context_handle_noserialize", tCONTEXTHANDLENOSERIALIZE}, + {"context_handle_serialize", tCONTEXTHANDLENOSERIALIZE}, + {"control", tCONTROL}, + {"cpp_quote", tCPPQUOTE}, +/* ... */ + {"default", tDEFAULT}, + {"defaultcollelem", tDEFAULTCOLLELEM}, + {"defaultvalue", tDEFAULTVALUE}, + {"defaultvtable", tDEFAULTVTABLE}, + {"dispinterface", tDISPINTERFACE}, + {"displaybind", tDISPLAYBIND}, + {"dllname", tDLLNAME}, + {"double", tDOUBLE}, + {"dual", tDUAL}, + {"endpoint", tENDPOINT}, + {"entry", tENTRY}, + {"enum", tENUM}, + {"error_status_t", tERRORSTATUST}, + {"explicit_handle", tEXPLICITHANDLE}, + {"extern", tEXTERN}, + {"float", tFLOAT}, + {"handle", tHANDLE}, + {"handle_t", tHANDLET}, + {"helpcontext", tHELPCONTEXT}, + {"helpfile", tHELPFILE}, + {"helpstring", tHELPSTRING}, + {"helpstringcontext", tHELPSTRINGCONTEXT}, + {"helpstringdll", tHELPSTRINGDLL}, + {"hidden", tHIDDEN}, + {"hyper", tHYPER}, + {"id", tID}, + {"idempotent", tIDEMPOTENT}, +/* ... */ + {"iid_is", tIIDIS}, + {"immediatebind", tIMMEDIATEBIND}, + {"implicit_handle", tIMPLICITHANDLE}, + {"import", tIMPORT}, + {"importlib", tIMPORTLIB}, + {"in", tIN}, + {"in_line", tINLINE}, + {"input_sync", tINPUTSYNC}, + {"int", tINT}, +/* ... */ + {"interface", tINTERFACE}, + {"lcid", tLCID}, + {"length_is", tLENGTHIS}, + {"library", tLIBRARY}, +/* ... */ + {"local", tLOCAL}, + {"long", tLONG}, +/* ... */ + {"methods", tMETHODS}, +/* ... */ + {"module", tMODULE}, +/* ... */ + {"nonbrowsable", tNONBROWSABLE}, + {"noncreatable", tNONCREATABLE}, + {"nonextensible", tNONEXTENSIBLE}, + {"object", tOBJECT}, + {"odl", tODL}, + {"oleautomation", tOLEAUTOMATION}, +/* ... */ + {"optional", tOPTIONAL}, + {"out", tOUT}, +/* ... */ + {"pointer_default", tPOINTERDEFAULT}, +/* ... */ + {"properties", tPROPERTIES}, + {"propget", tPROPGET}, + {"propput", tPROPPUT}, + {"propputref", tPROPPUTREF}, + {"ptr", tPTR}, +/* ... */ + {"public", tPUBLIC}, + {"range", tRANGE}, +/* ... */ + {"readonly", tREADONLY}, + {"ref", tREF}, + {"requestedit", tREQUESTEDIT}, + {"restricted", tRESTRICTED}, + {"retval", tRETVAL}, +/* ... */ + {"short", tSHORT}, + {"signed", tSIGNED}, + {"single", tSINGLE}, + {"size_is", tSIZEIS}, + {"sizeof", tSIZEOF}, + {"small", tSMALL}, +/* ... */ + {"source", tSOURCE}, +/* ... */ + {"string", tSTRING}, + {"struct", tSTRUCT}, + {"switch", tSWITCH}, + {"switch_is", tSWITCHIS}, + {"switch_type", tSWITCHTYPE}, +/* ... */ + {"transmit_as", tTRANSMITAS}, + {"typedef", tTYPEDEF}, + {"union", tUNION}, +/* ... */ + {"unique", tUNIQUE}, + {"unsigned", tUNSIGNED}, +/* ... */ + {"uuid", tUUID}, + {"v1_enum", tV1ENUM}, +/* ... */ + {"vararg", tVARARG}, + {"version", tVERSION}, + {"void", tVOID}, + {"wchar_t", tWCHAR}, + {"wire_marshal", tWIREMARSHAL}, +}; +#define NKEYWORDS (sizeof(keywords)/sizeof(keywords[0])) +#define KWP(p) ((const struct keyword *)(p)) + +static int kw_cmp_func(const void *s1, const void *s2) +{ + return strcmp(KWP(s1)->kw, KWP(s2)->kw); +} + +#define KW_BSEARCH +static int kw_token(const char *kw) +{ + struct keyword key, *kwp; + key.kw = kw; +#ifdef KW_BSEARCH + kwp = bsearch(&key, keywords, NKEYWORDS, sizeof(keywords[0]), kw_cmp_func); +#else + { + int i; + for (kwp=NULL, i=0; i < NKEYWORDS; i++) + if (!kw_cmp_func(&key, &keywords[i])) { + kwp = &keywords[i]; + break; + } + } +#endif + if (kwp) { + yylval.str = (char*)kwp->kw; + return kwp->token; + } + yylval.str = xstrdup(kw); + return is_type(kw) ? aKNOWNTYPE : aIDENTIFIER; +} + +static void addcchar(char c) +{ + if(cbufidx >= cbufalloc) + { + cbufalloc += 1024; + cbuffer = xrealloc(cbuffer, cbufalloc * sizeof(cbuffer[0])); + if(cbufalloc > 65536) + yywarning("Reallocating string buffer larger than 64kB"); + } + cbuffer[cbufidx++] = c; +} + +static char *get_buffered_cstring(void) +{ + addcchar(0); + return xstrdup(cbuffer); +} + +static void pop_import(void) +{ + int ptr = import_stack_ptr-1; + + fclose(yyin); + yy_delete_buffer( YY_CURRENT_BUFFER ); + yy_switch_to_buffer( import_stack[ptr].state ); + if (temp_name) { + unlink(temp_name); + free(temp_name); + } + temp_name = import_stack[ptr].temp_name; + free( input_name ); + input_name = import_stack[ptr].input_name; + line_number = import_stack[ptr].line_number; + import_stack_ptr--; +} + +struct imports { + char *name; + struct imports *next; +} *first_import; + +int do_import(char *fname) +{ + FILE *f; + char *hname, *path, *p; + struct imports *import; + int ptr = import_stack_ptr; + int ret; + + if (!parse_only && do_header) { + hname = dup_basename(fname, ".idl"); + p = hname + strlen(hname) - 2; + if (p <= hname || strcmp( p, ".h" )) strcat(hname, ".h"); + + fprintf(header, "#include <%s>\n", hname); + free(hname); + } + + import = first_import; + while (import && strcmp(import->name, fname)) + import = import->next; + if (import) return 0; /* already imported */ + + import = xmalloc(sizeof(struct imports)); + import->name = xstrdup(fname); + import->next = first_import; + first_import = import; + + if (!(path = wpp_find_include( fname, input_name ))) + yyerror("Unable to open include file %s", fname); + + import_stack[ptr].temp_name = temp_name; + import_stack[ptr].input_name = input_name; + import_stack[ptr].line_number = line_number; + import_stack_ptr++; + input_name = path; + line_number = 1; + + ret = wpp_parse_temp( path, NULL, &temp_name ); + if (ret) exit(1); + + if((f = fopen(temp_name, "r")) == NULL) + yyerror("Unable to open %s", temp_name); + + import_stack[ptr].state = YY_CURRENT_BUFFER; + yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE)); + return 1; +} + +void abort_import(void) +{ + int ptr; + + for (ptr=0; ptr +#include +#include +#include +#include +#ifdef HAVE_UNISTD_H +# include +#endif + +#include "widl.h" +#include "utils.h" +#include "parser.h" +#include "wine/wpp.h" + +#include "parser.tab.h" + +extern char *temp_name; + +static void addcchar(char c); +static char *get_buffered_cstring(void); + +static char *cbuffer; +static int cbufidx; +static int cbufalloc = 0; + +static int kw_token(const char *kw); + +#define MAX_IMPORT_DEPTH 10 +struct { + YY_BUFFER_STATE state; + char *input_name; + int line_number; + char *temp_name; +} import_stack[MAX_IMPORT_DEPTH]; +int import_stack_ptr = 0; + +static void pop_import(void); + +static UUID* parse_uuid(const char*u) +{ + UUID* uuid = xmalloc(sizeof(UUID)); + char b[3]; + /* it would be nice to use UuidFromStringA */ + uuid->Data1 = strtoul(u, NULL, 16); + uuid->Data2 = strtoul(u+9, NULL, 16); + uuid->Data3 = strtoul(u+14, NULL, 16); + b[2] = 0; + memcpy(b, u+19, 2); uuid->Data4[0] = strtoul(b, NULL, 16); + memcpy(b, u+21, 2); uuid->Data4[1] = strtoul(b, NULL, 16); + memcpy(b, u+24, 2); uuid->Data4[2] = strtoul(b, NULL, 16); + memcpy(b, u+26, 2); uuid->Data4[3] = strtoul(b, NULL, 16); + memcpy(b, u+28, 2); uuid->Data4[4] = strtoul(b, NULL, 16); + memcpy(b, u+30, 2); uuid->Data4[5] = strtoul(b, NULL, 16); + memcpy(b, u+32, 2); uuid->Data4[6] = strtoul(b, NULL, 16); + memcpy(b, u+34, 2); uuid->Data4[7] = strtoul(b, NULL, 16); + return uuid; +} + +%} + +/* + ************************************************************************** + * The flexer starts here + ************************************************************************** + */ +%% +^{ws}*\#{ws}* yy_push_state(pp_line); +[^\n]* { + int lineno; + char *cptr, *fname; + yy_pop_state(); + lineno = (int)strtol(yytext, &cptr, 10); + if(!lineno) + yyerror("Malformed '#...' line-directive; invalid linenumber"); + fname = strchr(cptr, '"'); + if(!fname) + yyerror("Malformed '#...' line-directive; missing filename"); + fname++; + cptr = strchr(fname, '"'); + if(!cptr) + yyerror("Malformed '#...' line-directive; missing terminating \""); + *cptr = '\0'; + line_number = lineno - 1; /* We didn't read the newline */ + free( input_name ); + input_name = xstrdup(fname); + } +\" yy_push_state(QUOTE); cbufidx = 0; +\" { + yy_pop_state(); + yylval.str = get_buffered_cstring(); + return aSTRING; + } +\\\\ | +\\\" addcchar(yytext[1]); +\\. addcchar('\\'); addcchar(yytext[1]); +. addcchar(yytext[0]); +{uuid} { + yylval.uuid = parse_uuid(yytext); + return aUUID; + } +{hex} { + yylval.num = strtoul(yytext, NULL, 0); + return aHEXNUM; + } +{int} { + yylval.num = strtoul(yytext, NULL, 0); + return aNUM; + } +SAFEARRAY{ws}*/\( return tSAFEARRAY; +{cident} return kw_token(yytext); +\n line_number++; +{ws} +\<\< return SHL; +\>\> return SHR; +. return yytext[0]; +<> { + if (import_stack_ptr) { + pop_import(); + return aEOF; + } + else yyterminate(); + } +%% + +#ifndef yywrap +int yywrap(void) +{ + return 1; +} +#endif + +static struct keyword { + const char *kw; + int token; + int val; +} keywords[] = { + {"FALSE", tFALSE}, + {"TRUE", tTRUE}, + {"__cdecl", tCDECL}, + {"__int64", tINT64}, + {"__stdcall", tSTDCALL}, + {"_stdcall", tSTDCALL}, + {"aggregatable", tAGGREGATABLE}, + {"allocate", tALLOCATE}, + {"appobject", tAPPOBJECT}, + {"async", tASYNC}, + {"async_uuid", tASYNCUUID}, + {"auto_handle", tAUTOHANDLE}, + {"bindable", tBINDABLE}, + {"boolean", tBOOLEAN}, + {"broadcast", tBROADCAST}, + {"byte", tBYTE}, + {"byte_count", tBYTECOUNT}, + {"call_as", tCALLAS}, + {"callback", tCALLBACK}, + {"case", tCASE}, + {"char", tCHAR}, + {"coclass", tCOCLASS}, + {"code", tCODE}, + {"comm_status", tCOMMSTATUS}, + {"const", tCONST}, + {"context_handle", tCONTEXTHANDLE}, + {"context_handle_noserialize", tCONTEXTHANDLENOSERIALIZE}, + {"context_handle_serialize", tCONTEXTHANDLENOSERIALIZE}, + {"control", tCONTROL}, + {"cpp_quote", tCPPQUOTE}, +/* ... */ + {"default", tDEFAULT}, + {"defaultcollelem", tDEFAULTCOLLELEM}, + {"defaultvalue", tDEFAULTVALUE}, + {"defaultvtable", tDEFAULTVTABLE}, + {"dispinterface", tDISPINTERFACE}, + {"displaybind", tDISPLAYBIND}, + {"dllname", tDLLNAME}, + {"double", tDOUBLE}, + {"dual", tDUAL}, + {"endpoint", tENDPOINT}, + {"entry", tENTRY}, + {"enum", tENUM}, + {"error_status_t", tERRORSTATUST}, + {"explicit_handle", tEXPLICITHANDLE}, + {"extern", tEXTERN}, + {"float", tFLOAT}, + {"handle", tHANDLE}, + {"handle_t", tHANDLET}, + {"helpcontext", tHELPCONTEXT}, + {"helpfile", tHELPFILE}, + {"helpstring", tHELPSTRING}, + {"helpstringcontext", tHELPSTRINGCONTEXT}, + {"helpstringdll", tHELPSTRINGDLL}, + {"hidden", tHIDDEN}, + {"hyper", tHYPER}, + {"id", tID}, + {"idempotent", tIDEMPOTENT}, +/* ... */ + {"iid_is", tIIDIS}, + {"immediatebind", tIMMEDIATEBIND}, + {"implicit_handle", tIMPLICITHANDLE}, + {"import", tIMPORT}, + {"importlib", tIMPORTLIB}, + {"in", tIN}, + {"in_line", tINLINE}, + {"input_sync", tINPUTSYNC}, + {"int", tINT}, +/* ... */ + {"interface", tINTERFACE}, + {"lcid", tLCID}, + {"length_is", tLENGTHIS}, + {"library", tLIBRARY}, +/* ... */ + {"local", tLOCAL}, + {"long", tLONG}, +/* ... */ + {"methods", tMETHODS}, +/* ... */ + {"module", tMODULE}, +/* ... */ + {"nonbrowsable", tNONBROWSABLE}, + {"noncreatable", tNONCREATABLE}, + {"nonextensible", tNONEXTENSIBLE}, + {"object", tOBJECT}, + {"odl", tODL}, + {"oleautomation", tOLEAUTOMATION}, +/* ... */ + {"optional", tOPTIONAL}, + {"out", tOUT}, +/* ... */ + {"pointer_default", tPOINTERDEFAULT}, +/* ... */ + {"properties", tPROPERTIES}, + {"propget", tPROPGET}, + {"propput", tPROPPUT}, + {"propputref", tPROPPUTREF}, + {"ptr", tPTR}, +/* ... */ + {"public", tPUBLIC}, + {"range", tRANGE}, +/* ... */ + {"readonly", tREADONLY}, + {"ref", tREF}, + {"requestedit", tREQUESTEDIT}, + {"restricted", tRESTRICTED}, + {"retval", tRETVAL}, +/* ... */ + {"short", tSHORT}, + {"signed", tSIGNED}, + {"single", tSINGLE}, + {"size_is", tSIZEIS}, + {"sizeof", tSIZEOF}, + {"small", tSMALL}, +/* ... */ + {"source", tSOURCE}, +/* ... */ + {"string", tSTRING}, + {"struct", tSTRUCT}, + {"switch", tSWITCH}, + {"switch_is", tSWITCHIS}, + {"switch_type", tSWITCHTYPE}, +/* ... */ + {"transmit_as", tTRANSMITAS}, + {"typedef", tTYPEDEF}, + {"union", tUNION}, +/* ... */ + {"unique", tUNIQUE}, + {"unsigned", tUNSIGNED}, +/* ... */ + {"uuid", tUUID}, + {"v1_enum", tV1ENUM}, +/* ... */ + {"vararg", tVARARG}, + {"version", tVERSION}, + {"void", tVOID}, + {"wchar_t", tWCHAR}, + {"wire_marshal", tWIREMARSHAL}, +}; +#define NKEYWORDS (sizeof(keywords)/sizeof(keywords[0])) +#define KWP(p) ((const struct keyword *)(p)) + +static int kw_cmp_func(const void *s1, const void *s2) +{ + return strcmp(KWP(s1)->kw, KWP(s2)->kw); +} + +#define KW_BSEARCH +static int kw_token(const char *kw) +{ + struct keyword key, *kwp; + key.kw = kw; +#ifdef KW_BSEARCH + kwp = bsearch(&key, keywords, NKEYWORDS, sizeof(keywords[0]), kw_cmp_func); +#else + { + int i; + for (kwp=NULL, i=0; i < NKEYWORDS; i++) + if (!kw_cmp_func(&key, &keywords[i])) { + kwp = &keywords[i]; + break; + } + } +#endif + if (kwp) { + yylval.str = (char*)kwp->kw; + return kwp->token; + } + yylval.str = xstrdup(kw); + return is_type(kw) ? aKNOWNTYPE : aIDENTIFIER; +} + +static void addcchar(char c) +{ + if(cbufidx >= cbufalloc) + { + cbufalloc += 1024; + cbuffer = xrealloc(cbuffer, cbufalloc * sizeof(cbuffer[0])); + if(cbufalloc > 65536) + yywarning("Reallocating string buffer larger than 64kB"); + } + cbuffer[cbufidx++] = c; +} + +static char *get_buffered_cstring(void) +{ + addcchar(0); + return xstrdup(cbuffer); +} + +static void pop_import(void) +{ + int ptr = import_stack_ptr-1; + + fclose(yyin); + yy_delete_buffer( YY_CURRENT_BUFFER ); + yy_switch_to_buffer( import_stack[ptr].state ); + if (temp_name) { + unlink(temp_name); + free(temp_name); + } + temp_name = import_stack[ptr].temp_name; + free( input_name ); + input_name = import_stack[ptr].input_name; + line_number = import_stack[ptr].line_number; + import_stack_ptr--; +} + +struct imports { + char *name; + struct imports *next; +} *first_import; + +int do_import(char *fname) +{ + FILE *f; + char *hname, *path, *p; + struct imports *import; + int ptr = import_stack_ptr; + int ret; + + if (!parse_only && do_header) { + hname = dup_basename(fname, ".idl"); + p = hname + strlen(hname) - 2; + if (p <= hname || strcmp( p, ".h" )) strcat(hname, ".h"); + + fprintf(header, "#include <%s>\n", hname); + free(hname); + } + + import = first_import; + while (import && strcmp(import->name, fname)) + import = import->next; + if (import) return 0; /* already imported */ + + import = xmalloc(sizeof(struct imports)); + import->name = xstrdup(fname); + import->next = first_import; + first_import = import; + + if (!(path = wpp_find_include( fname, input_name ))) + yyerror("Unable to open include file %s", fname); + + import_stack[ptr].temp_name = temp_name; + import_stack[ptr].input_name = input_name; + import_stack[ptr].line_number = line_number; + import_stack_ptr++; + input_name = path; + line_number = 1; + + ret = wpp_parse_temp( path, NULL, &temp_name ); + if (ret) exit(1); + + if((f = fopen(temp_name, "r")) == NULL) + yyerror("Unable to open %s", temp_name); + + import_stack[ptr].state = YY_CURRENT_BUFFER; + yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE)); + return 1; +} + +void abort_import(void) +{ + int ptr; + + for (ptr=0; ptr +#include +#include +#include +#include +#include +#ifdef HAVE_ALLOCA_H +#include +#endif + +#include "windef.h" + +#include "widl.h" +#include "utils.h" +#include "parser.h" +#include "header.h" +#include "typelib.h" + +#if defined(YYBYACC) + /* Berkeley yacc (byacc) doesn't seem to know about these */ + /* Some *BSD supplied versions do define these though */ +# ifndef YYEMPTY +# define YYEMPTY (-1) /* Empty lookahead value of yychar */ +# endif +# ifndef YYLEX +# define YYLEX yylex() +# endif + +#elif defined(YYBISON) + /* Bison was used for original development */ + /* #define YYEMPTY -2 */ + /* #define YYLEX yylex() */ + +#else + /* No yacc we know yet */ +# if !defined(YYEMPTY) || !defined(YYLEX) +# error Yacc version/type unknown. This version needs to be verified for settings of YYEMPTY and YYLEX. +# elif defined(__GNUC__) /* gcc defines the #warning directive */ +# warning Yacc version/type unknown. It defines YYEMPTY and YYLEX, but is not tested + /* #else we just take a chance that it works... */ +# endif +#endif + +static attr_t *make_attr(enum attr_type type); +static attr_t *make_attrv(enum attr_type type, unsigned long val); +static attr_t *make_attrp(enum attr_type type, void *val); +static expr_t *make_expr(enum expr_type type); +static expr_t *make_exprl(enum expr_type type, long val); +static expr_t *make_exprs(enum expr_type type, char *val); +static expr_t *make_exprt(enum expr_type type, typeref_t *tref, expr_t *expr); +static expr_t *make_expr1(enum expr_type type, expr_t *expr); +static expr_t *make_expr2(enum expr_type type, expr_t *exp1, expr_t *exp2); +static expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, expr_t *expr3); +static type_t *make_type(unsigned char type, type_t *ref); +static typeref_t *make_tref(char *name, type_t *ref); +static typeref_t *uniq_tref(typeref_t *ref); +static type_t *type_ref(typeref_t *ref); +static void set_type(var_t *v, typeref_t *ref, expr_t *arr); +static ifref_t *make_ifref(type_t *iface); +static var_t *make_var(char *name); +static func_t *make_func(var_t *def, var_t *args); +static type_t *make_class(char *name); +static type_t *make_safearray(void); + +static type_t *reg_type(type_t *type, const char *name, int t); +static type_t *reg_types(type_t *type, var_t *names, int t); +static type_t *find_type(const char *name, int t); +static type_t *find_type2(char *name, int t); +static type_t *get_type(unsigned char type, char *name, int t); +static type_t *get_typev(unsigned char type, var_t *name, int t); +static int get_struct_type(var_t *fields); + +static var_t *reg_const(var_t *var); +static var_t *find_const(char *name, int f); + +#define tsENUM 1 +#define tsSTRUCT 2 +#define tsUNION 3 + +static type_t std_bool = { "boolean" }; +static type_t std_int = { "int" }; +static type_t std_int64 = { "__int64" }; +static type_t std_uhyper = { "MIDL_uhyper" }; + + + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 1 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) +#line 109 "parser.y" +typedef union YYSTYPE { + attr_t *attr; + expr_t *expr; + type_t *type; + typeref_t *tref; + var_t *var; + func_t *func; + ifref_t *ifref; + char *str; + UUID *uuid; + unsigned int num; +} YYSTYPE; +/* Line 191 of yacc.c. */ +#line 463 "parser.tab.c" +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 +#endif + + + +/* Copy the second part of user declarations. */ + + +/* Line 214 of yacc.c. */ +#line 475 "parser.tab.c" + +#if ! defined (yyoverflow) || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# if YYSTACK_USE_ALLOCA +# define YYSTACK_ALLOC alloca +# else +# ifndef YYSTACK_USE_ALLOCA +# if defined (alloca) || defined (_ALLOCA_H) +# define YYSTACK_ALLOC alloca +# else +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# else +# if defined (__STDC__) || defined (__cplusplus) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# endif +# define YYSTACK_ALLOC malloc +# define YYSTACK_FREE free +# endif +#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ + + +#if (! defined (yyoverflow) \ + && (! defined (__cplusplus) \ + || (YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + short yyss; + YYSTYPE yyvs; + }; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + register YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (0) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack, Stack, yysize); \ + Stack = &yyptr->Stack; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (0) + +#endif + +#if defined (__STDC__) || defined (__cplusplus) + typedef signed char yysigned_char; +#else + typedef short yysigned_char; +#endif + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 3 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 1059 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 153 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 74 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 272 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 496 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 388 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const unsigned char yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 135, 2, + 145, 146, 138, 137, 131, 136, 152, 139, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 133, 144, + 2, 151, 2, 132, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 149, 2, 150, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 147, 134, 148, 140, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 141, 142, 143 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const unsigned short yyprhs[] = +{ + 0, 0, 3, 5, 6, 9, 12, 16, 19, 22, + 25, 28, 29, 32, 35, 39, 42, 45, 48, 51, + 52, 56, 59, 61, 64, 66, 69, 72, 74, 77, + 80, 83, 88, 92, 96, 101, 104, 108, 112, 113, + 115, 117, 119, 123, 125, 130, 134, 141, 147, 148, + 152, 156, 158, 162, 167, 168, 170, 174, 176, 180, + 185, 186, 188, 190, 192, 194, 196, 201, 206, 208, + 210, 212, 214, 216, 218, 223, 228, 230, 232, 237, + 239, 244, 249, 254, 256, 258, 263, 268, 273, 278, + 283, 285, 290, 292, 297, 299, 305, 307, 309, 314, + 316, 318, 320, 322, 324, 326, 328, 330, 332, 337, + 339, 341, 343, 345, 352, 354, 356, 358, 360, 365, + 367, 369, 374, 379, 384, 389, 391, 393, 398, 403, + 405, 406, 408, 409, 412, 417, 421, 427, 428, 431, + 433, 435, 439, 443, 445, 451, 453, 457, 458, 460, + 462, 464, 466, 468, 470, 476, 480, 484, 488, 492, + 496, 500, 504, 508, 511, 514, 517, 522, 527, 531, + 533, 537, 539, 544, 545, 548, 551, 555, 558, 560, + 565, 573, 574, 576, 577, 579, 581, 583, 585, 587, + 589, 591, 593, 595, 597, 599, 601, 603, 605, 607, + 610, 613, 615, 617, 619, 621, 623, 625, 627, 628, + 630, 632, 635, 637, 640, 643, 645, 647, 650, 653, + 656, 661, 662, 665, 668, 671, 674, 677, 680, 684, + 687, 691, 697, 698, 701, 704, 707, 710, 716, 724, + 726, 729, 732, 735, 738, 741, 746, 749, 752, 754, + 756, 760, 762, 766, 768, 770, 772, 778, 780, 782, + 784, 787, 789, 792, 794, 797, 799, 802, 807, 812, + 818, 829, 831 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const short yyrhs[] = +{ + 154, 0, -1, 155, -1, -1, 155, 214, -1, 155, + 213, -1, 155, 200, 144, -1, 155, 202, -1, 155, + 217, -1, 155, 165, -1, 155, 158, -1, -1, 156, + 214, -1, 156, 213, -1, 156, 200, 144, -1, 156, + 202, -1, 156, 217, -1, 156, 158, -1, 156, 162, + -1, -1, 157, 193, 144, -1, 157, 158, -1, 144, + -1, 179, 144, -1, 159, -1, 183, 144, -1, 189, + 144, -1, 161, -1, 222, 144, -1, 224, 144, -1, + 225, 144, -1, 36, 145, 7, 146, -1, 68, 7, + 144, -1, 160, 156, 9, -1, 69, 145, 7, 146, + -1, 78, 3, -1, 173, 163, 147, -1, 164, 156, + 148, -1, -1, 168, -1, 128, -1, 169, -1, 168, + 131, 169, -1, 167, -1, 173, 223, 219, 170, -1, + 223, 219, 170, -1, 173, 223, 219, 145, 166, 146, + -1, 223, 219, 145, 166, 146, -1, -1, 149, 171, + 150, -1, 149, 138, 150, -1, 185, -1, 171, 131, + 186, -1, 171, 150, 149, 186, -1, -1, 173, -1, + 149, 174, 150, -1, 175, -1, 174, 131, 175, -1, + 174, 150, 149, 175, -1, -1, 12, -1, 14, -1, + 15, -1, 17, -1, 18, -1, 23, 145, 196, 146, + -1, 25, 145, 187, 146, -1, 32, -1, 33, -1, + 34, -1, 35, -1, 37, -1, 38, -1, 39, 145, + 188, 146, -1, 39, 145, 7, 146, -1, 40, -1, + 41, -1, 43, 145, 7, 146, -1, 45, -1, 46, + 145, 7, 146, -1, 47, 145, 7, 146, -1, 47, + 145, 188, 146, -1, 50, -1, 54, -1, 56, 145, + 188, 146, -1, 57, 145, 7, 146, -1, 58, 145, + 7, 146, -1, 59, 145, 188, 146, -1, 60, 145, + 7, 146, -1, 61, -1, 63, 145, 188, 146, -1, + 64, -1, 65, 145, 196, 146, -1, 66, -1, 67, + 145, 55, 3, 146, -1, 70, -1, 72, -1, 77, + 145, 184, 146, -1, 79, -1, 83, -1, 84, -1, + 85, -1, 86, -1, 87, -1, 88, -1, 89, -1, + 90, -1, 91, 145, 221, 146, -1, 93, -1, 94, + -1, 95, -1, 97, -1, 98, 145, 188, 131, 188, + 146, -1, 99, -1, 101, -1, 102, -1, 103, -1, + 108, 145, 184, 146, -1, 111, -1, 113, -1, 116, + 145, 186, 146, -1, 117, 145, 223, 146, -1, 118, + 145, 223, 146, -1, 124, 145, 8, 146, -1, 125, + -1, 126, -1, 127, 145, 226, 146, -1, 130, 145, + 223, 146, -1, 221, -1, -1, 112, -1, -1, 177, + 178, -1, 25, 186, 133, 191, -1, 37, 133, 191, + -1, 31, 223, 196, 151, 188, -1, -1, 181, 131, + -1, 181, -1, 182, -1, 181, 131, 182, -1, 196, + 151, 188, -1, 196, -1, 48, 195, 147, 180, 148, + -1, 185, -1, 184, 131, 185, -1, -1, 186, -1, + 5, -1, 6, -1, 52, -1, 119, -1, 3, -1, + 186, 132, 186, 133, 186, -1, 186, 134, 186, -1, + 186, 135, 186, -1, 186, 137, 186, -1, 186, 136, + 186, -1, 186, 138, 186, -1, 186, 139, 186, -1, + 186, 10, 186, -1, 186, 11, 186, -1, 140, 186, + -1, 136, 186, -1, 138, 186, -1, 145, 223, 146, + 186, -1, 109, 145, 223, 146, -1, 145, 186, 146, + -1, 188, -1, 187, 131, 188, -1, 186, -1, 51, + 31, 223, 196, -1, -1, 190, 191, -1, 192, 144, + -1, 172, 225, 144, -1, 173, 144, -1, 144, -1, + 172, 223, 219, 170, -1, 172, 223, 176, 219, 145, + 166, 146, -1, -1, 196, -1, -1, 3, -1, 4, + -1, 3, -1, 4, -1, 15, -1, 63, -1, 76, + -1, 86, -1, 98, -1, 103, -1, 124, -1, 127, + -1, 21, -1, 129, -1, 199, -1, 106, 199, -1, + 123, 199, -1, 123, -1, 53, -1, 107, -1, 44, + -1, 19, -1, 49, -1, 55, -1, -1, 73, -1, + 73, -1, 105, 198, -1, 110, -1, 80, 198, -1, + 62, 198, -1, 74, -1, 27, -1, 28, 3, -1, + 28, 4, -1, 173, 200, -1, 201, 147, 203, 148, + -1, -1, 203, 204, -1, 172, 214, -1, 42, 3, + -1, 42, 4, -1, 173, 205, -1, 92, 133, -1, + 207, 192, 144, -1, 81, 133, -1, 208, 193, 144, + -1, 206, 147, 207, 208, 148, -1, -1, 133, 4, + -1, 75, 3, -1, 75, 4, -1, 173, 211, -1, + 212, 210, 147, 157, 148, -1, 212, 133, 3, 147, + 161, 157, 148, -1, 209, -1, 211, 144, -1, 205, + 144, -1, 82, 3, -1, 82, 4, -1, 173, 215, + -1, 216, 147, 157, 148, -1, 138, 219, -1, 31, + 218, -1, 196, -1, 218, -1, 145, 219, 146, -1, + 219, -1, 220, 131, 219, -1, 100, -1, 122, -1, + 96, -1, 114, 195, 147, 190, 148, -1, 128, -1, + 4, -1, 197, -1, 31, 223, -1, 183, -1, 48, + 3, -1, 222, -1, 114, 3, -1, 225, -1, 121, + 3, -1, 104, 145, 223, 146, -1, 120, 172, 223, + 220, -1, 121, 195, 147, 190, 148, -1, 121, 195, + 115, 145, 192, 146, 194, 147, 177, 148, -1, 5, + -1, 5, 152, 5, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const unsigned short yyrline[] = +{ + 0, 239, 239, 242, 243, 244, 245, 249, 253, 254, + 255, 258, 259, 260, 261, 262, 265, 266, 267, 270, + 271, 272, 275, 276, 277, 278, 279, 280, 281, 282, + 283, 286, 288, 291, 294, 297, 299, 302, 305, 306, + 309, 312, 313, 314, 318, 322, 325, 331, 338, 339, + 340, 343, 344, 345, 348, 349, 353, 359, 360, 363, + 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, + 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, + 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, + 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, + 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, + 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, + 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, + 440, 441, 444, 445, 450, 454, 460, 466, 467, 468, + 471, 474, 480, 484, 489, 497, 498, 511, 512, 515, + 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, + 526, 527, 528, 529, 530, 531, 532, 533, 534, 537, + 538, 541, 547, 552, 553, 558, 559, 560, 561, 564, + 568, 578, 579, 582, 583, 584, 587, 589, 590, 591, + 592, 593, 594, 595, 596, 597, 600, 601, 602, 603, + 604, 616, 617, 618, 619, 620, 621, 622, 625, 626, + 629, 630, 631, 632, 633, 634, 635, 638, 639, 645, + 652, 657, 658, 662, 665, 666, 669, 682, 683, 686, + 687, 690, 705, 706, 709, 710, 713, 721, 729, 736, + 740, 741, 744, 745, 748, 753, 759, 760, 763, 764, + 765, 769, 770, 774, 775, 776, 779, 789, 790, 791, + 792, 793, 794, 795, 796, 797, 798, 799, 802, 815, + 819, 833, 834 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE +/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "aIDENTIFIER", "aKNOWNTYPE", "aNUM", + "aHEXNUM", "aSTRING", "aUUID", "aEOF", "SHL", "SHR", "tAGGREGATABLE", + "tALLOCATE", "tAPPOBJECT", "tASYNC", "tASYNCUUID", "tAUTOHANDLE", + "tBINDABLE", "tBOOLEAN", "tBROADCAST", "tBYTE", "tBYTECOUNT", "tCALLAS", + "tCALLBACK", "tCASE", "tCDECL", "tCHAR", "tCOCLASS", "tCODE", + "tCOMMSTATUS", "tCONST", "tCONTEXTHANDLE", "tCONTEXTHANDLENOSERIALIZE", + "tCONTEXTHANDLESERIALIZE", "tCONTROL", "tCPPQUOTE", "tDEFAULT", + "tDEFAULTCOLLELEM", "tDEFAULTVALUE", "tDEFAULTVTABLE", "tDISPLAYBIND", + "tDISPINTERFACE", "tDLLNAME", "tDOUBLE", "tDUAL", "tENDPOINT", "tENTRY", + "tENUM", "tERRORSTATUST", "tEXPLICITHANDLE", "tEXTERN", "tFALSE", + "tFLOAT", "tHANDLE", "tHANDLET", "tHELPCONTEXT", "tHELPFILE", + "tHELPSTRING", "tHELPSTRINGCONTEXT", "tHELPSTRINGDLL", "tHIDDEN", + "tHYPER", "tID", "tIDEMPOTENT", "tIIDIS", "tIMMEDIATEBIND", + "tIMPLICITHANDLE", "tIMPORT", "tIMPORTLIB", "tIN", "tINLINE", + "tINPUTSYNC", "tINT", "tINT64", "tINTERFACE", "tLCID", "tLENGTHIS", + "tLIBRARY", "tLOCAL", "tLONG", "tMETHODS", "tMODULE", "tNONBROWSABLE", + "tNONCREATABLE", "tNONEXTENSIBLE", "tOBJECT", "tODL", "tOLEAUTOMATION", + "tOPTIONAL", "tOUT", "tPOINTERDEFAULT", "tPROPERTIES", "tPROPGET", + "tPROPPUT", "tPROPPUTREF", "tPTR", "tPUBLIC", "tRANGE", "tREADONLY", + "tREF", "tREQUESTEDIT", "tRESTRICTED", "tRETVAL", "tSAFEARRAY", + "tSHORT", "tSIGNED", "tSINGLE", "tSIZEIS", "tSIZEOF", "tSMALL", + "tSOURCE", "tSTDCALL", "tSTRING", "tSTRUCT", "tSWITCH", "tSWITCHIS", + "tSWITCHTYPE", "tTRANSMITAS", "tTRUE", "tTYPEDEF", "tUNION", "tUNIQUE", + "tUNSIGNED", "tUUID", "tV1ENUM", "tVARARG", "tVERSION", "tVOID", + "tWCHAR", "tWIREMARSHAL", "','", "'?'", "':'", "'|'", "'&'", "'-'", + "'+'", "'*'", "'/'", "'~'", "CAST", "PPTR", "NEG", "';'", "'('", "')'", + "'{'", "'}'", "'['", "']'", "'='", "'.'", "$accept", "input", + "gbl_statements", "imp_statements", "int_statements", "statement", + "cppquote", "import_start", "import", "importlib", "libraryhdr", + "library_start", "librarydef", "m_args", "no_args", "args", "arg", + "array", "array_list", "m_attributes", "attributes", "attrib_list", + "attribute", "callconv", "cases", "case", "constdef", "enums", + "enum_list", "enum", "enumdef", "m_exprs", "m_expr", "expr", + "expr_list_const", "expr_const", "externdef", "fields", "field", + "s_field", "funcdef", "m_ident", "t_ident", "ident", "base_type", + "m_int", "int_std", "coclass", "coclasshdr", "coclassdef", + "coclass_ints", "coclass_int", "dispinterface", "dispinterfacehdr", + "dispint_props", "dispint_meths", "dispinterfacedef", "inherit", + "interface", "interfacehdr", "interfacedef", "interfacedec", "module", + "modulehdr", "moduledef", "p_ident", "pident", "pident_list", + "pointer_type", "structdef", "type", "typedef", "uniondef", "version", 0 +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const unsigned short yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, + 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, + 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, + 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, + 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, + 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, + 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, + 385, 44, 63, 58, 124, 38, 45, 43, 42, 47, + 126, 386, 387, 388, 59, 40, 41, 123, 125, 91, + 93, 61, 46 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const unsigned char yyr1[] = +{ + 0, 153, 154, 155, 155, 155, 155, 155, 155, 155, + 155, 156, 156, 156, 156, 156, 156, 156, 156, 157, + 157, 157, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 159, 160, 161, 162, 163, 164, 165, 166, 166, + 167, 168, 168, 168, 169, 169, 169, 169, 170, 170, + 170, 171, 171, 171, 172, 172, 173, 174, 174, 174, + 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, + 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, + 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, + 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, + 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, + 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, + 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, + 176, 176, 177, 177, 178, 178, 179, 180, 180, 180, + 181, 181, 182, 182, 183, 184, 184, 185, 185, 186, + 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, + 186, 186, 186, 186, 186, 186, 186, 186, 186, 187, + 187, 188, 189, 190, 190, 191, 191, 191, 191, 192, + 193, 194, 194, 195, 195, 195, 196, 196, 196, 196, + 196, 196, 196, 196, 196, 196, 197, 197, 197, 197, + 197, 197, 197, 197, 197, 197, 197, 197, 198, 198, + 199, 199, 199, 199, 199, 199, 199, 200, 200, 201, + 202, 203, 203, 204, 205, 205, 206, 207, 207, 208, + 208, 209, 210, 210, 211, 211, 212, 213, 213, 213, + 214, 214, 215, 215, 216, 217, 218, 218, 219, 219, + 219, 220, 220, 221, 221, 221, 222, 223, 223, 223, + 223, 223, 223, 223, 223, 223, 223, 223, 224, 225, + 225, 226, 226 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const unsigned char yyr2[] = +{ + 0, 2, 1, 0, 2, 2, 3, 2, 2, 2, + 2, 0, 2, 2, 3, 2, 2, 2, 2, 0, + 3, 2, 1, 2, 1, 2, 2, 1, 2, 2, + 2, 4, 3, 3, 4, 2, 3, 3, 0, 1, + 1, 1, 3, 1, 4, 3, 6, 5, 0, 3, + 3, 1, 3, 4, 0, 1, 3, 1, 3, 4, + 0, 1, 1, 1, 1, 1, 4, 4, 1, 1, + 1, 1, 1, 1, 4, 4, 1, 1, 4, 1, + 4, 4, 4, 1, 1, 4, 4, 4, 4, 4, + 1, 4, 1, 4, 1, 5, 1, 1, 4, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, + 1, 1, 1, 6, 1, 1, 1, 1, 4, 1, + 1, 4, 4, 4, 4, 1, 1, 4, 4, 1, + 0, 1, 0, 2, 4, 3, 5, 0, 2, 1, + 1, 3, 3, 1, 5, 1, 3, 0, 1, 1, + 1, 1, 1, 1, 5, 3, 3, 3, 3, 3, + 3, 3, 3, 2, 2, 2, 4, 4, 3, 1, + 3, 1, 4, 0, 2, 2, 3, 2, 1, 4, + 7, 0, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, + 2, 1, 1, 1, 1, 1, 1, 1, 0, 1, + 1, 2, 1, 2, 2, 1, 1, 2, 2, 2, + 4, 0, 2, 2, 2, 2, 2, 2, 3, 2, + 3, 5, 0, 2, 2, 2, 2, 5, 7, 1, + 2, 2, 2, 2, 2, 4, 2, 2, 1, 1, + 3, 1, 3, 1, 1, 1, 5, 1, 1, 1, + 2, 1, 2, 1, 2, 1, 2, 4, 4, 5, + 10, 1, 3 +}; + +/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state + STATE-NUM when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const unsigned short yydefact[] = +{ + 3, 0, 2, 1, 0, 0, 0, 0, 183, 0, + 0, 0, 183, 54, 183, 22, 60, 10, 24, 11, + 27, 11, 9, 0, 0, 0, 0, 0, 0, 7, + 0, 0, 239, 0, 232, 5, 4, 0, 8, 0, + 0, 0, 217, 218, 258, 205, 196, 216, 0, 204, + 183, 206, 202, 207, 208, 210, 215, 208, 0, 208, + 0, 203, 212, 183, 183, 201, 257, 197, 261, 259, + 198, 263, 0, 265, 0, 224, 225, 184, 185, 0, + 0, 0, 234, 235, 0, 0, 55, 0, 61, 62, + 63, 64, 65, 0, 0, 68, 69, 70, 71, 72, + 73, 0, 76, 77, 0, 79, 0, 0, 83, 84, + 0, 0, 0, 0, 0, 90, 0, 92, 0, 94, + 0, 96, 97, 0, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 0, 109, 110, 111, 255, 112, 0, + 114, 253, 115, 116, 117, 0, 119, 120, 0, 0, + 0, 254, 0, 125, 126, 0, 0, 0, 57, 129, + 0, 0, 0, 0, 0, 219, 226, 236, 244, 23, + 25, 26, 6, 221, 241, 0, 240, 0, 0, 19, + 28, 29, 30, 260, 262, 209, 214, 213, 0, 211, + 199, 264, 266, 200, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 0, 0, 137, 0, 32, 173, + 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 147, 0, 0, + 147, 0, 0, 0, 0, 0, 0, 60, 56, 33, + 0, 17, 18, 0, 0, 15, 13, 12, 16, 37, + 35, 242, 243, 36, 54, 0, 54, 0, 233, 19, + 54, 0, 0, 31, 0, 139, 140, 143, 172, 54, + 0, 0, 0, 248, 249, 251, 268, 54, 54, 0, + 153, 149, 150, 151, 0, 152, 0, 0, 0, 0, + 171, 0, 169, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 145, 148, + 0, 0, 0, 0, 0, 0, 0, 271, 0, 0, + 58, 60, 0, 14, 220, 0, 222, 227, 0, 0, + 0, 54, 0, 54, 245, 21, 0, 0, 267, 136, + 144, 138, 0, 178, 256, 0, 55, 174, 0, 247, + 246, 0, 0, 0, 269, 66, 0, 164, 165, 163, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 67, 75, 74, 78, 80, 81, 82, 85, + 86, 87, 88, 89, 91, 93, 0, 147, 98, 108, + 0, 118, 121, 122, 123, 124, 0, 127, 128, 59, + 0, 223, 229, 0, 228, 231, 0, 19, 237, 130, + 20, 141, 142, 265, 177, 175, 250, 252, 181, 0, + 168, 0, 161, 162, 0, 155, 156, 158, 157, 159, + 160, 170, 95, 146, 0, 272, 34, 48, 230, 54, + 131, 0, 176, 0, 182, 167, 166, 0, 113, 147, + 179, 238, 0, 132, 154, 0, 0, 51, 38, 0, + 50, 0, 49, 257, 0, 43, 39, 41, 0, 0, + 0, 0, 270, 133, 52, 0, 180, 0, 0, 48, + 0, 54, 53, 42, 48, 38, 45, 54, 135, 38, + 44, 0, 134, 0, 47, 46 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const short yydefgoto[] = +{ + -1, 1, 2, 160, 260, 335, 18, 19, 20, 242, + 164, 21, 22, 464, 465, 466, 467, 450, 456, 336, + 86, 157, 158, 441, 459, 473, 24, 264, 265, 266, + 68, 307, 308, 290, 291, 292, 26, 269, 347, 348, + 337, 443, 79, 273, 69, 186, 70, 165, 28, 245, + 254, 326, 30, 31, 256, 331, 32, 178, 33, 34, + 246, 247, 168, 37, 248, 274, 275, 276, 159, 71, + 469, 40, 73, 318 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -447 +static const short yypact[] = +{ + -447, 43, 696, -447, 65, 655, -111, 97, 109, 35, + 78, 118, 109, -46, 109, -447, 809, -447, -447, -447, + -447, -447, -447, 66, -30, 2, 13, 16, -5, -447, + 26, 40, -447, 38, 76, -447, -447, 50, -447, 67, + 69, 71, -447, -447, -447, -447, -447, -447, 655, -447, + 129, -447, -447, -447, 161, -447, -447, 161, 91, 161, + 10, -447, -447, 182, 191, 10, -447, -447, -447, -447, + -447, -447, 587, -447, 235, -447, -447, -447, -447, 96, + 655, 102, -447, -447, 103, 655, -447, -94, -447, -447, + -447, -447, -447, 108, 110, -447, -447, -447, -447, -447, + -447, 112, -447, -447, 114, -447, 121, 127, -447, -447, + 130, 135, 136, 137, 138, -447, 142, -447, 144, -447, + 146, -447, -447, 147, -447, -447, -447, -447, -447, -447, + -447, -447, -447, 148, -447, -447, -447, -447, -447, 149, + -447, -447, -447, -447, -447, 152, -447, -447, 156, 158, + 159, -447, 160, -447, -447, 165, 166, -100, -447, -447, + 528, 665, 271, 201, 167, -447, -447, -447, -447, -447, + -447, -447, -447, -447, -447, 214, -447, 203, 168, -447, + -447, -447, -447, -447, 169, -447, -447, -447, 655, -447, + -447, 169, -82, -447, -447, -447, -447, -447, -447, -447, + -447, -447, -447, -447, 172, 173, 587, 587, -447, -447, + 223, 175, -447, 587, 246, 9, 305, 320, 99, 246, + 321, 323, 246, 326, 246, 587, 280, 246, -68, 246, + 246, 246, 655, 655, 329, 334, 655, 809, 195, -447, + 200, -447, -447, 220, 196, -447, -447, -447, -447, -447, + -447, -447, -447, -447, 72, 218, -61, 206, -447, -447, + 892, 208, 246, -447, 209, 225, -447, 207, -447, -25, + -21, 223, 223, -447, -447, -447, 228, -46, -19, 216, + -447, -447, -447, -447, 215, -447, 246, 246, 246, 500, + 532, -84, -447, 217, 221, 224, 226, 231, 239, 241, + 242, 243, 247, 248, 249, 250, 361, -79, -447, 532, + 254, 238, -76, 267, 261, 262, 263, 219, 264, 265, + -447, 809, 359, -447, -447, -16, -447, -447, 279, 655, + 270, 92, 347, 901, -447, -447, 655, 272, -447, -447, + -447, 587, 246, -447, -447, 655, 273, -447, 275, -447, + -447, 274, 223, 277, -447, -447, 655, -447, -447, -447, + 297, 278, 246, 246, 246, 246, 246, 246, 246, 246, + 246, 246, -447, -447, -447, -447, -447, -447, -447, -447, + -447, -447, -447, -447, -447, -447, 282, 246, -447, -447, + 246, -447, -447, -447, -447, -447, 416, -447, -447, -447, + 284, -447, -447, 223, -447, -447, 281, -447, -447, 314, + -447, -447, -447, 294, -447, -447, -447, -447, 587, 295, + -447, 246, -447, -447, 449, 64, 53, 14, 14, 212, + 212, -447, -447, -447, 300, -447, -447, 298, -447, 910, + -447, 223, -447, 301, -447, -447, -447, 246, -447, 375, + -447, -447, 306, -447, 532, 74, -93, -447, 269, -8, + -447, 246, 303, -60, 304, -447, 322, -447, 655, 223, + 246, 324, -447, -447, 532, 246, -447, 418, 223, -18, + 519, -71, 532, -447, -11, 269, -447, -71, -447, 269, + -447, 308, -447, 309, -447, -447 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const short yypgoto[] = +{ + -447, -447, -447, 437, -251, 7, -447, -447, 131, -447, + -447, -447, -447, -350, -447, -447, -7, -397, -447, -9, + -2, -447, -214, -447, -447, -447, -447, -447, -447, 120, + 3, 244, -357, -191, -447, -173, -447, 253, -446, -229, + 145, -447, 46, -70, -447, 34, 51, 20, -447, 466, + -447, -447, -12, -447, -447, -447, -447, -447, -10, -447, + 467, 4, -447, -447, 475, 211, -253, -447, 258, 5, + -4, -447, 1, -447 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what YYDEFACT says. + If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -185 +static const short yytable[] = +{ + 23, 72, 204, 41, 85, 25, 36, 39, 333, 17, + 270, 166, 280, 167, 281, 282, 293, 470, 350, 351, + 328, 211, 27, 320, 362, 363, 7, 330, 137, 471, + 433, 237, 141, -184, 74, 488, 309, 47, 461, 309, + 313, 492, 294, 3, 183, 298, 299, 371, 353, 302, + 238, 304, 387, 212, 151, 387, 311, 462, 84, 11, + 87, 283, 372, 362, 363, -184, 80, 388, 42, 43, + 391, -40, 54, 343, 362, 363, 207, 280, 16, 281, + 282, 210, 486, 55, 56, 81, -40, 490, 16, 339, + 57, 187, 457, 189, 4, 357, 358, 359, 360, 417, + 75, 76, 280, 16, 281, 282, 297, 399, 7, 84, + 87, 190, 77, 78, 169, 59, 193, 271, 284, 343, + 62, 82, 83, 344, 16, 343, 283, 485, 285, 354, + 16, 449, 184, 78, 489, 491, 267, 268, 449, 493, + 472, 11, 173, 279, 162, 286, 170, 287, 163, 288, + 437, 283, 369, 370, 289, 305, 439, 171, 243, 243, + 172, 41, 41, 25, 25, 39, 39, 241, 241, 412, + 174, 422, 423, 424, 425, 426, 427, 428, 429, 430, + 244, 244, 176, 284, 261, 191, 78, 175, 452, 367, + 368, 369, 370, 285, 192, 78, 309, 179, 431, 366, + 367, 368, 369, 370, 251, 252, 257, 258, 284, 177, + 286, 180, 287, 181, 288, 182, 479, 434, 285, 289, + 324, 16, 362, 363, 460, 484, 194, 195, 314, 315, + 446, 166, 319, 167, 185, 286, 188, 287, 196, 288, + 405, 16, 205, 206, 289, 325, 208, 329, 4, 280, + 209, 281, 282, 213, 270, 214, 454, 215, 309, 216, + 345, 41, 7, 25, 358, 39, 217, 346, 329, 345, + 474, 267, 218, 44, 250, 219, 346, 362, 363, 480, + 220, 221, 222, 223, 482, 361, 197, 224, 45, 225, + 46, 226, 227, 228, 229, 11, 47, 230, 283, 198, + 48, 231, 163, 232, 233, 234, 255, 362, 363, 199, + 235, 236, 295, 49, 253, 259, -184, 50, 51, 263, + 277, 200, 52, 262, 53, 403, 201, 296, 300, 401, + 301, 54, 409, 303, 41, 306, 25, 316, 39, 317, + 323, 403, 55, 56, 321, 322, 413, 202, 444, 57, + 203, 327, 419, 332, 338, 284, 341, 340, 342, 352, + 356, 271, 355, 373, 386, 285, 400, 374, 272, 390, + 375, 396, 376, 58, 59, 60, 61, 377, 280, 62, + 281, 282, 286, 63, 287, 378, 288, 379, 380, 381, + 64, 289, 65, 382, 383, 384, 385, 463, 67, 364, + 389, 365, 366, 367, 368, 369, 370, 393, 394, 395, + 397, 398, 402, 392, 404, 10, 410, 414, 16, 415, + 416, 435, 44, 418, 421, 438, 440, 283, 432, 364, + 436, 365, 366, 367, 368, 369, 370, 45, 442, 46, + 41, 445, 25, 420, 39, 47, 448, 449, 453, 48, + 476, 458, 475, 477, 494, 495, 468, 481, 161, 362, + 363, 411, 49, 407, 478, 278, 50, 51, 29, 35, + 483, 52, 345, 53, 312, 468, 406, 38, 345, 346, + 54, 349, 0, 468, 284, 346, 310, 468, 0, 0, + 0, 55, 56, 0, 285, 0, 0, 0, 57, 0, + 0, 0, 0, 280, 44, 281, 282, 0, 0, 0, + 0, 286, 0, 455, 0, 288, 0, 0, 0, 45, + 289, 46, 58, 59, 60, 61, 0, 47, 62, 362, + 363, 48, 63, 0, 0, 0, 0, 239, 0, 64, + 0, 65, 362, 363, 49, 0, 66, 67, 50, 51, + 0, 0, 283, 52, 0, 53, 4, 0, 0, 5, + 0, 0, 54, 0, 6, 0, 0, 16, 0, 0, + 7, 0, 0, 55, 56, 0, 8, 0, 0, 9, + 57, 364, 447, 365, 366, 367, 368, 369, 370, 0, + 194, 195, 0, 0, 0, 0, 10, 240, 0, 0, + 0, 0, 196, 11, 58, 59, 60, 61, 0, 284, + 62, 0, 0, 0, 63, 0, 0, 0, 0, 285, + 0, 64, 0, 65, 0, 0, 0, 0, 66, 67, + 0, 0, 0, 0, 0, 0, 286, 0, 287, 0, + 288, 0, 12, 0, 0, 289, 0, 0, 13, 14, + 197, 364, 487, 365, 366, 367, 368, 369, 370, 44, + 0, 0, 0, 198, 364, 0, 365, 366, 367, 368, + 369, 370, 15, 199, 45, 0, 46, 16, 0, 0, + 0, 0, 47, 0, 0, 200, 48, 0, 0, 0, + 201, 0, 0, 4, 0, 0, 5, 0, 0, 49, + 0, 6, 0, 50, 51, 0, 0, 7, 52, 0, + 53, 202, 0, 8, 203, 0, 9, 54, 0, 0, + 0, 0, 0, 0, 4, 0, 0, 5, 55, 56, + 0, 0, 6, 10, 240, 57, 0, 0, 7, 0, + 11, 0, 0, 0, 8, 0, 0, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, + 59, 60, 61, 0, 10, 62, 0, 0, 0, 63, + 0, 11, 0, 0, 0, 0, 64, 0, 65, 12, + 0, 0, 0, 66, 67, 13, 14, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, + 12, 0, 0, 249, 16, 0, 13, 14, 0, 0, + 0, 88, 0, 89, 90, 0, 91, 92, 0, 0, + 0, 0, 93, 0, 94, 0, 0, 0, 0, 0, + 15, 95, 96, 97, 98, 16, 99, 100, 101, 102, + 103, 0, 104, 0, 105, 106, 107, 0, 0, 108, + 0, 0, 0, 109, 0, 110, 111, 112, 113, 114, + 115, 0, 116, 117, 118, 119, 120, 0, 0, 121, + 0, 122, 0, 0, 0, 0, 123, 0, 124, 0, + 0, 0, 125, 126, 127, 128, 129, 130, 131, 132, + 133, 0, 134, 135, 136, 137, 138, 139, 140, 141, + 142, 143, 144, 0, 0, 0, 0, 145, 0, 0, + 146, 0, 147, 5, 0, 148, 149, 150, 6, 0, + 0, 151, 5, 152, 153, 154, 155, 6, 0, 156, + 8, 5, 0, 9, 0, 0, 6, 0, 0, 8, + 0, 0, 9, 0, 0, 0, 0, 0, 8, 0, + 10, 9, 0, 0, 0, 0, 0, 0, 0, 10, + 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 13, 14, 0, 12, 0, 0, 0, 0, + 0, 13, 14, 0, 12, 0, 0, 0, 0, 0, + 13, 14, 0, 0, 0, 0, 15, 0, 0, 0, + 334, 16, 0, 0, 0, 15, 0, 0, 0, 408, + 16, 0, 0, 0, 15, 0, 0, 0, 451, 16 +}; + +static const short yycheck[] = +{ + 2, 5, 72, 2, 13, 2, 2, 2, 259, 2, + 31, 23, 3, 23, 5, 6, 7, 25, 271, 272, + 81, 115, 2, 237, 10, 11, 42, 256, 96, 37, + 387, 131, 100, 115, 145, 481, 227, 27, 131, 230, + 231, 487, 215, 0, 48, 218, 219, 131, 277, 222, + 150, 224, 131, 147, 122, 131, 229, 150, 12, 75, + 14, 52, 146, 10, 11, 147, 31, 146, 3, 4, + 146, 131, 62, 144, 10, 11, 80, 3, 149, 5, + 6, 85, 479, 73, 74, 7, 146, 484, 149, 262, + 80, 57, 449, 59, 28, 286, 287, 288, 289, 352, + 3, 4, 3, 149, 5, 6, 7, 321, 42, 63, + 64, 60, 3, 4, 144, 105, 65, 138, 109, 144, + 110, 3, 4, 148, 149, 144, 52, 145, 119, 148, + 149, 149, 3, 4, 145, 485, 206, 207, 149, 489, + 148, 75, 147, 213, 78, 136, 144, 138, 82, 140, + 403, 52, 138, 139, 145, 225, 407, 144, 160, 161, + 144, 160, 161, 160, 161, 160, 161, 160, 161, 342, + 144, 362, 363, 364, 365, 366, 367, 368, 369, 370, + 160, 161, 144, 109, 188, 3, 4, 147, 441, 136, + 137, 138, 139, 119, 3, 4, 387, 147, 371, 135, + 136, 137, 138, 139, 3, 4, 3, 4, 109, 133, + 136, 144, 138, 144, 140, 144, 469, 390, 119, 145, + 148, 149, 10, 11, 150, 478, 3, 4, 232, 233, + 421, 243, 236, 243, 73, 136, 145, 138, 15, 140, + 148, 149, 7, 147, 145, 254, 144, 256, 28, 3, + 147, 5, 6, 145, 31, 145, 447, 145, 449, 145, + 269, 260, 42, 260, 455, 260, 145, 269, 277, 278, + 461, 341, 145, 4, 3, 145, 278, 10, 11, 470, + 145, 145, 145, 145, 475, 289, 63, 145, 19, 145, + 21, 145, 145, 145, 145, 75, 27, 145, 52, 76, + 31, 145, 82, 145, 145, 145, 92, 10, 11, 86, + 145, 145, 7, 44, 147, 147, 147, 48, 49, 146, + 145, 98, 53, 151, 55, 329, 103, 7, 7, 325, + 7, 62, 336, 7, 333, 55, 333, 8, 333, 5, + 144, 345, 73, 74, 149, 145, 345, 124, 418, 80, + 127, 133, 356, 147, 146, 109, 131, 148, 151, 131, + 145, 138, 146, 146, 3, 119, 7, 146, 145, 131, + 146, 152, 146, 104, 105, 106, 107, 146, 3, 110, + 5, 6, 136, 114, 138, 146, 140, 146, 146, 146, + 121, 145, 123, 146, 146, 146, 146, 128, 129, 132, + 146, 134, 135, 136, 137, 138, 139, 146, 146, 146, + 146, 146, 133, 146, 144, 68, 144, 144, 149, 144, + 146, 5, 4, 146, 146, 144, 112, 52, 146, 132, + 146, 134, 135, 136, 137, 138, 139, 19, 144, 21, + 439, 146, 439, 146, 439, 27, 146, 149, 147, 31, + 146, 145, 149, 131, 146, 146, 458, 133, 21, 10, + 11, 341, 44, 332, 468, 212, 48, 49, 2, 2, + 477, 53, 481, 55, 230, 477, 331, 2, 487, 481, + 62, 270, -1, 485, 109, 487, 228, 489, -1, -1, + -1, 73, 74, -1, 119, -1, -1, -1, 80, -1, + -1, -1, -1, 3, 4, 5, 6, -1, -1, -1, + -1, 136, -1, 138, -1, 140, -1, -1, -1, 19, + 145, 21, 104, 105, 106, 107, -1, 27, 110, 10, + 11, 31, 114, -1, -1, -1, -1, 9, -1, 121, + -1, 123, 10, 11, 44, -1, 128, 129, 48, 49, + -1, -1, 52, 53, -1, 55, 28, -1, -1, 31, + -1, -1, 62, -1, 36, -1, -1, 149, -1, -1, + 42, -1, -1, 73, 74, -1, 48, -1, -1, 51, + 80, 132, 133, 134, 135, 136, 137, 138, 139, -1, + 3, 4, -1, -1, -1, -1, 68, 69, -1, -1, + -1, -1, 15, 75, 104, 105, 106, 107, -1, 109, + 110, -1, -1, -1, 114, -1, -1, -1, -1, 119, + -1, 121, -1, 123, -1, -1, -1, -1, 128, 129, + -1, -1, -1, -1, -1, -1, 136, -1, 138, -1, + 140, -1, 114, -1, -1, 145, -1, -1, 120, 121, + 63, 132, 133, 134, 135, 136, 137, 138, 139, 4, + -1, -1, -1, 76, 132, -1, 134, 135, 136, 137, + 138, 139, 144, 86, 19, -1, 21, 149, -1, -1, + -1, -1, 27, -1, -1, 98, 31, -1, -1, -1, + 103, -1, -1, 28, -1, -1, 31, -1, -1, 44, + -1, 36, -1, 48, 49, -1, -1, 42, 53, -1, + 55, 124, -1, 48, 127, -1, 51, 62, -1, -1, + -1, -1, -1, -1, 28, -1, -1, 31, 73, 74, + -1, -1, 36, 68, 69, 80, -1, -1, 42, -1, + 75, -1, -1, -1, 48, -1, -1, 51, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 104, + 105, 106, 107, -1, 68, 110, -1, -1, -1, 114, + -1, 75, -1, -1, -1, -1, 121, -1, 123, 114, + -1, -1, -1, 128, 129, 120, 121, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 144, + 114, -1, -1, 148, 149, -1, 120, 121, -1, -1, + -1, 12, -1, 14, 15, -1, 17, 18, -1, -1, + -1, -1, 23, -1, 25, -1, -1, -1, -1, -1, + 144, 32, 33, 34, 35, 149, 37, 38, 39, 40, + 41, -1, 43, -1, 45, 46, 47, -1, -1, 50, + -1, -1, -1, 54, -1, 56, 57, 58, 59, 60, + 61, -1, 63, 64, 65, 66, 67, -1, -1, 70, + -1, 72, -1, -1, -1, -1, 77, -1, 79, -1, + -1, -1, 83, 84, 85, 86, 87, 88, 89, 90, + 91, -1, 93, 94, 95, 96, 97, 98, 99, 100, + 101, 102, 103, -1, -1, -1, -1, 108, -1, -1, + 111, -1, 113, 31, -1, 116, 117, 118, 36, -1, + -1, 122, 31, 124, 125, 126, 127, 36, -1, 130, + 48, 31, -1, 51, -1, -1, 36, -1, -1, 48, + -1, -1, 51, -1, -1, -1, -1, -1, 48, -1, + 68, 51, -1, -1, -1, -1, -1, -1, -1, 68, + -1, -1, -1, -1, -1, -1, -1, -1, 68, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 114, -1, -1, -1, + -1, -1, 120, 121, -1, 114, -1, -1, -1, -1, + -1, 120, 121, -1, 114, -1, -1, -1, -1, -1, + 120, 121, -1, -1, -1, -1, 144, -1, -1, -1, + 148, 149, -1, -1, -1, 144, -1, -1, -1, 148, + 149, -1, -1, -1, 144, -1, -1, -1, 148, 149 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const unsigned char yystos[] = +{ + 0, 154, 155, 0, 28, 31, 36, 42, 48, 51, + 68, 75, 114, 120, 121, 144, 149, 158, 159, 160, + 161, 164, 165, 173, 179, 183, 189, 200, 201, 202, + 205, 206, 209, 211, 212, 213, 214, 216, 217, 222, + 224, 225, 3, 4, 4, 19, 21, 27, 31, 44, + 48, 49, 53, 55, 62, 73, 74, 80, 104, 105, + 106, 107, 110, 114, 121, 123, 128, 129, 183, 197, + 199, 222, 223, 225, 145, 3, 4, 3, 4, 195, + 31, 7, 3, 4, 195, 172, 173, 195, 12, 14, + 15, 17, 18, 23, 25, 32, 33, 34, 35, 37, + 38, 39, 40, 41, 43, 45, 46, 47, 50, 54, + 56, 57, 58, 59, 60, 61, 63, 64, 65, 66, + 67, 70, 72, 77, 79, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 93, 94, 95, 96, 97, 98, + 99, 100, 101, 102, 103, 108, 111, 113, 116, 117, + 118, 122, 124, 125, 126, 127, 130, 174, 175, 221, + 156, 156, 78, 82, 163, 200, 205, 211, 215, 144, + 144, 144, 144, 147, 144, 147, 144, 133, 210, 147, + 144, 144, 144, 223, 3, 73, 198, 198, 145, 198, + 199, 3, 3, 199, 3, 4, 15, 63, 76, 86, + 98, 103, 124, 127, 196, 7, 147, 223, 144, 147, + 223, 115, 147, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 131, 150, 9, + 69, 158, 162, 173, 200, 202, 213, 214, 217, 148, + 3, 3, 4, 147, 203, 92, 207, 3, 4, 147, + 157, 223, 151, 146, 180, 181, 182, 196, 196, 190, + 31, 138, 145, 196, 218, 219, 220, 145, 190, 196, + 3, 5, 6, 52, 109, 119, 136, 138, 140, 145, + 186, 187, 188, 7, 188, 7, 7, 7, 188, 188, + 7, 7, 188, 7, 188, 196, 55, 184, 185, 186, + 221, 188, 184, 186, 223, 223, 8, 5, 226, 223, + 175, 149, 145, 144, 148, 172, 204, 133, 81, 172, + 192, 208, 147, 157, 148, 158, 172, 193, 146, 188, + 148, 131, 151, 144, 148, 172, 173, 191, 192, 218, + 219, 219, 131, 192, 148, 146, 145, 186, 186, 186, + 186, 223, 10, 11, 132, 134, 135, 136, 137, 138, + 139, 131, 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 3, 131, 146, 146, + 131, 146, 146, 146, 146, 146, 152, 146, 146, 175, + 7, 214, 133, 223, 144, 148, 193, 161, 148, 223, + 144, 182, 188, 225, 144, 144, 146, 219, 146, 223, + 146, 146, 186, 186, 186, 186, 186, 186, 186, 186, + 186, 188, 146, 185, 188, 5, 146, 219, 144, 157, + 112, 176, 144, 194, 196, 146, 186, 133, 146, 149, + 170, 148, 219, 147, 186, 138, 171, 185, 145, 177, + 150, 131, 150, 128, 166, 167, 168, 169, 173, 223, + 25, 37, 148, 178, 186, 149, 146, 131, 223, 219, + 186, 133, 186, 169, 219, 145, 170, 133, 191, 145, + 170, 166, 191, 166, 146, 146 +}; + +#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) +# define YYSIZE_T __SIZE_TYPE__ +#endif +#if ! defined (YYSIZE_T) && defined (size_t) +# define YYSIZE_T size_t +#endif +#if ! defined (YYSIZE_T) +# if defined (__STDC__) || defined (__cplusplus) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# endif +#endif +#if ! defined (YYSIZE_T) +# define YYSIZE_T unsigned int +#endif + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrlab1 + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. */ + +#define YYFAIL goto yyerrlab + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ + YYPOPSTACK; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror ("syntax error: cannot back up");\ + YYERROR; \ + } \ +while (0) + +#define YYTERROR 1 +#define YYERRCODE 256 + +/* YYLLOC_DEFAULT -- Compute the default location (before the actions + are run). */ + +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + Current.first_line = Rhs[1].first_line; \ + Current.first_column = Rhs[1].first_column; \ + Current.last_line = Rhs[N].last_line; \ + Current.last_column = Rhs[N].last_column; +#endif + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (YYLEX_PARAM) +#else +# define YYLEX yylex () +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) + +# define YYDSYMPRINT(Args) \ +do { \ + if (yydebug) \ + yysymprint Args; \ +} while (0) + +# define YYDSYMPRINTF(Title, Token, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yysymprint (stderr, \ + Token, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (cinluded). | +`------------------------------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yy_stack_print (short *bottom, short *top) +#else +static void +yy_stack_print (bottom, top) + short *bottom; + short *top; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (/* Nothing. */; bottom <= top; ++bottom) + YYFPRINTF (stderr, " %d", *bottom); + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (0) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yy_reduce_print (int yyrule) +#else +static void +yy_reduce_print (yyrule) + int yyrule; +#endif +{ + int yyi; + unsigned int yylineno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", + yyrule - 1, yylineno); + /* Print the symbols being reduced, and their result. */ + for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) + YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]); + YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]); +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (Rule); \ +} while (0) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YYDSYMPRINT(Args) +# define YYDSYMPRINTF(Title, Token, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#if YYMAXDEPTH == 0 +# undef YYMAXDEPTH +#endif + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined (__GLIBC__) && defined (_STRING_H) +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +static YYSIZE_T +# if defined (__STDC__) || defined (__cplusplus) +yystrlen (const char *yystr) +# else +yystrlen (yystr) + const char *yystr; +# endif +{ + register const char *yys = yystr; + + while (*yys++ != '\0') + continue; + + return yys - yystr - 1; +} +# endif +# endif + +# ifndef yystpcpy +# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +static char * +# if defined (__STDC__) || defined (__cplusplus) +yystpcpy (char *yydest, const char *yysrc) +# else +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +# endif +{ + register char *yyd = yydest; + register const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +#endif /* !YYERROR_VERBOSE */ + + + +#if YYDEBUG +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) +#else +static void +yysymprint (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + /* Pacify ``unused variable'' warnings. */ + (void) yyvaluep; + + if (yytype < YYNTOKENS) + { + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); +# ifdef YYPRINT + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# endif + } + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + switch (yytype) + { + default: + break; + } + YYFPRINTF (yyoutput, ")"); +} + +#endif /* ! YYDEBUG */ +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yydestruct (int yytype, YYSTYPE *yyvaluep) +#else +static void +yydestruct (yytype, yyvaluep) + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + /* Pacify ``unused variable'' warnings. */ + (void) yyvaluep; + + switch (yytype) + { + + default: + break; + } +} + + +/* Prevent warnings from -Wmissing-prototypes. */ + +#ifdef YYPARSE_PARAM +# if defined (__STDC__) || defined (__cplusplus) +int yyparse (void *YYPARSE_PARAM); +# else +int yyparse (); +# endif +#else /* ! YYPARSE_PARAM */ +#if defined (__STDC__) || defined (__cplusplus) +int yyparse (void); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + + + +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; + +/* Number of syntax errors so far. */ +int yynerrs; + + + +/*----------. +| yyparse. | +`----------*/ + +#ifdef YYPARSE_PARAM +# if defined (__STDC__) || defined (__cplusplus) +int yyparse (void *YYPARSE_PARAM) +# else +int yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +# endif +#else /* ! YYPARSE_PARAM */ +#if defined (__STDC__) || defined (__cplusplus) +int +yyparse (void) +#else +int +yyparse () + +#endif +#endif +{ + + register int yystate; + register int yyn; + int yyresult; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + /* Lookahead token as an internal (translated) token number. */ + int yytoken = 0; + + /* Three stacks and their tools: + `yyss': related to states, + `yyvs': related to semantic values, + `yyls': related to locations. + + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + short yyssa[YYINITDEPTH]; + short *yyss = yyssa; + register short *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs = yyvsa; + register YYSTYPE *yyvsp; + + + +#define YYPOPSTACK (yyvsp--, yyssp--) + + YYSIZE_T yystacksize = YYINITDEPTH; + + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + + + /* When reducing, the number of symbols on the RHS of the reduced + rule. */ + int yylen; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + + yyssp = yyss; + yyvsp = yyvs; + + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. so pushing a state here evens the stacks. + */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + short *yyss1 = yyss; + + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow ("parser stack overflow", + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyoverflowlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyoverflowlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + short *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyoverflowlab; + YYSTACK_RELOCATE (yyss); + YYSTACK_RELOCATE (yyvs); + +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + +/* Do appropriate processing given the current state. */ +/* Read a lookahead token if we need one and don't already have one. */ +/* yyresume: */ + + /* First try to decide what to do without reference to lookahead token. */ + + yyn = yypact[yystate]; + if (yyn == YYPACT_NINF) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yyn == 0 || yyn == YYTABLE_NINF) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + if (yyn == YYFINAL) + YYACCEPT; + + /* Shift the lookahead token. */ + YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken])); + + /* Discard the token being shifted unless it is eof. */ + if (yychar != YYEOF) + yychar = YYEMPTY; + + *++yyvsp = yylval; + + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + yystate = yyn; + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 2: +#line 239 "parser.y" + { write_proxies(yyvsp[0].ifref); write_client(yyvsp[0].ifref); write_server(yyvsp[0].ifref); ;} + break; + + case 3: +#line 242 "parser.y" + { yyval.ifref = NULL; ;} + break; + + case 4: +#line 243 "parser.y" + { yyval.ifref = yyvsp[-1].ifref; ;} + break; + + case 5: +#line 244 "parser.y" + { yyval.ifref = make_ifref(yyvsp[0].type); LINK(yyval.ifref, yyvsp[-1].ifref); ;} + break; + + case 6: +#line 245 "parser.y" + { yyval.ifref = yyvsp[-2].ifref; + reg_type(yyvsp[-1].type, yyvsp[-1].type->name, 0); + if (!parse_only && do_header) write_coclass_forward(yyvsp[-1].type); + ;} + break; + + case 7: +#line 249 "parser.y" + { yyval.ifref = yyvsp[-1].ifref; + add_coclass(yyvsp[0].type); + reg_type(yyvsp[0].type, yyvsp[0].type->name, 0); + ;} + break; + + case 8: +#line 253 "parser.y" + { yyval.ifref = yyvsp[-1].ifref; add_module(yyvsp[0].type); ;} + break; + + case 9: +#line 254 "parser.y" + { yyval.ifref = yyvsp[-1].ifref; ;} + break; + + case 10: +#line 255 "parser.y" + { yyval.ifref = yyvsp[-1].ifref; ;} + break; + + case 11: +#line 258 "parser.y" + {;} + break; + + case 12: +#line 259 "parser.y" + { if (!parse_only) add_interface(yyvsp[0].type); ;} + break; + + case 13: +#line 260 "parser.y" + { if (!parse_only) add_interface(yyvsp[0].type); ;} + break; + + case 14: +#line 261 "parser.y" + { reg_type(yyvsp[-1].type, yyvsp[-1].type->name, 0); if (!parse_only && do_header) write_coclass_forward(yyvsp[-1].type); ;} + break; + + case 15: +#line 262 "parser.y" + { if (!parse_only) add_coclass(yyvsp[0].type); + reg_type(yyvsp[0].type, yyvsp[0].type->name, 0); + ;} + break; + + case 16: +#line 265 "parser.y" + { if (!parse_only) add_module(yyvsp[0].type); ;} + break; + + case 17: +#line 266 "parser.y" + {;} + break; + + case 18: +#line 267 "parser.y" + {;} + break; + + case 19: +#line 270 "parser.y" + { yyval.func = NULL; ;} + break; + + case 20: +#line 271 "parser.y" + { yyval.func = yyvsp[-1].func; LINK(yyval.func, yyvsp[-2].func); ;} + break; + + case 21: +#line 272 "parser.y" + { yyval.func = yyvsp[-1].func; ;} + break; + + case 22: +#line 275 "parser.y" + {;} + break; + + case 23: +#line 276 "parser.y" + { if (!parse_only && do_header) { write_constdef(yyvsp[-1].var); } ;} + break; + + case 24: +#line 277 "parser.y" + {;} + break; + + case 25: +#line 278 "parser.y" + { if (!parse_only && do_header) { write_type(header, yyvsp[-1].type, NULL, NULL); fprintf(header, ";\n\n"); } ;} + break; + + case 26: +#line 279 "parser.y" + { if (!parse_only && do_header) { write_externdef(yyvsp[-1].var); } ;} + break; + + case 27: +#line 280 "parser.y" + {;} + break; + + case 28: +#line 281 "parser.y" + { if (!parse_only && do_header) { write_type(header, yyvsp[-1].type, NULL, NULL); fprintf(header, ";\n\n"); } ;} + break; + + case 29: +#line 282 "parser.y" + {;} + break; + + case 30: +#line 283 "parser.y" + { if (!parse_only && do_header) { write_type(header, yyvsp[-1].type, NULL, NULL); fprintf(header, ";\n\n"); } ;} + break; + + case 31: +#line 286 "parser.y" + { if (!parse_only && do_header) fprintf(header, "%s\n", yyvsp[-1].str); ;} + break; + + case 32: +#line 288 "parser.y" + { assert(yychar == YYEMPTY); + if (!do_import(yyvsp[-1].str)) yychar = aEOF; ;} + break; + + case 33: +#line 291 "parser.y" + {;} + break; + + case 34: +#line 294 "parser.y" + { if(!parse_only) add_importlib(yyvsp[-1].str); ;} + break; + + case 35: +#line 297 "parser.y" + { yyval.str = yyvsp[0].str; ;} + break; + + case 36: +#line 299 "parser.y" + { start_typelib(yyvsp[-1].str, yyvsp[-2].attr); + if (!parse_only && do_header) write_library(yyvsp[-1].str, yyvsp[-2].attr); ;} + break; + + case 37: +#line 302 "parser.y" + { end_typelib(); ;} + break; + + case 38: +#line 305 "parser.y" + { yyval.var = NULL; ;} + break; + + case 40: +#line 309 "parser.y" + { yyval.var = NULL; ;} + break; + + case 42: +#line 313 "parser.y" + { LINK(yyvsp[0].var, yyvsp[-2].var); yyval.var = yyvsp[0].var; ;} + break; + + case 44: +#line 318 "parser.y" + { yyval.var = yyvsp[-1].var; + set_type(yyval.var, yyvsp[-2].tref, yyvsp[0].expr); + yyval.var->attrs = yyvsp[-3].attr; + ;} + break; + + case 45: +#line 322 "parser.y" + { yyval.var = yyvsp[-1].var; + set_type(yyval.var, yyvsp[-2].tref, yyvsp[0].expr); + ;} + break; + + case 46: +#line 325 "parser.y" + { yyval.var = yyvsp[-3].var; + yyval.var->ptr_level--; + set_type(yyval.var, yyvsp[-4].tref, NULL); + yyval.var->attrs = yyvsp[-5].attr; + yyval.var->args = yyvsp[-1].var; + ;} + break; + + case 47: +#line 331 "parser.y" + { yyval.var = yyvsp[-3].var; + yyval.var->ptr_level--; + set_type(yyval.var, yyvsp[-4].tref, NULL); + yyval.var->args = yyvsp[-1].var; + ;} + break; + + case 48: +#line 338 "parser.y" + { yyval.expr = NULL; ;} + break; + + case 49: +#line 339 "parser.y" + { yyval.expr = yyvsp[-1].expr; ;} + break; + + case 50: +#line 340 "parser.y" + { yyval.expr = make_expr(EXPR_VOID); ;} + break; + + case 52: +#line 344 "parser.y" + { LINK(yyvsp[0].expr, yyvsp[-2].expr); yyval.expr = yyvsp[0].expr; ;} + break; + + case 53: +#line 345 "parser.y" + { LINK(yyvsp[0].expr, yyvsp[-3].expr); yyval.expr = yyvsp[0].expr; ;} + break; + + case 54: +#line 348 "parser.y" + { yyval.attr = NULL; ;} + break; + + case 56: +#line 353 "parser.y" + { yyval.attr = yyvsp[-1].attr; + if (!yyval.attr) + yyerror("empty attribute lists unsupported"); + ;} + break; + + case 58: +#line 360 "parser.y" + { if (yyvsp[0].attr) { LINK(yyvsp[0].attr, yyvsp[-2].attr); yyval.attr = yyvsp[0].attr; } + else { yyval.attr = yyvsp[-2].attr; } + ;} + break; + + case 59: +#line 363 "parser.y" + { if (yyvsp[0].attr) { LINK(yyvsp[0].attr, yyvsp[-3].attr); yyval.attr = yyvsp[0].attr; } + else { yyval.attr = yyvsp[-3].attr; } + ;} + break; + + case 60: +#line 368 "parser.y" + { yyval.attr = NULL; ;} + break; + + case 61: +#line 369 "parser.y" + { yyval.attr = make_attr(ATTR_AGGREGATABLE); ;} + break; + + case 62: +#line 370 "parser.y" + { yyval.attr = make_attr(ATTR_APPOBJECT); ;} + break; + + case 63: +#line 371 "parser.y" + { yyval.attr = make_attr(ATTR_ASYNC); ;} + break; + + case 64: +#line 372 "parser.y" + { yyval.attr = make_attr(ATTR_AUTO_HANDLE); ;} + break; + + case 65: +#line 373 "parser.y" + { yyval.attr = make_attr(ATTR_BINDABLE); ;} + break; + + case 66: +#line 374 "parser.y" + { yyval.attr = make_attrp(ATTR_CALLAS, yyvsp[-1].var); ;} + break; + + case 67: +#line 375 "parser.y" + { yyval.attr = make_attrp(ATTR_CASE, yyvsp[-1].expr); ;} + break; + + case 68: +#line 376 "parser.y" + { yyval.attr = make_attrv(ATTR_CONTEXTHANDLE, 0); ;} + break; + + case 69: +#line 377 "parser.y" + { yyval.attr = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_DONT_SERIALIZE */ ;} + break; + + case 70: +#line 378 "parser.y" + { yyval.attr = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_SERIALIZE */ ;} + break; + + case 71: +#line 379 "parser.y" + { yyval.attr = make_attr(ATTR_CONTROL); ;} + break; + + case 72: +#line 380 "parser.y" + { yyval.attr = make_attr(ATTR_DEFAULT); ;} + break; + + case 73: +#line 381 "parser.y" + { yyval.attr = make_attr(ATTR_DEFAULTCOLLELEM); ;} + break; + + case 74: +#line 382 "parser.y" + { yyval.attr = make_attrp(ATTR_DEFAULTVALUE_EXPR, yyvsp[-1].expr); ;} + break; + + case 75: +#line 383 "parser.y" + { yyval.attr = make_attrp(ATTR_DEFAULTVALUE_STRING, yyvsp[-1].str); ;} + break; + + case 76: +#line 384 "parser.y" + { yyval.attr = make_attr(ATTR_DEFAULTVTABLE); ;} + break; + + case 77: +#line 385 "parser.y" + { yyval.attr = make_attr(ATTR_DISPLAYBIND); ;} + break; + + case 78: +#line 386 "parser.y" + { yyval.attr = make_attrp(ATTR_DLLNAME, yyvsp[-1].str); ;} + break; + + case 79: +#line 387 "parser.y" + { yyval.attr = make_attr(ATTR_DUAL); ;} + break; + + case 80: +#line 388 "parser.y" + { yyval.attr = make_attrp(ATTR_ENDPOINT, yyvsp[-1].str); ;} + break; + + case 81: +#line 389 "parser.y" + { yyval.attr = make_attrp(ATTR_ENTRY_STRING, yyvsp[-1].str); ;} + break; + + case 82: +#line 390 "parser.y" + { yyval.attr = make_attrp(ATTR_ENTRY_ORDINAL, yyvsp[-1].expr); ;} + break; + + case 83: +#line 391 "parser.y" + { yyval.attr = make_attr(ATTR_EXPLICIT_HANDLE); ;} + break; + + case 84: +#line 392 "parser.y" + { yyval.attr = make_attr(ATTR_HANDLE); ;} + break; + + case 85: +#line 393 "parser.y" + { yyval.attr = make_attrp(ATTR_HELPCONTEXT, yyvsp[-1].expr); ;} + break; + + case 86: +#line 394 "parser.y" + { yyval.attr = make_attrp(ATTR_HELPFILE, yyvsp[-1].str); ;} + break; + + case 87: +#line 395 "parser.y" + { yyval.attr = make_attrp(ATTR_HELPSTRING, yyvsp[-1].str); ;} + break; + + case 88: +#line 396 "parser.y" + { yyval.attr = make_attrp(ATTR_HELPSTRINGCONTEXT, yyvsp[-1].expr); ;} + break; + + case 89: +#line 397 "parser.y" + { yyval.attr = make_attrp(ATTR_HELPSTRINGDLL, yyvsp[-1].str); ;} + break; + + case 90: +#line 398 "parser.y" + { yyval.attr = make_attr(ATTR_HIDDEN); ;} + break; + + case 91: +#line 399 "parser.y" + { yyval.attr = make_attrp(ATTR_ID, yyvsp[-1].expr); ;} + break; + + case 92: +#line 400 "parser.y" + { yyval.attr = make_attr(ATTR_IDEMPOTENT); ;} + break; + + case 93: +#line 401 "parser.y" + { yyval.attr = make_attrp(ATTR_IIDIS, yyvsp[-1].var); ;} + break; + + case 94: +#line 402 "parser.y" + { yyval.attr = make_attr(ATTR_IMMEDIATEBIND); ;} + break; + + case 95: +#line 403 "parser.y" + { yyval.attr = make_attrp(ATTR_IMPLICIT_HANDLE, yyvsp[-1].str); ;} + break; + + case 96: +#line 404 "parser.y" + { yyval.attr = make_attr(ATTR_IN); ;} + break; + + case 97: +#line 405 "parser.y" + { yyval.attr = make_attr(ATTR_INPUTSYNC); ;} + break; + + case 98: +#line 406 "parser.y" + { yyval.attr = make_attrp(ATTR_LENGTHIS, yyvsp[-1].expr); ;} + break; + + case 99: +#line 407 "parser.y" + { yyval.attr = make_attr(ATTR_LOCAL); ;} + break; + + case 100: +#line 408 "parser.y" + { yyval.attr = make_attr(ATTR_NONBROWSABLE); ;} + break; + + case 101: +#line 409 "parser.y" + { yyval.attr = make_attr(ATTR_NONCREATABLE); ;} + break; + + case 102: +#line 410 "parser.y" + { yyval.attr = make_attr(ATTR_NONEXTENSIBLE); ;} + break; + + case 103: +#line 411 "parser.y" + { yyval.attr = make_attr(ATTR_OBJECT); ;} + break; + + case 104: +#line 412 "parser.y" + { yyval.attr = make_attr(ATTR_ODL); ;} + break; + + case 105: +#line 413 "parser.y" + { yyval.attr = make_attr(ATTR_OLEAUTOMATION); ;} + break; + + case 106: +#line 414 "parser.y" + { yyval.attr = make_attr(ATTR_OPTIONAL); ;} + break; + + case 107: +#line 415 "parser.y" + { yyval.attr = make_attr(ATTR_OUT); ;} + break; + + case 108: +#line 416 "parser.y" + { yyval.attr = make_attrv(ATTR_POINTERDEFAULT, yyvsp[-1].num); ;} + break; + + case 109: +#line 417 "parser.y" + { yyval.attr = make_attr(ATTR_PROPGET); ;} + break; + + case 110: +#line 418 "parser.y" + { yyval.attr = make_attr(ATTR_PROPPUT); ;} + break; + + case 111: +#line 419 "parser.y" + { yyval.attr = make_attr(ATTR_PROPPUTREF); ;} + break; + + case 112: +#line 420 "parser.y" + { yyval.attr = make_attr(ATTR_PUBLIC); ;} + break; + + case 113: +#line 421 "parser.y" + { LINK(yyvsp[-1].expr, yyvsp[-3].expr); yyval.attr = make_attrp(ATTR_RANGE, yyvsp[-1].expr); ;} + break; + + case 114: +#line 422 "parser.y" + { yyval.attr = make_attr(ATTR_READONLY); ;} + break; + + case 115: +#line 423 "parser.y" + { yyval.attr = make_attr(ATTR_REQUESTEDIT); ;} + break; + + case 116: +#line 424 "parser.y" + { yyval.attr = make_attr(ATTR_RESTRICTED); ;} + break; + + case 117: +#line 425 "parser.y" + { yyval.attr = make_attr(ATTR_RETVAL); ;} + break; + + case 118: +#line 426 "parser.y" + { yyval.attr = make_attrp(ATTR_SIZEIS, yyvsp[-1].expr); ;} + break; + + case 119: +#line 427 "parser.y" + { yyval.attr = make_attr(ATTR_SOURCE); ;} + break; + + case 120: +#line 428 "parser.y" + { yyval.attr = make_attr(ATTR_STRING); ;} + break; + + case 121: +#line 429 "parser.y" + { yyval.attr = make_attrp(ATTR_SWITCHIS, yyvsp[-1].expr); ;} + break; + + case 122: +#line 430 "parser.y" + { yyval.attr = make_attrp(ATTR_SWITCHTYPE, type_ref(yyvsp[-1].tref)); ;} + break; + + case 123: +#line 431 "parser.y" + { yyval.attr = make_attrp(ATTR_TRANSMITAS, type_ref(yyvsp[-1].tref)); ;} + break; + + case 124: +#line 432 "parser.y" + { yyval.attr = make_attrp(ATTR_UUID, yyvsp[-1].uuid); ;} + break; + + case 125: +#line 433 "parser.y" + { yyval.attr = make_attr(ATTR_V1ENUM); ;} + break; + + case 126: +#line 434 "parser.y" + { yyval.attr = make_attr(ATTR_VARARG); ;} + break; + + case 127: +#line 435 "parser.y" + { yyval.attr = make_attrv(ATTR_VERSION, yyvsp[-1].num); ;} + break; + + case 128: +#line 436 "parser.y" + { yyval.attr = make_attrp(ATTR_WIREMARSHAL, type_ref(yyvsp[-1].tref)); ;} + break; + + case 129: +#line 437 "parser.y" + { yyval.attr = make_attrv(ATTR_POINTERTYPE, yyvsp[0].num); ;} + break; + + case 132: +#line 444 "parser.y" + { yyval.var = NULL; ;} + break; + + case 133: +#line 445 "parser.y" + { if (yyvsp[0].var) { LINK(yyvsp[0].var, yyvsp[-1].var); yyval.var = yyvsp[0].var; } + else { yyval.var = yyvsp[-1].var; } + ;} + break; + + case 134: +#line 450 "parser.y" + { attr_t *a = make_attrp(ATTR_CASE, yyvsp[-2].expr); + yyval.var = yyvsp[0].var; if (!yyval.var) yyval.var = make_var(NULL); + LINK(a, yyval.var->attrs); yyval.var->attrs = a; + ;} + break; + + case 135: +#line 454 "parser.y" + { attr_t *a = make_attr(ATTR_DEFAULT); + yyval.var = yyvsp[0].var; if (!yyval.var) yyval.var = make_var(NULL); + LINK(a, yyval.var->attrs); yyval.var->attrs = a; + ;} + break; + + case 136: +#line 460 "parser.y" + { yyval.var = reg_const(yyvsp[-2].var); + set_type(yyval.var, yyvsp[-3].tref, NULL); + yyval.var->eval = yyvsp[0].expr; + ;} + break; + + case 137: +#line 466 "parser.y" + { yyval.var = NULL; ;} + break; + + case 138: +#line 467 "parser.y" + { yyval.var = yyvsp[-1].var; ;} + break; + + case 140: +#line 471 "parser.y" + { if (!yyval.var->eval) + yyval.var->eval = make_exprl(EXPR_NUM, 0 /* default for first enum entry */); + ;} + break; + + case 141: +#line 474 "parser.y" + { LINK(yyvsp[0].var, yyvsp[-2].var); yyval.var = yyvsp[0].var; + if (!yyval.var->eval) + yyval.var->eval = make_exprl(EXPR_NUM, yyvsp[-2].var->eval->cval + 1); + ;} + break; + + case 142: +#line 480 "parser.y" + { yyval.var = reg_const(yyvsp[-2].var); + yyval.var->eval = yyvsp[0].expr; + yyval.var->type = make_type(RPC_FC_LONG, &std_int); + ;} + break; + + case 143: +#line 484 "parser.y" + { yyval.var = reg_const(yyvsp[0].var); + yyval.var->type = make_type(RPC_FC_LONG, &std_int); + ;} + break; + + case 144: +#line 489 "parser.y" + { yyval.type = get_typev(RPC_FC_ENUM16, yyvsp[-3].var, tsENUM); + yyval.type->fields = yyvsp[-1].var; + yyval.type->defined = TRUE; + if(in_typelib) + add_enum(yyval.type); + ;} + break; + + case 146: +#line 498 "parser.y" + { LINK(yyvsp[0].expr, yyvsp[-2].expr); yyval.expr = yyvsp[0].expr; ;} + break; + + case 147: +#line 511 "parser.y" + { yyval.expr = make_expr(EXPR_VOID); ;} + break; + + case 149: +#line 515 "parser.y" + { yyval.expr = make_exprl(EXPR_NUM, yyvsp[0].num); ;} + break; + + case 150: +#line 516 "parser.y" + { yyval.expr = make_exprl(EXPR_HEXNUM, yyvsp[0].num); ;} + break; + + case 151: +#line 517 "parser.y" + { yyval.expr = make_exprl(EXPR_TRUEFALSE, 0); ;} + break; + + case 152: +#line 518 "parser.y" + { yyval.expr = make_exprl(EXPR_TRUEFALSE, 1); ;} + break; + + case 153: +#line 519 "parser.y" + { yyval.expr = make_exprs(EXPR_IDENTIFIER, yyvsp[0].str); ;} + break; + + case 154: +#line 520 "parser.y" + { yyval.expr = make_expr3(EXPR_COND, yyvsp[-4].expr, yyvsp[-2].expr, yyvsp[0].expr); ;} + break; + + case 155: +#line 521 "parser.y" + { yyval.expr = make_expr2(EXPR_OR , yyvsp[-2].expr, yyvsp[0].expr); ;} + break; + + case 156: +#line 522 "parser.y" + { yyval.expr = make_expr2(EXPR_AND, yyvsp[-2].expr, yyvsp[0].expr); ;} + break; + + case 157: +#line 523 "parser.y" + { yyval.expr = make_expr2(EXPR_ADD, yyvsp[-2].expr, yyvsp[0].expr); ;} + break; + + case 158: +#line 524 "parser.y" + { yyval.expr = make_expr2(EXPR_SUB, yyvsp[-2].expr, yyvsp[0].expr); ;} + break; + + case 159: +#line 525 "parser.y" + { yyval.expr = make_expr2(EXPR_MUL, yyvsp[-2].expr, yyvsp[0].expr); ;} + break; + + case 160: +#line 526 "parser.y" + { yyval.expr = make_expr2(EXPR_DIV, yyvsp[-2].expr, yyvsp[0].expr); ;} + break; + + case 161: +#line 527 "parser.y" + { yyval.expr = make_expr2(EXPR_SHL, yyvsp[-2].expr, yyvsp[0].expr); ;} + break; + + case 162: +#line 528 "parser.y" + { yyval.expr = make_expr2(EXPR_SHR, yyvsp[-2].expr, yyvsp[0].expr); ;} + break; + + case 163: +#line 529 "parser.y" + { yyval.expr = make_expr1(EXPR_NOT, yyvsp[0].expr); ;} + break; + + case 164: +#line 530 "parser.y" + { yyval.expr = make_expr1(EXPR_NEG, yyvsp[0].expr); ;} + break; + + case 165: +#line 531 "parser.y" + { yyval.expr = make_expr1(EXPR_PPTR, yyvsp[0].expr); ;} + break; + + case 166: +#line 532 "parser.y" + { yyval.expr = make_exprt(EXPR_CAST, yyvsp[-2].tref, yyvsp[0].expr); ;} + break; + + case 167: +#line 533 "parser.y" + { yyval.expr = make_exprt(EXPR_SIZEOF, yyvsp[-1].tref, NULL); ;} + break; + + case 168: +#line 534 "parser.y" + { yyval.expr = yyvsp[-1].expr; ;} + break; + + case 170: +#line 538 "parser.y" + { LINK(yyvsp[0].expr, yyvsp[-2].expr); yyval.expr = yyvsp[0].expr; ;} + break; + + case 171: +#line 541 "parser.y" + { yyval.expr = yyvsp[0].expr; + if (!yyval.expr->is_const) + yyerror("expression is not constant"); + ;} + break; + + case 172: +#line 547 "parser.y" + { yyval.var = yyvsp[0].var; + set_type(yyval.var, yyvsp[-1].tref, NULL); + ;} + break; + + case 173: +#line 552 "parser.y" + { yyval.var = NULL; ;} + break; + + case 174: +#line 553 "parser.y" + { if (yyvsp[0].var) { LINK(yyvsp[0].var, yyvsp[-1].var); yyval.var = yyvsp[0].var; } + else { yyval.var = yyvsp[-1].var; } + ;} + break; + + case 175: +#line 558 "parser.y" + { yyval.var = yyvsp[-1].var; ;} + break; + + case 176: +#line 559 "parser.y" + { yyval.var = make_var(NULL); yyval.var->type = yyvsp[-1].type; yyval.var->attrs = yyvsp[-2].attr; ;} + break; + + case 177: +#line 560 "parser.y" + { yyval.var = make_var(NULL); yyval.var->attrs = yyvsp[-1].attr; ;} + break; + + case 178: +#line 561 "parser.y" + { yyval.var = NULL; ;} + break; + + case 179: +#line 564 "parser.y" + { yyval.var = yyvsp[-1].var; set_type(yyval.var, yyvsp[-2].tref, yyvsp[0].expr); yyval.var->attrs = yyvsp[-3].attr; ;} + break; + + case 180: +#line 569 "parser.y" + { set_type(yyvsp[-3].var, yyvsp[-5].tref, NULL); + yyvsp[-3].var->attrs = yyvsp[-6].attr; + yyval.func = make_func(yyvsp[-3].var, yyvsp[-1].var); + if (is_attr(yyvsp[-3].var->attrs, ATTR_IN)) { + yyerror("inapplicable attribute [in] for function '%s'",yyval.func->def->name); + } + ;} + break; + + case 181: +#line 578 "parser.y" + { yyval.var = NULL; ;} + break; + + case 183: +#line 582 "parser.y" + { yyval.var = NULL; ;} + break; + + case 184: +#line 583 "parser.y" + { yyval.var = make_var(yyvsp[0].str); ;} + break; + + case 185: +#line 584 "parser.y" + { yyval.var = make_var(yyvsp[0].str); ;} + break; + + case 186: +#line 587 "parser.y" + { yyval.var = make_var(yyvsp[0].str); ;} + break; + + case 187: +#line 589 "parser.y" + { yyval.var = make_var(yyvsp[0].str); ;} + break; + + case 188: +#line 590 "parser.y" + { yyval.var = make_var(yyvsp[0].str); ;} + break; + + case 189: +#line 591 "parser.y" + { yyval.var = make_var(yyvsp[0].str); ;} + break; + + case 190: +#line 592 "parser.y" + { yyval.var = make_var(yyvsp[0].str); ;} + break; + + case 191: +#line 593 "parser.y" + { yyval.var = make_var(yyvsp[0].str); ;} + break; + + case 192: +#line 594 "parser.y" + { yyval.var = make_var(yyvsp[0].str); ;} + break; + + case 193: +#line 595 "parser.y" + { yyval.var = make_var(yyvsp[0].str); ;} + break; + + case 194: +#line 596 "parser.y" + { yyval.var = make_var(yyvsp[0].str); ;} + break; + + case 195: +#line 597 "parser.y" + { yyval.var = make_var(yyvsp[0].str); ;} + break; + + case 196: +#line 600 "parser.y" + { yyval.type = make_type(RPC_FC_BYTE, NULL); ;} + break; + + case 197: +#line 601 "parser.y" + { yyval.type = make_type(RPC_FC_WCHAR, NULL); ;} + break; + + case 199: +#line 603 "parser.y" + { yyval.type = yyvsp[0].type; yyval.type->sign = 1; ;} + break; + + case 200: +#line 604 "parser.y" + { yyval.type = yyvsp[0].type; yyval.type->sign = -1; + switch (yyval.type->type) { + case RPC_FC_CHAR: break; + case RPC_FC_SMALL: yyval.type->type = RPC_FC_USMALL; break; + case RPC_FC_SHORT: yyval.type->type = RPC_FC_USHORT; break; + case RPC_FC_LONG: yyval.type->type = RPC_FC_ULONG; break; + case RPC_FC_HYPER: + if (!yyval.type->ref) { yyval.type->ref = &std_uhyper; yyval.type->sign = 0; } + break; + default: break; + } + ;} + break; + + case 201: +#line 616 "parser.y" + { yyval.type = make_type(RPC_FC_ULONG, &std_int); yyval.type->sign = -1; ;} + break; + + case 202: +#line 617 "parser.y" + { yyval.type = make_type(RPC_FC_FLOAT, NULL); ;} + break; + + case 203: +#line 618 "parser.y" + { yyval.type = make_type(RPC_FC_FLOAT, NULL); ;} + break; + + case 204: +#line 619 "parser.y" + { yyval.type = make_type(RPC_FC_DOUBLE, NULL); ;} + break; + + case 205: +#line 620 "parser.y" + { yyval.type = make_type(RPC_FC_BYTE, &std_bool); /* ? */ ;} + break; + + case 206: +#line 621 "parser.y" + { yyval.type = make_type(RPC_FC_ERROR_STATUS_T, NULL); ;} + break; + + case 207: +#line 622 "parser.y" + { yyval.type = make_type(RPC_FC_BIND_PRIMITIVE, NULL); /* ? */ ;} + break; + + case 210: +#line 629 "parser.y" + { yyval.type = make_type(RPC_FC_LONG, &std_int); ;} + break; + + case 211: +#line 630 "parser.y" + { yyval.type = make_type(RPC_FC_SHORT, NULL); ;} + break; + + case 212: +#line 631 "parser.y" + { yyval.type = make_type(RPC_FC_SMALL, NULL); ;} + break; + + case 213: +#line 632 "parser.y" + { yyval.type = make_type(RPC_FC_LONG, NULL); ;} + break; + + case 214: +#line 633 "parser.y" + { yyval.type = make_type(RPC_FC_HYPER, NULL); ;} + break; + + case 215: +#line 634 "parser.y" + { yyval.type = make_type(RPC_FC_HYPER, &std_int64); ;} + break; + + case 216: +#line 635 "parser.y" + { yyval.type = make_type(RPC_FC_CHAR, NULL); ;} + break; + + case 217: +#line 638 "parser.y" + { yyval.type = make_class(yyvsp[0].str); ;} + break; + + case 218: +#line 639 "parser.y" + { yyval.type = find_type(yyvsp[0].str, 0); + if (yyval.type->defined) yyerror("multiple definition error"); + if (yyval.type->kind != TKIND_COCLASS) yyerror("%s was not declared a coclass", yyvsp[0].str); + ;} + break; + + case 219: +#line 645 "parser.y" + { yyval.type = yyvsp[0].type; + yyval.type->attrs = yyvsp[-1].attr; + if (!parse_only && do_header) + write_coclass(yyval.type); + ;} + break; + + case 220: +#line 652 "parser.y" + { yyval.type = yyvsp[-3].type; + yyval.type->ifaces = yyvsp[-1].ifref; + ;} + break; + + case 221: +#line 657 "parser.y" + { yyval.ifref = NULL; ;} + break; + + case 222: +#line 658 "parser.y" + { LINK(yyvsp[0].ifref, yyvsp[-1].ifref); yyval.ifref = yyvsp[0].ifref; ;} + break; + + case 223: +#line 662 "parser.y" + { yyval.ifref = make_ifref(yyvsp[0].type); yyval.ifref->attrs = yyvsp[-1].attr; ;} + break; + + case 224: +#line 665 "parser.y" + { yyval.type = get_type(0, yyvsp[0].str, 0); ;} + break; + + case 225: +#line 666 "parser.y" + { yyval.type = get_type(0, yyvsp[0].str, 0); ;} + break; + + case 226: +#line 669 "parser.y" + { attr_t *attrs; + yyval.type = yyvsp[0].type; + if (yyval.type->defined) yyerror("multiple definition error"); + attrs = make_attr(ATTR_DISPINTERFACE); + LINK(attrs, yyvsp[-1].attr); + yyval.type->attrs = attrs; + yyval.type->ref = find_type("IDispatch", 0); + if (!yyval.type->ref) yyerror("IDispatch is undefined"); + yyval.type->defined = TRUE; + if (!parse_only && do_header) write_forward(yyval.type); + ;} + break; + + case 227: +#line 682 "parser.y" + { yyval.var = NULL; ;} + break; + + case 228: +#line 683 "parser.y" + { LINK(yyvsp[-1].var, yyvsp[-2].var); yyval.var = yyvsp[-1].var; ;} + break; + + case 229: +#line 686 "parser.y" + { yyval.func = NULL; ;} + break; + + case 230: +#line 687 "parser.y" + { LINK(yyvsp[-1].func, yyvsp[-2].func); yyval.func = yyvsp[-1].func; ;} + break; + + case 231: +#line 693 "parser.y" + { yyval.type = yyvsp[-4].type; + yyval.type->fields = yyvsp[-2].var; + yyval.type->funcs = yyvsp[-1].func; + if (!parse_only && do_header) write_dispinterface(yyval.type); + ;} + break; + + case 232: +#line 705 "parser.y" + { yyval.type = NULL; ;} + break; + + case 233: +#line 706 "parser.y" + { yyval.type = find_type2(yyvsp[0].str, 0); ;} + break; + + case 234: +#line 709 "parser.y" + { yyval.type = get_type(RPC_FC_IP, yyvsp[0].str, 0); ;} + break; + + case 235: +#line 710 "parser.y" + { yyval.type = get_type(RPC_FC_IP, yyvsp[0].str, 0); ;} + break; + + case 236: +#line 713 "parser.y" + { yyval.type = yyvsp[0].type; + if (yyval.type->defined) yyerror("multiple definition error"); + yyval.type->attrs = yyvsp[-1].attr; + yyval.type->defined = TRUE; + if (!parse_only && do_header) write_forward(yyval.type); + ;} + break; + + case 237: +#line 722 "parser.y" + { yyval.type = yyvsp[-4].type; + yyval.type->ref = yyvsp[-3].type; + yyval.type->funcs = yyvsp[-1].func; + if (!parse_only && do_header) write_interface(yyval.type); + ;} + break; + + case 238: +#line 730 "parser.y" + { yyval.type = yyvsp[-6].type; + yyval.type->ref = find_type2(yyvsp[-4].str, 0); + if (!yyval.type->ref) yyerror("base class '%s' not found in import", yyvsp[-4].str); + yyval.type->funcs = yyvsp[-1].func; + if (!parse_only && do_header) write_interface(yyval.type); + ;} + break; + + case 239: +#line 736 "parser.y" + { yyval.type = yyvsp[0].type; ;} + break; + + case 240: +#line 740 "parser.y" + { yyval.type = yyvsp[-1].type; if (!parse_only && do_header) write_forward(yyval.type); ;} + break; + + case 241: +#line 741 "parser.y" + { yyval.type = yyvsp[-1].type; if (!parse_only && do_header) write_forward(yyval.type); ;} + break; + + case 242: +#line 744 "parser.y" + { yyval.type = make_type(0, NULL); yyval.type->name = yyvsp[0].str; ;} + break; + + case 243: +#line 745 "parser.y" + { yyval.type = make_type(0, NULL); yyval.type->name = yyvsp[0].str; ;} + break; + + case 244: +#line 748 "parser.y" + { yyval.type = yyvsp[0].type; + yyval.type->attrs = yyvsp[-1].attr; + ;} + break; + + case 245: +#line 753 "parser.y" + { yyval.type = yyvsp[-3].type; + yyval.type->funcs = yyvsp[-1].func; + /* FIXME: if (!parse_only && do_header) write_module($$); */ + ;} + break; + + case 246: +#line 759 "parser.y" + { yyval.var = yyvsp[0].var; yyval.var->ptr_level++; ;} + break; + + case 247: +#line 760 "parser.y" + { yyval.var = yyvsp[0].var; /* FIXME */ ;} + break; + + case 250: +#line 765 "parser.y" + { yyval.var = yyvsp[-1].var; ;} + break; + + case 252: +#line 770 "parser.y" + { LINK(yyvsp[0].var, yyvsp[-2].var); yyval.var = yyvsp[0].var; ;} + break; + + case 253: +#line 774 "parser.y" + { yyval.num = RPC_FC_RP; ;} + break; + + case 254: +#line 775 "parser.y" + { yyval.num = RPC_FC_UP; ;} + break; + + case 255: +#line 776 "parser.y" + { yyval.num = RPC_FC_FP; ;} + break; + + case 256: +#line 779 "parser.y" + { yyval.type = get_typev(RPC_FC_STRUCT, yyvsp[-3].var, tsSTRUCT); + /* overwrite RPC_FC_STRUCT with a more exact type */ + yyval.type->type = get_struct_type( yyvsp[-1].var ); + yyval.type->fields = yyvsp[-1].var; + yyval.type->defined = TRUE; + if(in_typelib) + add_struct(yyval.type); + ;} + break; + + case 257: +#line 789 "parser.y" + { yyval.tref = make_tref(NULL, make_type(0, NULL)); ;} + break; + + case 258: +#line 790 "parser.y" + { yyval.tref = make_tref(yyvsp[0].str, find_type(yyvsp[0].str, 0)); ;} + break; + + case 259: +#line 791 "parser.y" + { yyval.tref = make_tref(NULL, yyvsp[0].type); ;} + break; + + case 260: +#line 792 "parser.y" + { yyval.tref = uniq_tref(yyvsp[0].tref); yyval.tref->ref->is_const = TRUE; ;} + break; + + case 261: +#line 793 "parser.y" + { yyval.tref = make_tref(NULL, yyvsp[0].type); ;} + break; + + case 262: +#line 794 "parser.y" + { yyval.tref = make_tref(NULL, find_type2(yyvsp[0].str, tsENUM)); ;} + break; + + case 263: +#line 795 "parser.y" + { yyval.tref = make_tref(NULL, yyvsp[0].type); ;} + break; + + case 264: +#line 796 "parser.y" + { yyval.tref = make_tref(NULL, get_type(RPC_FC_STRUCT, yyvsp[0].str, tsSTRUCT)); ;} + break; + + case 265: +#line 797 "parser.y" + { yyval.tref = make_tref(NULL, yyvsp[0].type); ;} + break; + + case 266: +#line 798 "parser.y" + { yyval.tref = make_tref(NULL, find_type2(yyvsp[0].str, tsUNION)); ;} + break; + + case 267: +#line 799 "parser.y" + { yyval.tref = make_tref(NULL, make_safearray()); ;} + break; + + case 268: +#line 802 "parser.y" + { typeref_t *tref = uniq_tref(yyvsp[-1].tref); + yyvsp[0].var->tname = tref->name; + tref->name = NULL; + yyval.type = type_ref(tref); + yyval.type->attrs = yyvsp[-2].attr; + if (!parse_only && do_header) + write_typedef(yyval.type, yyvsp[0].var); + if (in_typelib && yyval.type->attrs) + add_typedef(yyval.type, yyvsp[0].var); + reg_types(yyval.type, yyvsp[0].var, 0); + ;} + break; + + case 269: +#line 815 "parser.y" + { yyval.type = get_typev(RPC_FC_NON_ENCAPSULATED_UNION, yyvsp[-3].var, tsUNION); + yyval.type->fields = yyvsp[-1].var; + yyval.type->defined = TRUE; + ;} + break; + + case 270: +#line 821 "parser.y" + { var_t *u = yyvsp[-3].var; + yyval.type = get_typev(RPC_FC_ENCAPSULATED_UNION, yyvsp[-8].var, tsUNION); + if (!u) u = make_var("tagged_union"); + u->type = make_type(RPC_FC_NON_ENCAPSULATED_UNION, NULL); + u->type->fields = yyvsp[-1].var; + u->type->defined = TRUE; + LINK(u, yyvsp[-5].var); yyval.type->fields = u; + yyval.type->defined = TRUE; + ;} + break; + + case 271: +#line 833 "parser.y" + { yyval.num = MAKELONG(yyvsp[0].num, 0); ;} + break; + + case 272: +#line 834 "parser.y" + { yyval.num = MAKELONG(yyvsp[-2].num, yyvsp[0].num); ;} + break; + + + } + +/* Line 991 of yacc.c. */ +#line 3375 "parser.tab.c" + + yyvsp -= yylen; + yyssp -= yylen; + + + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if YYERROR_VERBOSE + yyn = yypact[yystate]; + + if (YYPACT_NINF < yyn && yyn < YYLAST) + { + YYSIZE_T yysize = 0; + int yytype = YYTRANSLATE (yychar); + char *yymsg; + int yyx, yycount; + + yycount = 0; + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + for (yyx = yyn < 0 ? -yyn : 0; + yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + yysize += yystrlen (yytname[yyx]) + 15, yycount++; + yysize += yystrlen ("syntax error, unexpected ") + 1; + yysize += yystrlen (yytname[yytype]); + yymsg = (char *) YYSTACK_ALLOC (yysize); + if (yymsg != 0) + { + char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); + yyp = yystpcpy (yyp, yytname[yytype]); + + if (yycount < 5) + { + yycount = 0; + for (yyx = yyn < 0 ? -yyn : 0; + yyx < (int) (sizeof (yytname) / sizeof (char *)); + yyx++) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + const char *yyq = ! yycount ? ", expecting " : " or "; + yyp = yystpcpy (yyp, yyq); + yyp = yystpcpy (yyp, yytname[yyx]); + yycount++; + } + } + yyerror (yymsg); + YYSTACK_FREE (yymsg); + } + else + yyerror ("syntax error; also virtual memory exhausted"); + } + else +#endif /* YYERROR_VERBOSE */ + yyerror ("syntax error"); + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + /* Return failure if at end of input. */ + if (yychar == YYEOF) + { + /* Pop the error token. */ + YYPOPSTACK; + /* Pop the rest of the stack. */ + while (yyss < yyssp) + { + YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); + yydestruct (yystos[*yyssp], yyvsp); + YYPOPSTACK; + } + YYABORT; + } + + YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); + yydestruct (yytoken, &yylval); + yychar = YYEMPTY; + + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab2; + + +/*----------------------------------------------------. +| yyerrlab1 -- error raised explicitly by an action. | +`----------------------------------------------------*/ +yyerrlab1: + + /* Suppress GCC warning that yyerrlab1 is unused when no action + invokes YYERROR. */ +#if defined (__GNUC_MINOR__) && 2093 <= (__GNUC__ * 1000 + __GNUC_MINOR__) + __attribute__ ((__unused__)) +#endif + + + goto yyerrlab2; + + +/*---------------------------------------------------------------. +| yyerrlab2 -- pop states until the error token can be shifted. | +`---------------------------------------------------------------*/ +yyerrlab2: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (yyn != YYPACT_NINF) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); + yydestruct (yystos[yystate], yyvsp); + yyvsp--; + yystate = *--yyssp; + + YY_STACK_PRINT (yyss, yyssp); + } + + if (yyn == YYFINAL) + YYACCEPT; + + YYDPRINTF ((stderr, "Shifting error token, ")); + + *++yyvsp = yylval; + + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#ifndef yyoverflow +/*----------------------------------------------. +| yyoverflowlab -- parser overflow comes here. | +`----------------------------------------------*/ +yyoverflowlab: + yyerror ("parser stack overflow"); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif + return yyresult; +} + + +#line 837 "parser.y" + + +static attr_t *make_attr(enum attr_type type) +{ + attr_t *a = xmalloc(sizeof(attr_t)); + a->type = type; + a->u.ival = 0; + INIT_LINK(a); + return a; +} + +static attr_t *make_attrv(enum attr_type type, unsigned long val) +{ + attr_t *a = xmalloc(sizeof(attr_t)); + a->type = type; + a->u.ival = val; + INIT_LINK(a); + return a; +} + +static attr_t *make_attrp(enum attr_type type, void *val) +{ + attr_t *a = xmalloc(sizeof(attr_t)); + a->type = type; + a->u.pval = val; + INIT_LINK(a); + return a; +} + +static expr_t *make_expr(enum expr_type type) +{ + expr_t *e = xmalloc(sizeof(expr_t)); + e->type = type; + e->ref = NULL; + e->u.lval = 0; + e->is_const = FALSE; + INIT_LINK(e); + return e; +} + +static expr_t *make_exprl(enum expr_type type, long val) +{ + expr_t *e = xmalloc(sizeof(expr_t)); + e->type = type; + e->ref = NULL; + e->u.lval = val; + e->is_const = FALSE; + INIT_LINK(e); + /* check for numeric constant */ + if (type == EXPR_NUM || type == EXPR_HEXNUM || type == EXPR_TRUEFALSE) { + /* make sure true/false value is valid */ + assert(type != EXPR_TRUEFALSE || val == 0 || val == 1); + e->is_const = TRUE; + e->cval = val; + } + return e; +} + +static expr_t *make_exprs(enum expr_type type, char *val) +{ + expr_t *e; + e = xmalloc(sizeof(expr_t)); + e->type = type; + e->ref = NULL; + e->u.sval = val; + e->is_const = FALSE; + INIT_LINK(e); + /* check for predefined constants */ + if (type == EXPR_IDENTIFIER) { + var_t *c = find_const(val, 0); + if (c) { + e->u.sval = c->name; + free(val); + e->is_const = TRUE; + e->cval = c->eval->cval; + } + } + return e; +} + +static expr_t *make_exprt(enum expr_type type, typeref_t *tref, expr_t *expr) +{ + expr_t *e; + e = xmalloc(sizeof(expr_t)); + e->type = type; + e->ref = expr; + e->u.tref = tref; + e->is_const = FALSE; + INIT_LINK(e); + /* check for cast of constant expression */ + if (type == EXPR_SIZEOF) { + switch (tref->ref->type) { + case RPC_FC_BYTE: + case RPC_FC_CHAR: + case RPC_FC_SMALL: + case RPC_FC_USMALL: + e->is_const = TRUE; + e->cval = 1; + break; + case RPC_FC_WCHAR: + case RPC_FC_USHORT: + case RPC_FC_SHORT: + e->is_const = TRUE; + e->cval = 2; + break; + case RPC_FC_LONG: + case RPC_FC_ULONG: + case RPC_FC_FLOAT: + case RPC_FC_ERROR_STATUS_T: + e->is_const = TRUE; + e->cval = 4; + break; + case RPC_FC_HYPER: + case RPC_FC_DOUBLE: + e->is_const = TRUE; + e->cval = 8; + break; + } + } + if (type == EXPR_CAST && expr->is_const) { + e->is_const = TRUE; + e->cval = expr->cval; + } + return e; +} + +static expr_t *make_expr1(enum expr_type type, expr_t *expr) +{ + expr_t *e; + e = xmalloc(sizeof(expr_t)); + e->type = type; + e->ref = expr; + e->u.lval = 0; + e->is_const = FALSE; + INIT_LINK(e); + /* check for compile-time optimization */ + if (expr->is_const) { + e->is_const = TRUE; + switch (type) { + case EXPR_NEG: + e->cval = -expr->cval; + break; + case EXPR_NOT: + e->cval = ~expr->cval; + break; + default: + e->is_const = FALSE; + break; + } + } + return e; +} + +static expr_t *make_expr2(enum expr_type type, expr_t *expr1, expr_t *expr2) +{ + expr_t *e; + e = xmalloc(sizeof(expr_t)); + e->type = type; + e->ref = expr1; + e->u.ext = expr2; + e->is_const = FALSE; + INIT_LINK(e); + /* check for compile-time optimization */ + if (expr1->is_const && expr2->is_const) { + e->is_const = TRUE; + switch (type) { + case EXPR_ADD: + e->cval = expr1->cval + expr2->cval; + break; + case EXPR_SUB: + e->cval = expr1->cval - expr2->cval; + break; + case EXPR_MUL: + e->cval = expr1->cval * expr2->cval; + break; + case EXPR_DIV: + e->cval = expr1->cval / expr2->cval; + break; + case EXPR_OR: + e->cval = expr1->cval | expr2->cval; + break; + case EXPR_AND: + e->cval = expr1->cval & expr2->cval; + break; + case EXPR_SHL: + e->cval = expr1->cval << expr2->cval; + break; + case EXPR_SHR: + e->cval = expr1->cval >> expr2->cval; + break; + default: + e->is_const = FALSE; + break; + } + } + return e; +} + +static expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, expr_t *expr3) +{ + expr_t *e; + e = xmalloc(sizeof(expr_t)); + e->type = type; + e->ref = expr1; + e->u.ext = expr2; + e->ext2 = expr3; + e->is_const = FALSE; + INIT_LINK(e); + /* check for compile-time optimization */ + if (expr1->is_const && expr2->is_const && expr3->is_const) { + e->is_const = TRUE; + switch (type) { + case EXPR_COND: + e->cval = expr1->cval ? expr2->cval : expr3->cval; + break; + default: + e->is_const = FALSE; + break; + } + } + return e; +} + +static type_t *make_type(unsigned char type, type_t *ref) +{ + type_t *t = xmalloc(sizeof(type_t)); + t->name = NULL; + t->kind = TKIND_PRIMITIVE; + t->type = type; + t->ref = ref; + t->attrs = NULL; + t->funcs = NULL; + t->fields = NULL; + t->ifaces = NULL; + t->ignore = parse_only; + t->is_const = FALSE; + t->sign = 0; + t->defined = FALSE; + t->written = FALSE; + t->typelib_idx = -1; + INIT_LINK(t); + return t; +} + +static typeref_t *make_tref(char *name, type_t *ref) +{ + typeref_t *t = xmalloc(sizeof(typeref_t)); + t->name = name; + t->ref = ref; + t->uniq = ref ? 0 : 1; + return t; +} + +static typeref_t *uniq_tref(typeref_t *ref) +{ + typeref_t *t = ref; + type_t *tp; + if (t->uniq) return t; + tp = make_type(0, t->ref); + tp->name = t->name; + t->name = NULL; + t->ref = tp; + t->uniq = 1; + return t; +} + +static type_t *type_ref(typeref_t *ref) +{ + type_t *t = ref->ref; + if (ref->name) free(ref->name); + free(ref); + return t; +} + +static void set_type(var_t *v, typeref_t *ref, expr_t *arr) +{ + v->type = ref->ref; + v->tname = ref->name; + ref->name = NULL; + free(ref); + v->array = arr; +} + +static ifref_t *make_ifref(type_t *iface) +{ + ifref_t *l = xmalloc(sizeof(ifref_t)); + l->iface = iface; + l->attrs = NULL; + INIT_LINK(l); + return l; +} + +static var_t *make_var(char *name) +{ + var_t *v = xmalloc(sizeof(var_t)); + v->name = name; + v->ptr_level = 0; + v->type = NULL; + v->tname = NULL; + v->attrs = NULL; + v->array = NULL; + v->eval = NULL; + INIT_LINK(v); + return v; +} + +static func_t *make_func(var_t *def, var_t *args) +{ + func_t *f = xmalloc(sizeof(func_t)); + f->def = def; + f->args = args; + f->ignore = parse_only; + f->idx = -1; + INIT_LINK(f); + return f; +} + +static type_t *make_class(char *name) +{ + type_t *c = make_type(0, NULL); + c->name = name; + c->kind = TKIND_COCLASS; + INIT_LINK(c); + return c; +} + +static type_t *make_safearray(void) +{ + return make_type(RPC_FC_FP, find_type("SAFEARRAY", 0)); +} + +#define HASHMAX 64 + +static int hash_ident(const char *name) +{ + const char *p = name; + int sum = 0; + /* a simple sum hash is probably good enough */ + while (*p) { + sum += *p; + p++; + } + return sum & (HASHMAX-1); +} + +/***** type repository *****/ + +struct rtype { + const char *name; + type_t *type; + int t; + struct rtype *next; +}; + +struct rtype *type_hash[HASHMAX]; + +static type_t *reg_type(type_t *type, const char *name, int t) +{ + struct rtype *nt; + int hash; + if (!name) { + yyerror("registering named type without name"); + return type; + } + hash = hash_ident(name); + nt = xmalloc(sizeof(struct rtype)); + nt->name = name; + nt->type = type; + nt->t = t; + nt->next = type_hash[hash]; + type_hash[hash] = nt; + return type; +} + +/* determine pointer type from attrs */ +static unsigned char get_pointer_type( type_t *type ) +{ + int t; + if (is_attr( type->attrs, ATTR_STRING )) + { + type_t *t = type; + while( t->type == 0 && t->ref ) + t = t->ref; + switch( t->type ) + { + case RPC_FC_CHAR: + return RPC_FC_C_CSTRING; + case RPC_FC_WCHAR: + return RPC_FC_C_WSTRING; + } + } + t = get_attrv( type->attrs, ATTR_POINTERTYPE ); + if (t) return t; + return RPC_FC_FP; +} + +static type_t *reg_types(type_t *type, var_t *names, int t) +{ + type_t *ptr = type; + int ptrc = 0; + + while (names) { + var_t *next = NEXT_LINK(names); + if (names->name) { + type_t *cur = ptr; + int cptr = names->ptr_level; + if (cptr > ptrc) { + while (cptr > ptrc) { + int t = get_pointer_type( cur ); + cur = ptr = make_type(t, cur); + ptrc++; + } + } else { + while (cptr < ptrc) { + cur = cur->ref; + cptr++; + } + } + reg_type(cur, names->name, t); + } + free(names); + names = next; + } + return type; +} + +static type_t *find_type(const char *name, int t) +{ + struct rtype *cur = type_hash[hash_ident(name)]; + while (cur && (cur->t != t || strcmp(cur->name, name))) + cur = cur->next; + if (!cur) { + yyerror("type '%s' not found", name); + return NULL; + } + return cur->type; +} + +static type_t *find_type2(char *name, int t) +{ + type_t *tp = find_type(name, t); + free(name); + return tp; +} + +int is_type(const char *name) +{ + struct rtype *cur = type_hash[hash_ident(name)]; + while (cur && (cur->t || strcmp(cur->name, name))) + cur = cur->next; + if (cur) return TRUE; + return FALSE; +} + +static type_t *get_type(unsigned char type, char *name, int t) +{ + struct rtype *cur = NULL; + type_t *tp; + if (name) { + cur = type_hash[hash_ident(name)]; + while (cur && (cur->t != t || strcmp(cur->name, name))) + cur = cur->next; + } + if (cur) { + free(name); + return cur->type; + } + tp = make_type(type, NULL); + tp->name = name; + if (!name) return tp; + return reg_type(tp, name, t); +} + +static type_t *get_typev(unsigned char type, var_t *name, int t) +{ + char *sname = NULL; + if (name) { + sname = name->name; + free(name); + } + return get_type(type, sname, t); +} + +static int get_struct_type(var_t *field) +{ + int has_pointer = 0; + int has_conformance = 0; + int has_variance = 0; + + for (; field; field = NEXT_LINK(field)) + { + type_t *t = field->type; + + /* get the base type */ + while( (t->type == 0) && t->ref ) + t = t->ref; + + if (field->ptr_level > 0) + { + has_pointer = 1; + continue; + } + + if (is_string_type(field->attrs, 0, field->array)) + { + has_conformance = 1; + has_variance = 1; + continue; + } + + if (is_array_type(field->attrs, 0, field->array)) + { + if (field->array && !field->array->is_const) + { + has_conformance = 1; + if (PREV_LINK(field)) + yyerror("field '%s' deriving from a conformant array must be the last field in the structure", + field->name); + } + if (is_attr(field->attrs, ATTR_LENGTHIS)) + has_variance = 1; + } + + switch (t->type) + { + /* + * RPC_FC_BYTE, RPC_FC_STRUCT, etc + * Simple types don't effect the type of struct. + * A struct containing a simple struct is still a simple struct. + * So long as we can block copy the data, we return RPC_FC_STRUCT. + */ + case 0: /* void pointer */ + case RPC_FC_BYTE: + case RPC_FC_CHAR: + case RPC_FC_SMALL: + case RPC_FC_USMALL: + case RPC_FC_WCHAR: + case RPC_FC_SHORT: + case RPC_FC_USHORT: + case RPC_FC_LONG: + case RPC_FC_ULONG: + case RPC_FC_INT3264: + case RPC_FC_UINT3264: + case RPC_FC_HYPER: + case RPC_FC_FLOAT: + case RPC_FC_DOUBLE: + case RPC_FC_STRUCT: + case RPC_FC_ENUM16: + case RPC_FC_ENUM32: + break; + + case RPC_FC_UP: + case RPC_FC_FP: + has_pointer = 1; + break; + case RPC_FC_CARRAY: + has_conformance = 1; + if (PREV_LINK(field)) + yyerror("field '%s' deriving from a conformant array must be the last field in the structure", + field->name); + break; + case RPC_FC_C_CSTRING: + case RPC_FC_C_WSTRING: + has_conformance = 1; + has_variance = 1; + break; + + /* + * Propagate member attributes + * a struct should be at least as complex as its member + */ + case RPC_FC_CVSTRUCT: + has_conformance = 1; + has_variance = 1; + has_pointer = 1; + break; + + case RPC_FC_CPSTRUCT: + has_conformance = 1; + if (PREV_LINK(field)) + yyerror("field '%s' deriving from a conformant array must be the last field in the structure", + field->name); + has_pointer = 1; + break; + + case RPC_FC_CSTRUCT: + has_conformance = 1; + if (PREV_LINK(field)) + yyerror("field '%s' deriving from a conformant array must be the last field in the structure", + field->name); + break; + + case RPC_FC_PSTRUCT: + has_pointer = 1; + break; + + default: + fprintf(stderr,"Unknown struct member %s with type (0x%02x)\n", + field->name, t->type); + /* fallthru - treat it as complex */ + + /* as soon as we see one of these these members, it's bogus... */ + case RPC_FC_IP: + case RPC_FC_ENCAPSULATED_UNION: + case RPC_FC_NON_ENCAPSULATED_UNION: + case RPC_FC_TRANSMIT_AS: + case RPC_FC_REPRESENT_AS: + case RPC_FC_PAD: + case RPC_FC_EMBEDDED_COMPLEX: + case RPC_FC_BOGUS_STRUCT: + return RPC_FC_BOGUS_STRUCT; + } + } + + if( has_variance ) + return RPC_FC_CVSTRUCT; + if( has_conformance && has_pointer ) + return RPC_FC_CPSTRUCT; + if( has_conformance ) + return RPC_FC_CSTRUCT; + if( has_pointer ) + return RPC_FC_PSTRUCT; + return RPC_FC_STRUCT; +} + +/***** constant repository *****/ + +struct rconst { + char *name; + var_t *var; + struct rconst *next; +}; + +struct rconst *const_hash[HASHMAX]; + +static var_t *reg_const(var_t *var) +{ + struct rconst *nc; + int hash; + if (!var->name) { + yyerror("registering constant without name"); + return var; + } + hash = hash_ident(var->name); + nc = xmalloc(sizeof(struct rconst)); + nc->name = var->name; + nc->var = var; + nc->next = const_hash[hash]; + const_hash[hash] = nc; + return var; +} + +static var_t *find_const(char *name, int f) +{ + struct rconst *cur = const_hash[hash_ident(name)]; + while (cur && strcmp(cur->name, name)) + cur = cur->next; + if (!cur) { + if (f) yyerror("constant '%s' not found", name); + return NULL; + } + return cur->var; +} + diff --git a/reactos/tools/widl_new/parser.tab.h b/reactos/tools/widl_new/parser.tab.h new file mode 100644 index 00000000000..8c33a70aa9f --- /dev/null +++ b/reactos/tools/widl_new/parser.tab.h @@ -0,0 +1,324 @@ +/* A Bison parser, made by GNU Bison 1.875. */ + +/* Skeleton parser for Yacc-like parsing with Bison, + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + aIDENTIFIER = 258, + aKNOWNTYPE = 259, + aNUM = 260, + aHEXNUM = 261, + aSTRING = 262, + aUUID = 263, + aEOF = 264, + SHL = 265, + SHR = 266, + tAGGREGATABLE = 267, + tALLOCATE = 268, + tAPPOBJECT = 269, + tASYNC = 270, + tASYNCUUID = 271, + tAUTOHANDLE = 272, + tBINDABLE = 273, + tBOOLEAN = 274, + tBROADCAST = 275, + tBYTE = 276, + tBYTECOUNT = 277, + tCALLAS = 278, + tCALLBACK = 279, + tCASE = 280, + tCDECL = 281, + tCHAR = 282, + tCOCLASS = 283, + tCODE = 284, + tCOMMSTATUS = 285, + tCONST = 286, + tCONTEXTHANDLE = 287, + tCONTEXTHANDLENOSERIALIZE = 288, + tCONTEXTHANDLESERIALIZE = 289, + tCONTROL = 290, + tCPPQUOTE = 291, + tDEFAULT = 292, + tDEFAULTCOLLELEM = 293, + tDEFAULTVALUE = 294, + tDEFAULTVTABLE = 295, + tDISPLAYBIND = 296, + tDISPINTERFACE = 297, + tDLLNAME = 298, + tDOUBLE = 299, + tDUAL = 300, + tENDPOINT = 301, + tENTRY = 302, + tENUM = 303, + tERRORSTATUST = 304, + tEXPLICITHANDLE = 305, + tEXTERN = 306, + tFALSE = 307, + tFLOAT = 308, + tHANDLE = 309, + tHANDLET = 310, + tHELPCONTEXT = 311, + tHELPFILE = 312, + tHELPSTRING = 313, + tHELPSTRINGCONTEXT = 314, + tHELPSTRINGDLL = 315, + tHIDDEN = 316, + tHYPER = 317, + tID = 318, + tIDEMPOTENT = 319, + tIIDIS = 320, + tIMMEDIATEBIND = 321, + tIMPLICITHANDLE = 322, + tIMPORT = 323, + tIMPORTLIB = 324, + tIN = 325, + tINLINE = 326, + tINPUTSYNC = 327, + tINT = 328, + tINT64 = 329, + tINTERFACE = 330, + tLCID = 331, + tLENGTHIS = 332, + tLIBRARY = 333, + tLOCAL = 334, + tLONG = 335, + tMETHODS = 336, + tMODULE = 337, + tNONBROWSABLE = 338, + tNONCREATABLE = 339, + tNONEXTENSIBLE = 340, + tOBJECT = 341, + tODL = 342, + tOLEAUTOMATION = 343, + tOPTIONAL = 344, + tOUT = 345, + tPOINTERDEFAULT = 346, + tPROPERTIES = 347, + tPROPGET = 348, + tPROPPUT = 349, + tPROPPUTREF = 350, + tPTR = 351, + tPUBLIC = 352, + tRANGE = 353, + tREADONLY = 354, + tREF = 355, + tREQUESTEDIT = 356, + tRESTRICTED = 357, + tRETVAL = 358, + tSAFEARRAY = 359, + tSHORT = 360, + tSIGNED = 361, + tSINGLE = 362, + tSIZEIS = 363, + tSIZEOF = 364, + tSMALL = 365, + tSOURCE = 366, + tSTDCALL = 367, + tSTRING = 368, + tSTRUCT = 369, + tSWITCH = 370, + tSWITCHIS = 371, + tSWITCHTYPE = 372, + tTRANSMITAS = 373, + tTRUE = 374, + tTYPEDEF = 375, + tUNION = 376, + tUNIQUE = 377, + tUNSIGNED = 378, + tUUID = 379, + tV1ENUM = 380, + tVARARG = 381, + tVERSION = 382, + tVOID = 383, + tWCHAR = 384, + tWIREMARSHAL = 385, + CAST = 386, + PPTR = 387, + NEG = 388 + }; +#endif +#define aIDENTIFIER 258 +#define aKNOWNTYPE 259 +#define aNUM 260 +#define aHEXNUM 261 +#define aSTRING 262 +#define aUUID 263 +#define aEOF 264 +#define SHL 265 +#define SHR 266 +#define tAGGREGATABLE 267 +#define tALLOCATE 268 +#define tAPPOBJECT 269 +#define tASYNC 270 +#define tASYNCUUID 271 +#define tAUTOHANDLE 272 +#define tBINDABLE 273 +#define tBOOLEAN 274 +#define tBROADCAST 275 +#define tBYTE 276 +#define tBYTECOUNT 277 +#define tCALLAS 278 +#define tCALLBACK 279 +#define tCASE 280 +#define tCDECL 281 +#define tCHAR 282 +#define tCOCLASS 283 +#define tCODE 284 +#define tCOMMSTATUS 285 +#define tCONST 286 +#define tCONTEXTHANDLE 287 +#define tCONTEXTHANDLENOSERIALIZE 288 +#define tCONTEXTHANDLESERIALIZE 289 +#define tCONTROL 290 +#define tCPPQUOTE 291 +#define tDEFAULT 292 +#define tDEFAULTCOLLELEM 293 +#define tDEFAULTVALUE 294 +#define tDEFAULTVTABLE 295 +#define tDISPLAYBIND 296 +#define tDISPINTERFACE 297 +#define tDLLNAME 298 +#define tDOUBLE 299 +#define tDUAL 300 +#define tENDPOINT 301 +#define tENTRY 302 +#define tENUM 303 +#define tERRORSTATUST 304 +#define tEXPLICITHANDLE 305 +#define tEXTERN 306 +#define tFALSE 307 +#define tFLOAT 308 +#define tHANDLE 309 +#define tHANDLET 310 +#define tHELPCONTEXT 311 +#define tHELPFILE 312 +#define tHELPSTRING 313 +#define tHELPSTRINGCONTEXT 314 +#define tHELPSTRINGDLL 315 +#define tHIDDEN 316 +#define tHYPER 317 +#define tID 318 +#define tIDEMPOTENT 319 +#define tIIDIS 320 +#define tIMMEDIATEBIND 321 +#define tIMPLICITHANDLE 322 +#define tIMPORT 323 +#define tIMPORTLIB 324 +#define tIN 325 +#define tINLINE 326 +#define tINPUTSYNC 327 +#define tINT 328 +#define tINT64 329 +#define tINTERFACE 330 +#define tLCID 331 +#define tLENGTHIS 332 +#define tLIBRARY 333 +#define tLOCAL 334 +#define tLONG 335 +#define tMETHODS 336 +#define tMODULE 337 +#define tNONBROWSABLE 338 +#define tNONCREATABLE 339 +#define tNONEXTENSIBLE 340 +#define tOBJECT 341 +#define tODL 342 +#define tOLEAUTOMATION 343 +#define tOPTIONAL 344 +#define tOUT 345 +#define tPOINTERDEFAULT 346 +#define tPROPERTIES 347 +#define tPROPGET 348 +#define tPROPPUT 349 +#define tPROPPUTREF 350 +#define tPTR 351 +#define tPUBLIC 352 +#define tRANGE 353 +#define tREADONLY 354 +#define tREF 355 +#define tREQUESTEDIT 356 +#define tRESTRICTED 357 +#define tRETVAL 358 +#define tSAFEARRAY 359 +#define tSHORT 360 +#define tSIGNED 361 +#define tSINGLE 362 +#define tSIZEIS 363 +#define tSIZEOF 364 +#define tSMALL 365 +#define tSOURCE 366 +#define tSTDCALL 367 +#define tSTRING 368 +#define tSTRUCT 369 +#define tSWITCH 370 +#define tSWITCHIS 371 +#define tSWITCHTYPE 372 +#define tTRANSMITAS 373 +#define tTRUE 374 +#define tTYPEDEF 375 +#define tUNION 376 +#define tUNIQUE 377 +#define tUNSIGNED 378 +#define tUUID 379 +#define tV1ENUM 380 +#define tVARARG 381 +#define tVERSION 382 +#define tVOID 383 +#define tWCHAR 384 +#define tWIREMARSHAL 385 +#define CAST 386 +#define PPTR 387 +#define NEG 388 + + + + +#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) +#line 109 "parser.y" +typedef union YYSTYPE { + attr_t *attr; + expr_t *expr; + type_t *type; + typeref_t *tref; + var_t *var; + func_t *func; + ifref_t *ifref; + char *str; + UUID *uuid; + unsigned int num; +} YYSTYPE; +/* Line 1248 of yacc.c. */ +#line 315 "parser.tab.h" +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 +#endif + +extern YYSTYPE yylval; + + + diff --git a/reactos/tools/widl_new/parser.y b/reactos/tools/widl_new/parser.y new file mode 100644 index 00000000000..b8e1c397a2d --- /dev/null +++ b/reactos/tools/widl_new/parser.y @@ -0,0 +1,1499 @@ +%{ +/* + * IDL Compiler + * + * Copyright 2002 Ove Kaaven + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#ifdef HAVE_ALLOCA_H +#include +#endif + +#include "windef.h" + +#include "widl.h" +#include "utils.h" +#include "parser.h" +#include "header.h" +#include "typelib.h" + +#if defined(YYBYACC) + /* Berkeley yacc (byacc) doesn't seem to know about these */ + /* Some *BSD supplied versions do define these though */ +# ifndef YYEMPTY +# define YYEMPTY (-1) /* Empty lookahead value of yychar */ +# endif +# ifndef YYLEX +# define YYLEX yylex() +# endif + +#elif defined(YYBISON) + /* Bison was used for original development */ + /* #define YYEMPTY -2 */ + /* #define YYLEX yylex() */ + +#else + /* No yacc we know yet */ +# if !defined(YYEMPTY) || !defined(YYLEX) +# error Yacc version/type unknown. This version needs to be verified for settings of YYEMPTY and YYLEX. +# elif defined(__GNUC__) /* gcc defines the #warning directive */ +# warning Yacc version/type unknown. It defines YYEMPTY and YYLEX, but is not tested + /* #else we just take a chance that it works... */ +# endif +#endif + +static attr_t *make_attr(enum attr_type type); +static attr_t *make_attrv(enum attr_type type, unsigned long val); +static attr_t *make_attrp(enum attr_type type, void *val); +static expr_t *make_expr(enum expr_type type); +static expr_t *make_exprl(enum expr_type type, long val); +static expr_t *make_exprs(enum expr_type type, char *val); +static expr_t *make_exprt(enum expr_type type, typeref_t *tref, expr_t *expr); +static expr_t *make_expr1(enum expr_type type, expr_t *expr); +static expr_t *make_expr2(enum expr_type type, expr_t *exp1, expr_t *exp2); +static expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, expr_t *expr3); +static type_t *make_type(unsigned char type, type_t *ref); +static typeref_t *make_tref(char *name, type_t *ref); +static typeref_t *uniq_tref(typeref_t *ref); +static type_t *type_ref(typeref_t *ref); +static void set_type(var_t *v, typeref_t *ref, expr_t *arr); +static ifref_t *make_ifref(type_t *iface); +static var_t *make_var(char *name); +static func_t *make_func(var_t *def, var_t *args); +static type_t *make_class(char *name); +static type_t *make_safearray(void); + +static type_t *reg_type(type_t *type, const char *name, int t); +static type_t *reg_types(type_t *type, var_t *names, int t); +static type_t *find_type(const char *name, int t); +static type_t *find_type2(char *name, int t); +static type_t *get_type(unsigned char type, char *name, int t); +static type_t *get_typev(unsigned char type, var_t *name, int t); +static int get_struct_type(var_t *fields); + +static var_t *reg_const(var_t *var); +static var_t *find_const(char *name, int f); + +#define tsENUM 1 +#define tsSTRUCT 2 +#define tsUNION 3 + +static type_t std_bool = { "boolean" }; +static type_t std_int = { "int" }; +static type_t std_int64 = { "__int64" }; +static type_t std_uhyper = { "MIDL_uhyper" }; + +%} +%union { + attr_t *attr; + expr_t *expr; + type_t *type; + typeref_t *tref; + var_t *var; + func_t *func; + ifref_t *ifref; + char *str; + UUID *uuid; + unsigned int num; +} + +%token aIDENTIFIER +%token aKNOWNTYPE +%token aNUM aHEXNUM +%token aSTRING +%token aUUID +%token aEOF +%token SHL SHR +%token tAGGREGATABLE tALLOCATE tAPPOBJECT tASYNC tASYNCUUID +%token tAUTOHANDLE tBINDABLE tBOOLEAN tBROADCAST tBYTE tBYTECOUNT +%token tCALLAS tCALLBACK tCASE tCDECL tCHAR tCOCLASS tCODE tCOMMSTATUS +%token tCONST tCONTEXTHANDLE tCONTEXTHANDLENOSERIALIZE +%token tCONTEXTHANDLESERIALIZE tCONTROL tCPPQUOTE +%token tDEFAULT +%token tDEFAULTCOLLELEM +%token tDEFAULTVALUE +%token tDEFAULTVTABLE +%token tDISPLAYBIND +%token tDISPINTERFACE +%token tDLLNAME tDOUBLE tDUAL +%token tENDPOINT +%token tENTRY tENUM tERRORSTATUST +%token tEXPLICITHANDLE tEXTERN +%token tFALSE +%token tFLOAT +%token tHANDLE +%token tHANDLET +%token tHELPCONTEXT tHELPFILE +%token tHELPSTRING tHELPSTRINGCONTEXT tHELPSTRINGDLL +%token tHIDDEN +%token tHYPER tID tIDEMPOTENT +%token tIIDIS +%token tIMMEDIATEBIND +%token tIMPLICITHANDLE +%token tIMPORT tIMPORTLIB +%token tIN tINLINE +%token tINPUTSYNC +%token tINT tINT64 +%token tINTERFACE +%token tLCID +%token tLENGTHIS tLIBRARY +%token tLOCAL +%token tLONG +%token tMETHODS +%token tMODULE +%token tNONBROWSABLE +%token tNONCREATABLE +%token tNONEXTENSIBLE +%token tOBJECT tODL tOLEAUTOMATION +%token tOPTIONAL +%token tOUT +%token tPOINTERDEFAULT +%token tPROPERTIES +%token tPROPGET tPROPPUT tPROPPUTREF +%token tPTR +%token tPUBLIC +%token tRANGE +%token tREADONLY tREF +%token tREQUESTEDIT +%token tRESTRICTED +%token tRETVAL +%token tSAFEARRAY +%token tSHORT +%token tSIGNED +%token tSINGLE +%token tSIZEIS tSIZEOF +%token tSMALL +%token tSOURCE +%token tSTDCALL +%token tSTRING tSTRUCT +%token tSWITCH tSWITCHIS tSWITCHTYPE +%token tTRANSMITAS +%token tTRUE +%token tTYPEDEF +%token tUNION +%token tUNIQUE +%token tUNSIGNED +%token tUUID +%token tV1ENUM +%token tVARARG +%token tVERSION +%token tVOID +%token tWCHAR tWIREMARSHAL + +%type m_attributes attributes attrib_list attribute +%type m_exprs /* exprs expr_list */ m_expr expr expr_list_const expr_const +%type array array_list +%type inherit interface interfacehdr interfacedef interfacedec +%type dispinterface dispinterfacehdr dispinterfacedef +%type module modulehdr moduledef +%type base_type int_std +%type enumdef structdef typedef uniondef +%type gbl_statements coclass_ints coclass_int +%type type +%type m_args no_args args arg +%type fields field s_field cases case enums enum_list enum constdef externdef +%type m_ident t_ident ident p_ident pident pident_list +%type dispint_props +%type funcdef int_statements +%type dispint_meths +%type coclass coclasshdr coclassdef +%type pointer_type version +%type libraryhdr + +%left ',' +%right '?' ':' +%left '|' +%left '&' +%left '-' '+' +%left '*' '/' +%left SHL SHR +%right '~' +%right CAST +%right PPTR +%right NEG + +%% + +input: gbl_statements { write_proxies($1); write_client($1); write_server($1); } + ; + +gbl_statements: { $$ = NULL; } + | gbl_statements interfacedec { $$ = $1; } + | gbl_statements interfacedef { $$ = make_ifref($2); LINK($$, $1); } + | gbl_statements coclass ';' { $$ = $1; + reg_type($2, $2->name, 0); + if (!parse_only && do_header) write_coclass_forward($2); + } + | gbl_statements coclassdef { $$ = $1; + add_coclass($2); + reg_type($2, $2->name, 0); + } + | gbl_statements moduledef { $$ = $1; add_module($2); } + | gbl_statements librarydef { $$ = $1; } + | gbl_statements statement { $$ = $1; } + ; + +imp_statements: {} + | imp_statements interfacedec { if (!parse_only) add_interface($2); } + | imp_statements interfacedef { if (!parse_only) add_interface($2); } + | imp_statements coclass ';' { reg_type($2, $2->name, 0); if (!parse_only && do_header) write_coclass_forward($2); } + | imp_statements coclassdef { if (!parse_only) add_coclass($2); + reg_type($2, $2->name, 0); + } + | imp_statements moduledef { if (!parse_only) add_module($2); } + | imp_statements statement {} + | imp_statements importlib {} + ; + +int_statements: { $$ = NULL; } + | int_statements funcdef ';' { $$ = $2; LINK($$, $1); } + | int_statements statement { $$ = $1; } + ; + +statement: ';' {} + | constdef ';' { if (!parse_only && do_header) { write_constdef($1); } } + | cppquote {} + | enumdef ';' { if (!parse_only && do_header) { write_type(header, $1, NULL, NULL); fprintf(header, ";\n\n"); } } + | externdef ';' { if (!parse_only && do_header) { write_externdef($1); } } + | import {} + | structdef ';' { if (!parse_only && do_header) { write_type(header, $1, NULL, NULL); fprintf(header, ";\n\n"); } } + | typedef ';' {} + | uniondef ';' { if (!parse_only && do_header) { write_type(header, $1, NULL, NULL); fprintf(header, ";\n\n"); } } + ; + +cppquote: tCPPQUOTE '(' aSTRING ')' { if (!parse_only && do_header) fprintf(header, "%s\n", $3); } + ; +import_start: tIMPORT aSTRING ';' { assert(yychar == YYEMPTY); + if (!do_import($2)) yychar = aEOF; } + ; +import: import_start imp_statements aEOF {} + ; + +importlib: tIMPORTLIB '(' aSTRING ')' { if(!parse_only) add_importlib($3); } + ; + +libraryhdr: tLIBRARY aIDENTIFIER { $$ = $2; } + ; +library_start: attributes libraryhdr '{' { start_typelib($2, $1); + if (!parse_only && do_header) write_library($2, $1); } + ; +librarydef: library_start imp_statements '}' { end_typelib(); } + ; + +m_args: { $$ = NULL; } + | args + ; + +no_args: tVOID { $$ = NULL; } + ; + +args: arg + | args ',' arg { LINK($3, $1); $$ = $3; } + | no_args + ; + +/* split into two rules to get bison to resolve a tVOID conflict */ +arg: attributes type pident array { $$ = $3; + set_type($$, $2, $4); + $$->attrs = $1; + } + | type pident array { $$ = $2; + set_type($$, $1, $3); + } + | attributes type pident '(' m_args ')' { $$ = $3; + $$->ptr_level--; + set_type($$, $2, NULL); + $$->attrs = $1; + $$->args = $5; + } + | type pident '(' m_args ')' { $$ = $2; + $$->ptr_level--; + set_type($$, $1, NULL); + $$->args = $4; + } + ; + +array: { $$ = NULL; } + | '[' array_list ']' { $$ = $2; } + | '[' '*' ']' { $$ = make_expr(EXPR_VOID); } + ; + +array_list: m_expr /* size of first dimension is optional */ + | array_list ',' expr { LINK($3, $1); $$ = $3; } + | array_list ']' '[' expr { LINK($4, $1); $$ = $4; } + ; + +m_attributes: { $$ = NULL; } + | attributes + ; + +attributes: + '[' attrib_list ']' { $$ = $2; + if (!$$) + yyerror("empty attribute lists unsupported"); + } + ; + +attrib_list: attribute + | attrib_list ',' attribute { if ($3) { LINK($3, $1); $$ = $3; } + else { $$ = $1; } + } + | attrib_list ']' '[' attribute { if ($4) { LINK($4, $1); $$ = $4; } + else { $$ = $1; } + } + ; + +attribute: { $$ = NULL; } + | tAGGREGATABLE { $$ = make_attr(ATTR_AGGREGATABLE); } + | tAPPOBJECT { $$ = make_attr(ATTR_APPOBJECT); } + | tASYNC { $$ = make_attr(ATTR_ASYNC); } + | tAUTOHANDLE { $$ = make_attr(ATTR_AUTO_HANDLE); } + | tBINDABLE { $$ = make_attr(ATTR_BINDABLE); } + | tCALLAS '(' ident ')' { $$ = make_attrp(ATTR_CALLAS, $3); } + | tCASE '(' expr_list_const ')' { $$ = make_attrp(ATTR_CASE, $3); } + | tCONTEXTHANDLE { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); } + | tCONTEXTHANDLENOSERIALIZE { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_DONT_SERIALIZE */ } + | tCONTEXTHANDLESERIALIZE { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_SERIALIZE */ } + | tCONTROL { $$ = make_attr(ATTR_CONTROL); } + | tDEFAULT { $$ = make_attr(ATTR_DEFAULT); } + | tDEFAULTCOLLELEM { $$ = make_attr(ATTR_DEFAULTCOLLELEM); } + | tDEFAULTVALUE '(' expr_const ')' { $$ = make_attrp(ATTR_DEFAULTVALUE_EXPR, $3); } + | tDEFAULTVALUE '(' aSTRING ')' { $$ = make_attrp(ATTR_DEFAULTVALUE_STRING, $3); } + | tDEFAULTVTABLE { $$ = make_attr(ATTR_DEFAULTVTABLE); } + | tDISPLAYBIND { $$ = make_attr(ATTR_DISPLAYBIND); } + | tDLLNAME '(' aSTRING ')' { $$ = make_attrp(ATTR_DLLNAME, $3); } + | tDUAL { $$ = make_attr(ATTR_DUAL); } + | tENDPOINT '(' aSTRING ')' { $$ = make_attrp(ATTR_ENDPOINT, $3); } + | tENTRY '(' aSTRING ')' { $$ = make_attrp(ATTR_ENTRY_STRING, $3); } + | tENTRY '(' expr_const ')' { $$ = make_attrp(ATTR_ENTRY_ORDINAL, $3); } + | tEXPLICITHANDLE { $$ = make_attr(ATTR_EXPLICIT_HANDLE); } + | tHANDLE { $$ = make_attr(ATTR_HANDLE); } + | tHELPCONTEXT '(' expr_const ')' { $$ = make_attrp(ATTR_HELPCONTEXT, $3); } + | tHELPFILE '(' aSTRING ')' { $$ = make_attrp(ATTR_HELPFILE, $3); } + | tHELPSTRING '(' aSTRING ')' { $$ = make_attrp(ATTR_HELPSTRING, $3); } + | tHELPSTRINGCONTEXT '(' expr_const ')' { $$ = make_attrp(ATTR_HELPSTRINGCONTEXT, $3); } + | tHELPSTRINGDLL '(' aSTRING ')' { $$ = make_attrp(ATTR_HELPSTRINGDLL, $3); } + | tHIDDEN { $$ = make_attr(ATTR_HIDDEN); } + | tID '(' expr_const ')' { $$ = make_attrp(ATTR_ID, $3); } + | tIDEMPOTENT { $$ = make_attr(ATTR_IDEMPOTENT); } + | tIIDIS '(' ident ')' { $$ = make_attrp(ATTR_IIDIS, $3); } + | tIMMEDIATEBIND { $$ = make_attr(ATTR_IMMEDIATEBIND); } + | tIMPLICITHANDLE '(' tHANDLET aIDENTIFIER ')' { $$ = make_attrp(ATTR_IMPLICIT_HANDLE, $4); } + | tIN { $$ = make_attr(ATTR_IN); } + | tINPUTSYNC { $$ = make_attr(ATTR_INPUTSYNC); } + | tLENGTHIS '(' m_exprs ')' { $$ = make_attrp(ATTR_LENGTHIS, $3); } + | tLOCAL { $$ = make_attr(ATTR_LOCAL); } + | tNONBROWSABLE { $$ = make_attr(ATTR_NONBROWSABLE); } + | tNONCREATABLE { $$ = make_attr(ATTR_NONCREATABLE); } + | tNONEXTENSIBLE { $$ = make_attr(ATTR_NONEXTENSIBLE); } + | tOBJECT { $$ = make_attr(ATTR_OBJECT); } + | tODL { $$ = make_attr(ATTR_ODL); } + | tOLEAUTOMATION { $$ = make_attr(ATTR_OLEAUTOMATION); } + | tOPTIONAL { $$ = make_attr(ATTR_OPTIONAL); } + | tOUT { $$ = make_attr(ATTR_OUT); } + | tPOINTERDEFAULT '(' pointer_type ')' { $$ = make_attrv(ATTR_POINTERDEFAULT, $3); } + | tPROPGET { $$ = make_attr(ATTR_PROPGET); } + | tPROPPUT { $$ = make_attr(ATTR_PROPPUT); } + | tPROPPUTREF { $$ = make_attr(ATTR_PROPPUTREF); } + | tPUBLIC { $$ = make_attr(ATTR_PUBLIC); } + | tRANGE '(' expr_const ',' expr_const ')' { LINK($5, $3); $$ = make_attrp(ATTR_RANGE, $5); } + | tREADONLY { $$ = make_attr(ATTR_READONLY); } + | tREQUESTEDIT { $$ = make_attr(ATTR_REQUESTEDIT); } + | tRESTRICTED { $$ = make_attr(ATTR_RESTRICTED); } + | tRETVAL { $$ = make_attr(ATTR_RETVAL); } + | tSIZEIS '(' m_exprs ')' { $$ = make_attrp(ATTR_SIZEIS, $3); } + | tSOURCE { $$ = make_attr(ATTR_SOURCE); } + | tSTRING { $$ = make_attr(ATTR_STRING); } + | tSWITCHIS '(' expr ')' { $$ = make_attrp(ATTR_SWITCHIS, $3); } + | tSWITCHTYPE '(' type ')' { $$ = make_attrp(ATTR_SWITCHTYPE, type_ref($3)); } + | tTRANSMITAS '(' type ')' { $$ = make_attrp(ATTR_TRANSMITAS, type_ref($3)); } + | tUUID '(' aUUID ')' { $$ = make_attrp(ATTR_UUID, $3); } + | tV1ENUM { $$ = make_attr(ATTR_V1ENUM); } + | tVARARG { $$ = make_attr(ATTR_VARARG); } + | tVERSION '(' version ')' { $$ = make_attrv(ATTR_VERSION, $3); } + | tWIREMARSHAL '(' type ')' { $$ = make_attrp(ATTR_WIREMARSHAL, type_ref($3)); } + | pointer_type { $$ = make_attrv(ATTR_POINTERTYPE, $1); } + ; + +callconv: + | tSTDCALL + ; + +cases: { $$ = NULL; } + | cases case { if ($2) { LINK($2, $1); $$ = $2; } + else { $$ = $1; } + } + ; + +case: tCASE expr ':' field { attr_t *a = make_attrp(ATTR_CASE, $2); + $$ = $4; if (!$$) $$ = make_var(NULL); + LINK(a, $$->attrs); $$->attrs = a; + } + | tDEFAULT ':' field { attr_t *a = make_attr(ATTR_DEFAULT); + $$ = $3; if (!$$) $$ = make_var(NULL); + LINK(a, $$->attrs); $$->attrs = a; + } + ; + +constdef: tCONST type ident '=' expr_const { $$ = reg_const($3); + set_type($$, $2, NULL); + $$->eval = $5; + } + ; + +enums: { $$ = NULL; } + | enum_list ',' { $$ = $1; } + | enum_list + ; + +enum_list: enum { if (!$$->eval) + $$->eval = make_exprl(EXPR_NUM, 0 /* default for first enum entry */); + } + | enum_list ',' enum { LINK($3, $1); $$ = $3; + if (!$$->eval) + $$->eval = make_exprl(EXPR_NUM, $1->eval->cval + 1); + } + ; + +enum: ident '=' expr_const { $$ = reg_const($1); + $$->eval = $3; + $$->type = make_type(RPC_FC_LONG, &std_int); + } + | ident { $$ = reg_const($1); + $$->type = make_type(RPC_FC_LONG, &std_int); + } + ; + +enumdef: tENUM t_ident '{' enums '}' { $$ = get_typev(RPC_FC_ENUM16, $2, tsENUM); + $$->fields = $4; + $$->defined = TRUE; + if(in_typelib) + add_enum($$); + } + ; + +m_exprs: m_expr + | m_exprs ',' m_expr { LINK($3, $1); $$ = $3; } + ; + +/* +exprs: { $$ = make_expr(EXPR_VOID); } + | expr_list + ; + +expr_list: expr + | expr_list ',' expr { LINK($3, $1); $$ = $3; } + ; +*/ + +m_expr: { $$ = make_expr(EXPR_VOID); } + | expr + ; + +expr: aNUM { $$ = make_exprl(EXPR_NUM, $1); } + | aHEXNUM { $$ = make_exprl(EXPR_HEXNUM, $1); } + | tFALSE { $$ = make_exprl(EXPR_TRUEFALSE, 0); } + | tTRUE { $$ = make_exprl(EXPR_TRUEFALSE, 1); } + | aIDENTIFIER { $$ = make_exprs(EXPR_IDENTIFIER, $1); } + | expr '?' expr ':' expr { $$ = make_expr3(EXPR_COND, $1, $3, $5); } + | expr '|' expr { $$ = make_expr2(EXPR_OR , $1, $3); } + | expr '&' expr { $$ = make_expr2(EXPR_AND, $1, $3); } + | expr '+' expr { $$ = make_expr2(EXPR_ADD, $1, $3); } + | expr '-' expr { $$ = make_expr2(EXPR_SUB, $1, $3); } + | expr '*' expr { $$ = make_expr2(EXPR_MUL, $1, $3); } + | expr '/' expr { $$ = make_expr2(EXPR_DIV, $1, $3); } + | expr SHL expr { $$ = make_expr2(EXPR_SHL, $1, $3); } + | expr SHR expr { $$ = make_expr2(EXPR_SHR, $1, $3); } + | '~' expr { $$ = make_expr1(EXPR_NOT, $2); } + | '-' expr %prec NEG { $$ = make_expr1(EXPR_NEG, $2); } + | '*' expr %prec PPTR { $$ = make_expr1(EXPR_PPTR, $2); } + | '(' type ')' expr %prec CAST { $$ = make_exprt(EXPR_CAST, $2, $4); } + | tSIZEOF '(' type ')' { $$ = make_exprt(EXPR_SIZEOF, $3, NULL); } + | '(' expr ')' { $$ = $2; } + ; + +expr_list_const: expr_const + | expr_list_const ',' expr_const { LINK($3, $1); $$ = $3; } + ; + +expr_const: expr { $$ = $1; + if (!$$->is_const) + yyerror("expression is not constant"); + } + ; + +externdef: tEXTERN tCONST type ident { $$ = $4; + set_type($$, $3, NULL); + } + ; + +fields: { $$ = NULL; } + | fields field { if ($2) { LINK($2, $1); $$ = $2; } + else { $$ = $1; } + } + ; + +field: s_field ';' { $$ = $1; } + | m_attributes uniondef ';' { $$ = make_var(NULL); $$->type = $2; $$->attrs = $1; } + | attributes ';' { $$ = make_var(NULL); $$->attrs = $1; } + | ';' { $$ = NULL; } + ; + +s_field: m_attributes type pident array { $$ = $3; set_type($$, $2, $4); $$->attrs = $1; } + ; + +funcdef: + m_attributes type callconv pident + '(' m_args ')' { set_type($4, $2, NULL); + $4->attrs = $1; + $$ = make_func($4, $6); + if (is_attr($4->attrs, ATTR_IN)) { + yyerror("inapplicable attribute [in] for function '%s'",$$->def->name); + } + } + ; + +m_ident: { $$ = NULL; } + | ident + ; + +t_ident: { $$ = NULL; } + | aIDENTIFIER { $$ = make_var($1); } + | aKNOWNTYPE { $$ = make_var($1); } + ; + +ident: aIDENTIFIER { $$ = make_var($1); } +/* some "reserved words" used in attributes are also used as field names in some MS IDL files */ + | aKNOWNTYPE { $$ = make_var($1); } + | tASYNC { $$ = make_var($1); } + | tID { $$ = make_var($1); } + | tLCID { $$ = make_var($1); } + | tOBJECT { $$ = make_var($1); } + | tRANGE { $$ = make_var($1); } + | tRETVAL { $$ = make_var($1); } + | tUUID { $$ = make_var($1); } + | tVERSION { $$ = make_var($1); } + ; + +base_type: tBYTE { $$ = make_type(RPC_FC_BYTE, NULL); } + | tWCHAR { $$ = make_type(RPC_FC_WCHAR, NULL); } + | int_std + | tSIGNED int_std { $$ = $2; $$->sign = 1; } + | tUNSIGNED int_std { $$ = $2; $$->sign = -1; + switch ($$->type) { + case RPC_FC_CHAR: break; + case RPC_FC_SMALL: $$->type = RPC_FC_USMALL; break; + case RPC_FC_SHORT: $$->type = RPC_FC_USHORT; break; + case RPC_FC_LONG: $$->type = RPC_FC_ULONG; break; + case RPC_FC_HYPER: + if (!$$->ref) { $$->ref = &std_uhyper; $$->sign = 0; } + break; + default: break; + } + } + | tUNSIGNED { $$ = make_type(RPC_FC_ULONG, &std_int); $$->sign = -1; } + | tFLOAT { $$ = make_type(RPC_FC_FLOAT, NULL); } + | tSINGLE { $$ = make_type(RPC_FC_FLOAT, NULL); } + | tDOUBLE { $$ = make_type(RPC_FC_DOUBLE, NULL); } + | tBOOLEAN { $$ = make_type(RPC_FC_BYTE, &std_bool); /* ? */ } + | tERRORSTATUST { $$ = make_type(RPC_FC_ERROR_STATUS_T, NULL); } + | tHANDLET { $$ = make_type(RPC_FC_BIND_PRIMITIVE, NULL); /* ? */ } + ; + +m_int: + | tINT + ; + +int_std: tINT { $$ = make_type(RPC_FC_LONG, &std_int); } /* win32 only */ + | tSHORT m_int { $$ = make_type(RPC_FC_SHORT, NULL); } + | tSMALL { $$ = make_type(RPC_FC_SMALL, NULL); } + | tLONG m_int { $$ = make_type(RPC_FC_LONG, NULL); } + | tHYPER m_int { $$ = make_type(RPC_FC_HYPER, NULL); } + | tINT64 { $$ = make_type(RPC_FC_HYPER, &std_int64); } + | tCHAR { $$ = make_type(RPC_FC_CHAR, NULL); } + ; + +coclass: tCOCLASS aIDENTIFIER { $$ = make_class($2); } + | tCOCLASS aKNOWNTYPE { $$ = find_type($2, 0); + if ($$->defined) yyerror("multiple definition error"); + if ($$->kind != TKIND_COCLASS) yyerror("%s was not declared a coclass", $2); + } + ; + +coclasshdr: attributes coclass { $$ = $2; + $$->attrs = $1; + if (!parse_only && do_header) + write_coclass($$); + } + ; + +coclassdef: coclasshdr '{' coclass_ints '}' { $$ = $1; + $$->ifaces = $3; + } + ; + +coclass_ints: { $$ = NULL; } + | coclass_ints coclass_int { LINK($2, $1); $$ = $2; } + ; + +coclass_int: + m_attributes interfacedec { $$ = make_ifref($2); $$->attrs = $1; } + ; + +dispinterface: tDISPINTERFACE aIDENTIFIER { $$ = get_type(0, $2, 0); } + | tDISPINTERFACE aKNOWNTYPE { $$ = get_type(0, $2, 0); } + ; + +dispinterfacehdr: attributes dispinterface { attr_t *attrs; + $$ = $2; + if ($$->defined) yyerror("multiple definition error"); + attrs = make_attr(ATTR_DISPINTERFACE); + LINK(attrs, $1); + $$->attrs = attrs; + $$->ref = find_type("IDispatch", 0); + if (!$$->ref) yyerror("IDispatch is undefined"); + $$->defined = TRUE; + if (!parse_only && do_header) write_forward($$); + } + ; + +dispint_props: tPROPERTIES ':' { $$ = NULL; } + | dispint_props s_field ';' { LINK($2, $1); $$ = $2; } + ; + +dispint_meths: tMETHODS ':' { $$ = NULL; } + | dispint_meths funcdef ';' { LINK($2, $1); $$ = $2; } + ; + +dispinterfacedef: dispinterfacehdr '{' + dispint_props + dispint_meths + '}' { $$ = $1; + $$->fields = $3; + $$->funcs = $4; + if (!parse_only && do_header) write_dispinterface($$); + } +/* FIXME: not sure how to handle this yet + | dispinterfacehdr '{' interface '}' { $$ = $1; + if (!parse_only && do_header) write_interface($$); + } +*/ + ; + +inherit: { $$ = NULL; } + | ':' aKNOWNTYPE { $$ = find_type2($2, 0); } + ; + +interface: tINTERFACE aIDENTIFIER { $$ = get_type(RPC_FC_IP, $2, 0); } + | tINTERFACE aKNOWNTYPE { $$ = get_type(RPC_FC_IP, $2, 0); } + ; + +interfacehdr: attributes interface { $$ = $2; + if ($$->defined) yyerror("multiple definition error"); + $$->attrs = $1; + $$->defined = TRUE; + if (!parse_only && do_header) write_forward($$); + } + ; + +interfacedef: interfacehdr inherit + '{' int_statements '}' { $$ = $1; + $$->ref = $2; + $$->funcs = $4; + if (!parse_only && do_header) write_interface($$); + } +/* MIDL is able to import the definition of a base class from inside the + * definition of a derived class, I'll try to support it with this rule */ + | interfacehdr ':' aIDENTIFIER + '{' import int_statements '}' { $$ = $1; + $$->ref = find_type2($3, 0); + if (!$$->ref) yyerror("base class '%s' not found in import", $3); + $$->funcs = $6; + if (!parse_only && do_header) write_interface($$); + } + | dispinterfacedef { $$ = $1; } + ; + +interfacedec: + interface ';' { $$ = $1; if (!parse_only && do_header) write_forward($$); } + | dispinterface ';' { $$ = $1; if (!parse_only && do_header) write_forward($$); } + ; + +module: tMODULE aIDENTIFIER { $$ = make_type(0, NULL); $$->name = $2; } + | tMODULE aKNOWNTYPE { $$ = make_type(0, NULL); $$->name = $2; } + ; + +modulehdr: attributes module { $$ = $2; + $$->attrs = $1; + } + ; + +moduledef: modulehdr '{' int_statements '}' { $$ = $1; + $$->funcs = $3; + /* FIXME: if (!parse_only && do_header) write_module($$); */ + } + ; + +p_ident: '*' pident %prec PPTR { $$ = $2; $$->ptr_level++; } + | tCONST p_ident { $$ = $2; /* FIXME */ } + ; + +pident: ident + | p_ident + | '(' pident ')' { $$ = $2; } + ; + +pident_list: + pident + | pident_list ',' pident { LINK($3, $1); $$ = $3; } + ; + +pointer_type: + tREF { $$ = RPC_FC_RP; } + | tUNIQUE { $$ = RPC_FC_UP; } + | tPTR { $$ = RPC_FC_FP; } + ; + +structdef: tSTRUCT t_ident '{' fields '}' { $$ = get_typev(RPC_FC_STRUCT, $2, tsSTRUCT); + /* overwrite RPC_FC_STRUCT with a more exact type */ + $$->type = get_struct_type( $4 ); + $$->fields = $4; + $$->defined = TRUE; + if(in_typelib) + add_struct($$); + } + ; + +type: tVOID { $$ = make_tref(NULL, make_type(0, NULL)); } + | aKNOWNTYPE { $$ = make_tref($1, find_type($1, 0)); } + | base_type { $$ = make_tref(NULL, $1); } + | tCONST type { $$ = uniq_tref($2); $$->ref->is_const = TRUE; } + | enumdef { $$ = make_tref(NULL, $1); } + | tENUM aIDENTIFIER { $$ = make_tref(NULL, find_type2($2, tsENUM)); } + | structdef { $$ = make_tref(NULL, $1); } + | tSTRUCT aIDENTIFIER { $$ = make_tref(NULL, get_type(RPC_FC_STRUCT, $2, tsSTRUCT)); } + | uniondef { $$ = make_tref(NULL, $1); } + | tUNION aIDENTIFIER { $$ = make_tref(NULL, find_type2($2, tsUNION)); } + | tSAFEARRAY '(' type ')' { $$ = make_tref(NULL, make_safearray()); } + ; + +typedef: tTYPEDEF m_attributes type pident_list { typeref_t *tref = uniq_tref($3); + $4->tname = tref->name; + tref->name = NULL; + $$ = type_ref(tref); + $$->attrs = $2; + if (!parse_only && do_header) + write_typedef($$, $4); + if (in_typelib && $$->attrs) + add_typedef($$, $4); + reg_types($$, $4, 0); + } + ; + +uniondef: tUNION t_ident '{' fields '}' { $$ = get_typev(RPC_FC_NON_ENCAPSULATED_UNION, $2, tsUNION); + $$->fields = $4; + $$->defined = TRUE; + } + | tUNION t_ident + tSWITCH '(' s_field ')' + m_ident '{' cases '}' { var_t *u = $7; + $$ = get_typev(RPC_FC_ENCAPSULATED_UNION, $2, tsUNION); + if (!u) u = make_var("tagged_union"); + u->type = make_type(RPC_FC_NON_ENCAPSULATED_UNION, NULL); + u->type->fields = $9; + u->type->defined = TRUE; + LINK(u, $5); $$->fields = u; + $$->defined = TRUE; + } + ; + +version: + aNUM { $$ = MAKELONG($1, 0); } + | aNUM '.' aNUM { $$ = MAKELONG($1, $3); } + ; + +%% + +static attr_t *make_attr(enum attr_type type) +{ + attr_t *a = xmalloc(sizeof(attr_t)); + a->type = type; + a->u.ival = 0; + INIT_LINK(a); + return a; +} + +static attr_t *make_attrv(enum attr_type type, unsigned long val) +{ + attr_t *a = xmalloc(sizeof(attr_t)); + a->type = type; + a->u.ival = val; + INIT_LINK(a); + return a; +} + +static attr_t *make_attrp(enum attr_type type, void *val) +{ + attr_t *a = xmalloc(sizeof(attr_t)); + a->type = type; + a->u.pval = val; + INIT_LINK(a); + return a; +} + +static expr_t *make_expr(enum expr_type type) +{ + expr_t *e = xmalloc(sizeof(expr_t)); + e->type = type; + e->ref = NULL; + e->u.lval = 0; + e->is_const = FALSE; + INIT_LINK(e); + return e; +} + +static expr_t *make_exprl(enum expr_type type, long val) +{ + expr_t *e = xmalloc(sizeof(expr_t)); + e->type = type; + e->ref = NULL; + e->u.lval = val; + e->is_const = FALSE; + INIT_LINK(e); + /* check for numeric constant */ + if (type == EXPR_NUM || type == EXPR_HEXNUM || type == EXPR_TRUEFALSE) { + /* make sure true/false value is valid */ + assert(type != EXPR_TRUEFALSE || val == 0 || val == 1); + e->is_const = TRUE; + e->cval = val; + } + return e; +} + +static expr_t *make_exprs(enum expr_type type, char *val) +{ + expr_t *e; + e = xmalloc(sizeof(expr_t)); + e->type = type; + e->ref = NULL; + e->u.sval = val; + e->is_const = FALSE; + INIT_LINK(e); + /* check for predefined constants */ + if (type == EXPR_IDENTIFIER) { + var_t *c = find_const(val, 0); + if (c) { + e->u.sval = c->name; + free(val); + e->is_const = TRUE; + e->cval = c->eval->cval; + } + } + return e; +} + +static expr_t *make_exprt(enum expr_type type, typeref_t *tref, expr_t *expr) +{ + expr_t *e; + e = xmalloc(sizeof(expr_t)); + e->type = type; + e->ref = expr; + e->u.tref = tref; + e->is_const = FALSE; + INIT_LINK(e); + /* check for cast of constant expression */ + if (type == EXPR_SIZEOF) { + switch (tref->ref->type) { + case RPC_FC_BYTE: + case RPC_FC_CHAR: + case RPC_FC_SMALL: + case RPC_FC_USMALL: + e->is_const = TRUE; + e->cval = 1; + break; + case RPC_FC_WCHAR: + case RPC_FC_USHORT: + case RPC_FC_SHORT: + e->is_const = TRUE; + e->cval = 2; + break; + case RPC_FC_LONG: + case RPC_FC_ULONG: + case RPC_FC_FLOAT: + case RPC_FC_ERROR_STATUS_T: + e->is_const = TRUE; + e->cval = 4; + break; + case RPC_FC_HYPER: + case RPC_FC_DOUBLE: + e->is_const = TRUE; + e->cval = 8; + break; + } + } + if (type == EXPR_CAST && expr->is_const) { + e->is_const = TRUE; + e->cval = expr->cval; + } + return e; +} + +static expr_t *make_expr1(enum expr_type type, expr_t *expr) +{ + expr_t *e; + e = xmalloc(sizeof(expr_t)); + e->type = type; + e->ref = expr; + e->u.lval = 0; + e->is_const = FALSE; + INIT_LINK(e); + /* check for compile-time optimization */ + if (expr->is_const) { + e->is_const = TRUE; + switch (type) { + case EXPR_NEG: + e->cval = -expr->cval; + break; + case EXPR_NOT: + e->cval = ~expr->cval; + break; + default: + e->is_const = FALSE; + break; + } + } + return e; +} + +static expr_t *make_expr2(enum expr_type type, expr_t *expr1, expr_t *expr2) +{ + expr_t *e; + e = xmalloc(sizeof(expr_t)); + e->type = type; + e->ref = expr1; + e->u.ext = expr2; + e->is_const = FALSE; + INIT_LINK(e); + /* check for compile-time optimization */ + if (expr1->is_const && expr2->is_const) { + e->is_const = TRUE; + switch (type) { + case EXPR_ADD: + e->cval = expr1->cval + expr2->cval; + break; + case EXPR_SUB: + e->cval = expr1->cval - expr2->cval; + break; + case EXPR_MUL: + e->cval = expr1->cval * expr2->cval; + break; + case EXPR_DIV: + e->cval = expr1->cval / expr2->cval; + break; + case EXPR_OR: + e->cval = expr1->cval | expr2->cval; + break; + case EXPR_AND: + e->cval = expr1->cval & expr2->cval; + break; + case EXPR_SHL: + e->cval = expr1->cval << expr2->cval; + break; + case EXPR_SHR: + e->cval = expr1->cval >> expr2->cval; + break; + default: + e->is_const = FALSE; + break; + } + } + return e; +} + +static expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, expr_t *expr3) +{ + expr_t *e; + e = xmalloc(sizeof(expr_t)); + e->type = type; + e->ref = expr1; + e->u.ext = expr2; + e->ext2 = expr3; + e->is_const = FALSE; + INIT_LINK(e); + /* check for compile-time optimization */ + if (expr1->is_const && expr2->is_const && expr3->is_const) { + e->is_const = TRUE; + switch (type) { + case EXPR_COND: + e->cval = expr1->cval ? expr2->cval : expr3->cval; + break; + default: + e->is_const = FALSE; + break; + } + } + return e; +} + +static type_t *make_type(unsigned char type, type_t *ref) +{ + type_t *t = xmalloc(sizeof(type_t)); + t->name = NULL; + t->kind = TKIND_PRIMITIVE; + t->type = type; + t->ref = ref; + t->attrs = NULL; + t->funcs = NULL; + t->fields = NULL; + t->ifaces = NULL; + t->ignore = parse_only; + t->is_const = FALSE; + t->sign = 0; + t->defined = FALSE; + t->written = FALSE; + t->typelib_idx = -1; + INIT_LINK(t); + return t; +} + +static typeref_t *make_tref(char *name, type_t *ref) +{ + typeref_t *t = xmalloc(sizeof(typeref_t)); + t->name = name; + t->ref = ref; + t->uniq = ref ? 0 : 1; + return t; +} + +static typeref_t *uniq_tref(typeref_t *ref) +{ + typeref_t *t = ref; + type_t *tp; + if (t->uniq) return t; + tp = make_type(0, t->ref); + tp->name = t->name; + t->name = NULL; + t->ref = tp; + t->uniq = 1; + return t; +} + +static type_t *type_ref(typeref_t *ref) +{ + type_t *t = ref->ref; + if (ref->name) free(ref->name); + free(ref); + return t; +} + +static void set_type(var_t *v, typeref_t *ref, expr_t *arr) +{ + v->type = ref->ref; + v->tname = ref->name; + ref->name = NULL; + free(ref); + v->array = arr; +} + +static ifref_t *make_ifref(type_t *iface) +{ + ifref_t *l = xmalloc(sizeof(ifref_t)); + l->iface = iface; + l->attrs = NULL; + INIT_LINK(l); + return l; +} + +static var_t *make_var(char *name) +{ + var_t *v = xmalloc(sizeof(var_t)); + v->name = name; + v->ptr_level = 0; + v->type = NULL; + v->tname = NULL; + v->attrs = NULL; + v->array = NULL; + v->eval = NULL; + INIT_LINK(v); + return v; +} + +static func_t *make_func(var_t *def, var_t *args) +{ + func_t *f = xmalloc(sizeof(func_t)); + f->def = def; + f->args = args; + f->ignore = parse_only; + f->idx = -1; + INIT_LINK(f); + return f; +} + +static type_t *make_class(char *name) +{ + type_t *c = make_type(0, NULL); + c->name = name; + c->kind = TKIND_COCLASS; + INIT_LINK(c); + return c; +} + +static type_t *make_safearray(void) +{ + return make_type(RPC_FC_FP, find_type("SAFEARRAY", 0)); +} + +#define HASHMAX 64 + +static int hash_ident(const char *name) +{ + const char *p = name; + int sum = 0; + /* a simple sum hash is probably good enough */ + while (*p) { + sum += *p; + p++; + } + return sum & (HASHMAX-1); +} + +/***** type repository *****/ + +struct rtype { + const char *name; + type_t *type; + int t; + struct rtype *next; +}; + +struct rtype *type_hash[HASHMAX]; + +static type_t *reg_type(type_t *type, const char *name, int t) +{ + struct rtype *nt; + int hash; + if (!name) { + yyerror("registering named type without name"); + return type; + } + hash = hash_ident(name); + nt = xmalloc(sizeof(struct rtype)); + nt->name = name; + nt->type = type; + nt->t = t; + nt->next = type_hash[hash]; + type_hash[hash] = nt; + return type; +} + +/* determine pointer type from attrs */ +static unsigned char get_pointer_type( type_t *type ) +{ + int t; + if (is_attr( type->attrs, ATTR_STRING )) + { + type_t *t = type; + while( t->type == 0 && t->ref ) + t = t->ref; + switch( t->type ) + { + case RPC_FC_CHAR: + return RPC_FC_C_CSTRING; + case RPC_FC_WCHAR: + return RPC_FC_C_WSTRING; + } + } + t = get_attrv( type->attrs, ATTR_POINTERTYPE ); + if (t) return t; + return RPC_FC_FP; +} + +static type_t *reg_types(type_t *type, var_t *names, int t) +{ + type_t *ptr = type; + int ptrc = 0; + + while (names) { + var_t *next = NEXT_LINK(names); + if (names->name) { + type_t *cur = ptr; + int cptr = names->ptr_level; + if (cptr > ptrc) { + while (cptr > ptrc) { + int t = get_pointer_type( cur ); + cur = ptr = make_type(t, cur); + ptrc++; + } + } else { + while (cptr < ptrc) { + cur = cur->ref; + cptr++; + } + } + reg_type(cur, names->name, t); + } + free(names); + names = next; + } + return type; +} + +static type_t *find_type(const char *name, int t) +{ + struct rtype *cur = type_hash[hash_ident(name)]; + while (cur && (cur->t != t || strcmp(cur->name, name))) + cur = cur->next; + if (!cur) { + yyerror("type '%s' not found", name); + return NULL; + } + return cur->type; +} + +static type_t *find_type2(char *name, int t) +{ + type_t *tp = find_type(name, t); + free(name); + return tp; +} + +int is_type(const char *name) +{ + struct rtype *cur = type_hash[hash_ident(name)]; + while (cur && (cur->t || strcmp(cur->name, name))) + cur = cur->next; + if (cur) return TRUE; + return FALSE; +} + +static type_t *get_type(unsigned char type, char *name, int t) +{ + struct rtype *cur = NULL; + type_t *tp; + if (name) { + cur = type_hash[hash_ident(name)]; + while (cur && (cur->t != t || strcmp(cur->name, name))) + cur = cur->next; + } + if (cur) { + free(name); + return cur->type; + } + tp = make_type(type, NULL); + tp->name = name; + if (!name) return tp; + return reg_type(tp, name, t); +} + +static type_t *get_typev(unsigned char type, var_t *name, int t) +{ + char *sname = NULL; + if (name) { + sname = name->name; + free(name); + } + return get_type(type, sname, t); +} + +static int get_struct_type(var_t *field) +{ + int has_pointer = 0; + int has_conformance = 0; + int has_variance = 0; + + for (; field; field = NEXT_LINK(field)) + { + type_t *t = field->type; + + /* get the base type */ + while( (t->type == 0) && t->ref ) + t = t->ref; + + if (field->ptr_level > 0) + { + has_pointer = 1; + continue; + } + + if (is_string_type(field->attrs, 0, field->array)) + { + has_conformance = 1; + has_variance = 1; + continue; + } + + if (is_array_type(field->attrs, 0, field->array)) + { + if (field->array && !field->array->is_const) + { + has_conformance = 1; + if (PREV_LINK(field)) + yyerror("field '%s' deriving from a conformant array must be the last field in the structure", + field->name); + } + if (is_attr(field->attrs, ATTR_LENGTHIS)) + has_variance = 1; + } + + switch (t->type) + { + /* + * RPC_FC_BYTE, RPC_FC_STRUCT, etc + * Simple types don't effect the type of struct. + * A struct containing a simple struct is still a simple struct. + * So long as we can block copy the data, we return RPC_FC_STRUCT. + */ + case 0: /* void pointer */ + case RPC_FC_BYTE: + case RPC_FC_CHAR: + case RPC_FC_SMALL: + case RPC_FC_USMALL: + case RPC_FC_WCHAR: + case RPC_FC_SHORT: + case RPC_FC_USHORT: + case RPC_FC_LONG: + case RPC_FC_ULONG: + case RPC_FC_INT3264: + case RPC_FC_UINT3264: + case RPC_FC_HYPER: + case RPC_FC_FLOAT: + case RPC_FC_DOUBLE: + case RPC_FC_STRUCT: + case RPC_FC_ENUM16: + case RPC_FC_ENUM32: + break; + + case RPC_FC_UP: + case RPC_FC_FP: + has_pointer = 1; + break; + case RPC_FC_CARRAY: + has_conformance = 1; + if (PREV_LINK(field)) + yyerror("field '%s' deriving from a conformant array must be the last field in the structure", + field->name); + break; + case RPC_FC_C_CSTRING: + case RPC_FC_C_WSTRING: + has_conformance = 1; + has_variance = 1; + break; + + /* + * Propagate member attributes + * a struct should be at least as complex as its member + */ + case RPC_FC_CVSTRUCT: + has_conformance = 1; + has_variance = 1; + has_pointer = 1; + break; + + case RPC_FC_CPSTRUCT: + has_conformance = 1; + if (PREV_LINK(field)) + yyerror("field '%s' deriving from a conformant array must be the last field in the structure", + field->name); + has_pointer = 1; + break; + + case RPC_FC_CSTRUCT: + has_conformance = 1; + if (PREV_LINK(field)) + yyerror("field '%s' deriving from a conformant array must be the last field in the structure", + field->name); + break; + + case RPC_FC_PSTRUCT: + has_pointer = 1; + break; + + default: + fprintf(stderr,"Unknown struct member %s with type (0x%02x)\n", + field->name, t->type); + /* fallthru - treat it as complex */ + + /* as soon as we see one of these these members, it's bogus... */ + case RPC_FC_IP: + case RPC_FC_ENCAPSULATED_UNION: + case RPC_FC_NON_ENCAPSULATED_UNION: + case RPC_FC_TRANSMIT_AS: + case RPC_FC_REPRESENT_AS: + case RPC_FC_PAD: + case RPC_FC_EMBEDDED_COMPLEX: + case RPC_FC_BOGUS_STRUCT: + return RPC_FC_BOGUS_STRUCT; + } + } + + if( has_variance ) + return RPC_FC_CVSTRUCT; + if( has_conformance && has_pointer ) + return RPC_FC_CPSTRUCT; + if( has_conformance ) + return RPC_FC_CSTRUCT; + if( has_pointer ) + return RPC_FC_PSTRUCT; + return RPC_FC_STRUCT; +} + +/***** constant repository *****/ + +struct rconst { + char *name; + var_t *var; + struct rconst *next; +}; + +struct rconst *const_hash[HASHMAX]; + +static var_t *reg_const(var_t *var) +{ + struct rconst *nc; + int hash; + if (!var->name) { + yyerror("registering constant without name"); + return var; + } + hash = hash_ident(var->name); + nc = xmalloc(sizeof(struct rconst)); + nc->name = var->name; + nc->var = var; + nc->next = const_hash[hash]; + const_hash[hash] = nc; + return var; +} + +static var_t *find_const(char *name, int f) +{ + struct rconst *cur = const_hash[hash_ident(name)]; + while (cur && strcmp(cur->name, name)) + cur = cur->next; + if (!cur) { + if (f) yyerror("constant '%s' not found", name); + return NULL; + } + return cur->var; +} diff --git a/reactos/tools/widl_new/port/mkstemps.c b/reactos/tools/widl_new/port/mkstemps.c new file mode 100644 index 00000000000..9919eac949f --- /dev/null +++ b/reactos/tools/widl_new/port/mkstemps.c @@ -0,0 +1,138 @@ +/* Copyright (C) 1991, 1992, 1996, 1998 Free Software Foundation, Inc. + This file is derived from mkstemp.c from the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_SYS_TIME_H +#include +#endif +#ifdef HAVE_PROCESS_H +#include +#endif + +/* We need to provide a type for gcc_uint64_t. */ +#ifdef __GNUC__ +__extension__ typedef unsigned long long gcc_uint64_t; +#else +typedef unsigned long gcc_uint64_t; +#endif + +#ifndef TMP_MAX +#define TMP_MAX 16384 +#endif + +/* + +@deftypefn Replacement int mkstemps (char *@var{template}, int @var{suffix_len}) + +Generate a unique temporary file name from @var{template}. +@var{template} has the form: + +@example + @var{path}/ccXXXXXX@var{suffix} +@end example + +@var{suffix_len} tells us how long @var{suffix} is (it can be zero +length). The last six characters of @var{template} before @var{suffix} +must be @samp{XXXXXX}; they are replaced with a string that makes the +filename unique. Returns a file descriptor open on the file for +reading and writing. + +@end deftypefn + +*/ + +int +mkstemps ( + char *template, + int suffix_len) +{ + static const char letters[] + = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + static gcc_uint64_t value; +#ifdef HAVE_GETTIMEOFDAY + struct timeval tv; +#endif + char *XXXXXX; + size_t len; + int count; + + len = strlen (template); + + if ((int) len < 6 + suffix_len + || strncmp (&template[len - 6 - suffix_len], "XXXXXX", 6)) + { + return -1; + } + + XXXXXX = &template[len - 6 - suffix_len]; + +#ifdef HAVE_GETTIMEOFDAY + /* Get some more or less random data. */ + gettimeofday (&tv, NULL); + value += ((gcc_uint64_t) tv.tv_usec << 16) ^ tv.tv_sec ^ getpid (); +#else + value += getpid (); +#endif + + for (count = 0; count < TMP_MAX; ++count) + { + gcc_uint64_t v = value; + int fd; + + /* Fill in the random bits. */ + XXXXXX[0] = letters[v % 62]; + v /= 62; + XXXXXX[1] = letters[v % 62]; + v /= 62; + XXXXXX[2] = letters[v % 62]; + v /= 62; + XXXXXX[3] = letters[v % 62]; + v /= 62; + XXXXXX[4] = letters[v % 62]; + v /= 62; + XXXXXX[5] = letters[v % 62]; + +#ifdef VMS + fd = open (template, O_RDWR|O_CREAT|O_EXCL, 0600, "fop=tmd"); +#else + fd = open (template, O_RDWR|O_CREAT|O_EXCL, 0600); +#endif + if (fd >= 0) + /* The file does not exist. */ + return fd; + + /* This is a random value. It is only necessary that the next + TMP_MAX values generated by adding 7777 to VALUE are different + with (module 2^32). */ + value += 7777; + } + + /* We return the null string if we can't find a unique file name. */ + template[0] = '\0'; + return -1; +} diff --git a/reactos/tools/widl_new/proxy.c b/reactos/tools/widl_new/proxy.c new file mode 100644 index 00000000000..1710cdcadb7 --- /dev/null +++ b/reactos/tools/widl_new/proxy.c @@ -0,0 +1,1070 @@ +/* + * IDL Compiler + * + * Copyright 2002 Ove Kaaven + * Copyright 2004 Mike McCormack + * + * 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 +#include +#ifdef HAVE_UNISTD_H +# include +#endif +#include +#include +#include +#include + +#include "widl.h" +#include "utils.h" +#include "parser.h" +#include "header.h" + +#define END_OF_LIST(list) \ + do { \ + if (list) { \ + while (NEXT_LINK(list)) \ + list = NEXT_LINK(list); \ + } \ + } while(0) + +static FILE* proxy; +static int indent = 0; + +/* FIXME: support generation of stubless proxies */ + +static int print_proxy( const char *format, ... ) +{ + va_list va; + int i, r; + + va_start( va, format ); + for( i=0; itype; + while( (t->type == 0) && t->ref ) + t = t->ref; + return t; +} + +static void write_stubdescproto(void) +{ + print_proxy( "extern const MIDL_STUB_DESC Object_StubDesc;\n"); + print_proxy( "\n"); +} + +static void write_stubdesc(void) +{ + print_proxy( "const MIDL_STUB_DESC Object_StubDesc = {\n"); + print_proxy( " 0,\n"); + print_proxy( " NdrOleAllocate,\n"); + print_proxy( " NdrOleFree,\n"); + print_proxy( " {0}, 0, 0, 0, 0,\n"); + print_proxy( " 0 /* __MIDL_TypeFormatString.Format */\n"); + print_proxy( "};\n"); + print_proxy( "\n"); +} + +static void write_formatdesc( const char *str ) +{ + print_proxy( "typedef struct _MIDL_%s_FORMAT_STRING\n", str ); + indent++; + print_proxy( "{\n"); + print_proxy( "short Pad;\n"); + print_proxy( "unsigned char Format[%s_FORMAT_STRING_SIZE];\n", str); + indent--; + print_proxy( "} MIDL_%s_FORMAT_STRING;\n", str); + print_proxy( "\n"); +} + +static void write_formatstringsdecl(void) +{ + print_proxy( "#define TYPE_FORMAT_STRING_SIZE %d\n",1); /* FIXME */ + print_proxy( "#define PROC_FORMAT_STRING_SIZE %d\n",1); /* FIXME */ + fprintf(proxy, "\n"); + write_formatdesc( "TYPE" ); + write_formatdesc( "PROC" ); + fprintf(proxy, "\n"); + print_proxy( "static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString;\n"); + print_proxy( "static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString;\n"); + print_proxy( "\n"); +} + +static void write_formatstring( int proc ) +{ + const char *t, *n; + if( !proc ) + { + t = "TYPE"; + n = "Type"; + } + else + { + t = "PROC"; + n = "Proc"; + } + print_proxy( "static const MIDL_%s_FORMAT_STRING __MIDL_%sFormatString =\n", t, n); + print_proxy( "{\n"); + indent++; + print_proxy( "0,\n"); + print_proxy( "{\n"); + indent++; + print_proxy( "0\n"); + indent--; + print_proxy( "}\n"); + indent--; + print_proxy( "};\n"); + print_proxy( "\n"); +} + +static void init_proxy(void) +{ + if (proxy) return; + if(!(proxy = fopen(proxy_name, "w"))) + error("Could not open %s for output\n", proxy_name); + print_proxy( "/*** Autogenerated by WIDL %s - Do not edit ***/\n", WIDL_FULLVERSION); + print_proxy( "\n"); + print_proxy( "#ifndef __REDQ_RPCPROXY_H_VERSION__\n"); + print_proxy( "#define __REQUIRED_RPCPROXY_H_VERSION__ 440\n"); + print_proxy( "#endif /* __REDQ_RPCPROXY_H_VERSION__ */\n"); + print_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"); + print_proxy( "#endif /* __RPCPROXY_H_VERSION__ */\n"); + print_proxy( "\n"); + print_proxy( "#include \"%s\"\n", header_name); + print_proxy( "\n"); + write_formatstringsdecl(); + write_stubdescproto(); +} + +static void clear_output_vars( var_t *arg ) +{ + END_OF_LIST(arg); + while (arg) { + if (is_attr(arg->attrs, ATTR_OUT) && !is_attr(arg->attrs, ATTR_IN)) { + print_proxy( "if(%s)\n", arg->name ); + indent++; + print_proxy( "MIDL_memset( %s, 0, sizeof( ", arg->name ); + indent--; + write_type(proxy, arg->type, arg, arg->tname); + fprintf( proxy, " ));\n" ); + } + arg = PREV_LINK(arg); + } +} + +static int is_pointer(var_t *arg) +{ + if (arg->ptr_level) + return 1; + if (arg->type->type == RPC_FC_FP ) + return 1; + return 0; +} + +static void proxy_check_pointers( var_t *arg ) +{ + END_OF_LIST(arg); + while (arg) { + if (is_pointer(arg)) { + print_proxy( "if(!%s)\n", arg->name ); + indent++; + print_proxy( "RpcRaiseException(RPC_X_NULL_REF_POINTER);\n"); + indent--; + } + arg = PREV_LINK(arg); + } +} + +static void marshall_size_arg( var_t *arg ) +{ + int index = 0; + const type_t *type = get_base_type(arg); + expr_t *expr; + + expr = get_attrp( arg->attrs, ATTR_SIZEIS ); + if (expr) + { + print_proxy( "_StubMsg.MaxCount = ", arg->name ); + write_expr(proxy, expr, 0); + fprintf(proxy, ";\n\n"); + print_proxy( "NdrConformantArrayBufferSize( &_StubMsg, (unsigned char*)%s, ", arg->name ); + fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d]);\n", index ); + return; + } + + switch( type->type ) + { + case RPC_FC_BYTE: + case RPC_FC_CHAR: + print_proxy( "_StubMsg.BufferLength += %d; /* %s */\n", 1, arg->name ); + break; + + case RPC_FC_WCHAR: + case RPC_FC_SHORT: + case RPC_FC_USHORT: + case RPC_FC_ENUM16: + print_proxy( "_StubMsg.BufferLength += %d; /* %s */\n", 2, arg->name ); + break; + + case RPC_FC_LONG: + case RPC_FC_ULONG: + case RPC_FC_ENUM32: + print_proxy( "_StubMsg.BufferLength += %d; /* %s */\n", 4, arg->name ); + break; + + case RPC_FC_STRUCT: + print_proxy( "NdrSimpleStructBufferSize(&_StubMsg, (unsigned char*)%s, ", arg->name ); + fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d] );\n", index ); + break; + + case RPC_FC_C_CSTRING: + case RPC_FC_C_WSTRING: + case RPC_FC_CARRAY: + print_proxy( "NdrConformantArrayBufferSize( &_StubMsg, (unsigned char*)%s, ", arg->name ); + fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d]);\n", index ); + break; + + case RPC_FC_BOGUS_STRUCT: + print_proxy( "NdrComplexStructBufferSize(&_StubMsg, (unsigned char*)%s, ", arg->name ); + fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d] );\n", index ); + break; + + case RPC_FC_FP: + { + var_t temp; + memset( &temp, 0, sizeof temp ); + temp.type = type->ref; + temp.name = arg->name; /* FIXME */ +#if 0 + print_proxy( "/* FIXME: %s use the right name for %s */\n", __FUNCTION__, arg->name ); +#endif + marshall_size_arg( &temp ); + } + break; + + case RPC_FC_IP: + print_proxy( "NdrPointerBufferSize( &_StubMsg, (unsigned char*)%s, ", arg->name ); + fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d]);\n", index ); + break; + + default: + print_proxy("/* FIXME: %s code for %s type %d missing */\n", __FUNCTION__, arg->name, type->type ); + } +} + +static void proxy_gen_marshall_size( var_t *arg ) +{ + print_proxy( "_StubMsg.BufferLength = 0U;\n" ); + + END_OF_LIST(arg); + while (arg) { + if (is_attr(arg->attrs, ATTR_IN)) + { + marshall_size_arg( arg ); + fprintf(proxy, "\n"); + } + arg = PREV_LINK(arg); + } +} + +static void marshall_copy_arg( var_t *arg ) +{ + int index = 0; + type_t *type = get_base_type(arg); + expr_t *expr; + + expr = get_attrp( arg->attrs, ATTR_SIZEIS ); + if (expr) + { + print_proxy( "_StubMsg.MaxCount = ", arg->name ); + write_expr(proxy, expr, 0); + fprintf(proxy, ";\n\n"); + print_proxy( "NdrConformantArrayMarshall( &_StubMsg, (unsigned char*)%s, ", arg->name ); + fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d]);\n", index ); + return; + } + + switch( type->type ) + { + case RPC_FC_BYTE: + case RPC_FC_CHAR: + case RPC_FC_WCHAR: + case RPC_FC_SHORT: + case RPC_FC_USHORT: + case RPC_FC_ENUM16: + case RPC_FC_LONG: + case RPC_FC_ULONG: + case RPC_FC_ENUM32: + print_proxy( "*("); + write_type(proxy, arg->type, arg, arg->tname); + fprintf(proxy, " *)_StubMsg.Buffer = %s;\n", arg->name ); + print_proxy("_StubMsg.Buffer += sizeof("); + write_type(proxy, arg->type, arg, arg->tname); + fprintf(proxy, ");\n"); + break; + + case RPC_FC_STRUCT: + /* FIXME: add the format string, and set the index below */ + print_proxy( "NdrSimpleStructMarshall(&_StubMsg, (unsigned char*)%s, ", arg->name ); + fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d]);\n", index ); + break; + + case RPC_FC_C_CSTRING: + case RPC_FC_C_WSTRING: + case RPC_FC_CARRAY: + break; + + case RPC_FC_BOGUS_STRUCT: + print_proxy( "NdrComplexStructMarshall(&_StubMsg, (unsigned char*)%s, ", arg->name ); + fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d] );\n", index ); + break; + + case RPC_FC_FP: + { + var_t temp; + memset( &temp, 0, sizeof temp ); + temp.type = type->ref; + temp.name = arg->name; /* FIXME */ +#if 0 + print_proxy( "/* FIXME: %s use the right name for %s */\n", __FUNCTION__, arg->name ); +#endif + marshall_copy_arg( &temp ); + } + break; + + case RPC_FC_IP: + print_proxy( "NdrPointerMarshall( &_StubMsg, (unsigned char*)%s, ", arg->name ); + fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d]);\n", index ); + break; + + default: + print_proxy("/* FIXME: %s code for %s type %d missing */\n", __FUNCTION__, arg->name, type->type ); + } +} + +static void gen_marshall_copydata( var_t *arg ) +{ + END_OF_LIST(arg); + while (arg) { + if (is_attr(arg->attrs, ATTR_IN)) + { + marshall_copy_arg( arg ); + fprintf(proxy, "\n"); + } + arg = PREV_LINK(arg); + } +} + +static void gen_marshall( var_t *arg ) +{ + /* generated code to determine the size of the buffer required */ + proxy_gen_marshall_size( arg ); + + /* generated code to allocate the buffer */ + print_proxy( "NdrProxyGetBuffer(This, &_StubMsg);\n" ); + + /* generated code to copy the args into the buffer */ + gen_marshall_copydata( arg ); + + print_proxy( "\n"); +} + +static void unmarshall_copy_arg( var_t *arg ) +{ + int index = 0; + type_t *type = get_base_type(arg); + expr_t *expr; + + expr = get_attrp( arg->attrs, ATTR_SIZEIS ); + if (expr) + { + print_proxy( "NdrConformantArrayUnmarshall( &_StubMsg, (unsigned char*)%s, ", arg->name ); + fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d]);\n", index ); + return; + } + + switch( type->type ) + { + case RPC_FC_BYTE: + case RPC_FC_CHAR: + case RPC_FC_WCHAR: + case RPC_FC_SHORT: + case RPC_FC_USHORT: + case RPC_FC_ENUM16: + case RPC_FC_LONG: + case RPC_FC_ULONG: + case RPC_FC_ENUM32: + print_proxy( "%s = *(", arg->name ); + write_type(proxy, arg->type, arg, arg->tname); + fprintf(proxy," *)_StubMsg.Buffer;\n"); + print_proxy("_StubMsg.Buffer += sizeof("); + write_type(proxy, arg->type, arg, arg->tname); + fprintf(proxy, ");\n"); + break; + + case RPC_FC_STRUCT: + print_proxy( "NdrSimpleStructUnmarshall(&_StubMsg, (unsigned char**)%s, ", arg->name ); + fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d], 0);\n", index ); + break; + + case RPC_FC_C_CSTRING: + case RPC_FC_C_WSTRING: + case RPC_FC_CARRAY: + print_proxy( "NdrConformantArrayUnmarshall( &_StubMsg, (unsigned char*)%s, ", arg->name ); + fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d]);\n", index ); + break; + + case RPC_FC_BOGUS_STRUCT: + print_proxy( "NdrComplexStructUnmarshall(&_StubMsg, (unsigned char*)%s, ", arg->name ); + fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d], 0 );\n", index ); + break; + + case RPC_FC_FP: + { + var_t temp; + memset( &temp, 0, sizeof temp ); + temp.type = type->ref; + temp.name = arg->name; /* FIXME */ +#if 1 + print_proxy( "/* FIXME: %s use the right name for %s */\n", __FUNCTION__, arg->name ); +#endif + unmarshall_copy_arg( &temp ); + } + break; + + case RPC_FC_IP: + print_proxy( "NdrPointerUnmarshall(&_StubMsg, (unsigned char**)&%s, ", arg->name ); + fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d], 0);\n", index ); + break; + + default: + print_proxy("/* FIXME: %s code for %s type %d missing */\n", __FUNCTION__, arg->name, type->type ); + } +} + +static void gen_unmarshall( var_t *arg ) +{ + END_OF_LIST(arg); + while (arg) { + if (is_attr(arg->attrs, ATTR_OUT)) + { + unmarshall_copy_arg( arg ); + fprintf(proxy, "\n"); + } + arg = PREV_LINK(arg); + } +} + +static void free_variable( var_t *arg ) +{ + var_t *constraint; + int index = 0; /* FIXME */ + type_t *type; + expr_t *expr; + + expr = get_attrp( arg->attrs, ATTR_SIZEIS ); + if (expr) + { + print_proxy( "_StubMsg.MaxCount = ", arg->name ); + write_expr(proxy, expr, 0); + fprintf(proxy, ";\n\n"); + print_proxy( "NdrClearOutParameters( &_StubMsg, "); + fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d], ", index ); + fprintf(proxy, "(void*)%s );\n", arg->name ); + return; + } + + type = get_base_type(arg); + switch( type->type ) + { + case RPC_FC_BYTE: + case RPC_FC_CHAR: + case RPC_FC_WCHAR: + case RPC_FC_SHORT: + case RPC_FC_USHORT: + case RPC_FC_ENUM16: + case RPC_FC_LONG: + case RPC_FC_ULONG: + case RPC_FC_ENUM32: + case RPC_FC_STRUCT: + break; + + case RPC_FC_FP: + case RPC_FC_IP: + constraint = get_attrp( arg->attrs, ATTR_IIDIS ); + if( constraint ) + print_proxy( "_StubMsg.MaxCount = (unsigned long) ( %s );\n",constraint->name); + print_proxy( "NdrClearOutParameters( &_StubMsg, "); + fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d], ", index ); + fprintf(proxy, "(void*)%s );\n", arg->name ); + break; + + default: + print_proxy("/* FIXME: %s code for %s type %d missing */\n", __FUNCTION__, arg->name, type->type ); + } +} + +static void proxy_free_variables( var_t *arg ) +{ + END_OF_LIST(arg); + while (arg) { + if (is_attr(arg->attrs, ATTR_OUT)) + { + free_variable( arg ); + fprintf(proxy, "\n"); + } + arg = PREV_LINK(arg); + } +} + +static void gen_proxy(type_t *iface, func_t *cur, int idx) +{ + var_t *def = cur->def; + int has_ret = !is_void(def->type, def); + + indent = 0; + write_type(proxy, def->type, def, def->tname); + print_proxy( " STDMETHODCALLTYPE %s_", iface->name); + write_name(proxy, def); + print_proxy( "_Proxy(\n"); + write_args(proxy, cur->args, iface->name, 1, TRUE); + print_proxy( ")\n"); + print_proxy( "{\n"); + indent ++; + /* local variables */ + if (has_ret) { + print_proxy( "" ); + write_type(proxy, def->type, def, def->tname); + print_proxy( " _RetVal;\n"); + } + print_proxy( "RPC_MESSAGE _Msg;\n" ); + print_proxy( "MIDL_STUB_MESSAGE _StubMsg;\n" ); + print_proxy( "\n"); + + /* FIXME: trace */ + clear_output_vars( cur->args ); + + print_proxy( "RpcTryExcept\n" ); + print_proxy( "{\n" ); + indent++; + print_proxy( "NdrProxyInitialize(This, &_Msg, &_StubMsg, &Object_StubDesc, %d);\n", idx); + proxy_check_pointers( cur->args ); + + print_proxy( "RpcTryFinally\n" ); + print_proxy( "{\n" ); + indent++; + + gen_marshall( cur->args ); + + print_proxy( "NdrProxySendReceive(This, &_StubMsg);\n" ); + fprintf(proxy, "\n"); + print_proxy("if ((_Msg.DataRepresentation&0xffff) != NDR_LOCAL_DATA_REPRESENTATION)\n"); + indent++; + print_proxy("NdrConvert( &_StubMsg, &__MIDL_ProcFormatString.Format[0]);\n" ); + indent--; + fprintf(proxy, "\n"); + + gen_unmarshall( cur->args ); + if (has_ret) { + /* + * FIXME: We only need to round the buffer up if it could be unaligned... + * We should calculate how much buffer we used and output the following + * line only if necessary. + */ + print_proxy( "_StubMsg.Buffer = (unsigned char *)(((long)_StubMsg.Buffer + 3) & ~ 0x3);\n"); + + print_proxy( "_RetVal = *(" ); + write_type(proxy, def->type, def, def->tname); + fprintf(proxy, " *)_StubMsg.Buffer;\n"); + print_proxy("_StubMsg.Buffer += sizeof("); + write_type(proxy, def->type, def, def->tname); + fprintf(proxy, ");\n"); + } + + indent--; + print_proxy( "}\n"); + print_proxy( "RpcFinally\n" ); + print_proxy( "{\n" ); + indent++; + print_proxy( "NdrProxyFreeBuffer(This, &_StubMsg);\n" ); + indent--; + print_proxy( "}\n"); + print_proxy( "RpcEndFinally\n" ); + indent--; + print_proxy( "}\n" ); + print_proxy( "RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE)\n" ); + print_proxy( "{\n" ); + if (has_ret) { + indent++; + proxy_free_variables( cur->args ); + print_proxy( "_RetVal = NdrProxyErrorHandler(RpcExceptionCode());\n" ); + indent--; + } + print_proxy( "}\n" ); + print_proxy( "RpcEndExcept\n" ); + + if (has_ret) { + print_proxy( "return _RetVal;\n" ); + } + indent--; + print_proxy( "}\n"); + print_proxy( "\n"); +} + +static void stub_write_locals( var_t *arg ) +{ + int n = 0; + while (arg) { + int outptr = is_attr(arg->attrs, ATTR_OUT); + + /* create a temporary variable to store the output */ + if (outptr) { + var_t temp; + memset( &temp, 0, sizeof temp ); + temp.ptr_level = arg->ptr_level - 1; /* dereference once */ + print_proxy(""); + write_type(proxy, arg->type, &temp, arg->tname); + fprintf(proxy, " _M%d;\n",n++); + } + print_proxy(""); + write_type(proxy, arg->type, arg, arg->tname); + fprintf(proxy, " "); + write_name(proxy, arg); + fprintf(proxy, ";\n"); + arg = NEXT_LINK(arg); + } +} + +static void stub_unmarshall( var_t *arg ) +{ + int n = 0; + END_OF_LIST(arg); + while (arg) { + if (is_attr(arg->attrs, ATTR_IN)) + { + unmarshall_copy_arg( arg ); + fprintf(proxy,"\n"); + } + else if (is_attr(arg->attrs, ATTR_OUT)) { + type_t *type = get_base_type(arg); + switch( type->type ) + { + case RPC_FC_STRUCT: + print_proxy("MIDL_memset("); + write_name(proxy, arg); + fprintf(proxy,", 0, sizeof("); + write_type(proxy, arg->type, arg, arg->tname); + fprintf(proxy,"));\n"); + break; + default: + print_proxy(""); + write_name(proxy, arg); + fprintf(proxy," = &_M%d;\n", n); + print_proxy("_M%d = 0;\n", n++); + break; + } + } + arg = PREV_LINK(arg); + } +} + +static void stub_gen_marshall_size( var_t *arg ) +{ + print_proxy( "_StubMsg.BufferLength = 0U;\n" ); + + END_OF_LIST(arg); + while (arg) { + if (is_attr(arg->attrs, ATTR_OUT)) + marshall_size_arg( arg ); + arg = PREV_LINK(arg); + } +} + +static void stub_gen_marshall_copydata( var_t *arg ) +{ + END_OF_LIST(arg); + while (arg) { + if (is_attr(arg->attrs, ATTR_OUT)) + marshall_copy_arg( arg ); + arg = PREV_LINK(arg); + } +} + +static void stub_genmarshall( var_t *args ) +{ + /* FIXME: size buffer */ + stub_gen_marshall_size( args ); + + print_proxy("NdrStubGetBuffer(This, pRpcChannelBuffer, &_StubMsg);\n"); + + stub_gen_marshall_copydata( args ); +} + +static void gen_stub(type_t *iface, func_t *cur, const char *cas) +{ + var_t *def = cur->def; + var_t *arg; + int has_ret = !is_void(def->type, def); + + indent = 0; + print_proxy( "void __RPC_STUB %s_", iface->name); + write_name(proxy, def); + print_proxy( "_Stub(\n"); + indent++; + print_proxy( "IRpcStubBuffer* This,\n"); + print_proxy( "IRpcChannelBuffer* pRpcChannelBuffer,\n"); + print_proxy( "PRPC_MESSAGE _Msg,\n"); + print_proxy( "DWORD* _pdwStubPhase)\n"); + indent--; + print_proxy( "{\n"); + indent++; + /* local variables */ + if (has_ret) { + print_proxy(""); + write_type(proxy, def->type, def, def->tname); + fprintf(proxy, " _RetVal;\n"); + } + print_proxy("%s * _This = (%s*)((CStdStubBuffer*)This)->pvServerObject;\n", iface->name, iface->name); + print_proxy("MIDL_STUB_MESSAGE _StubMsg;\n"); + stub_write_locals( cur->args ); + fprintf(proxy, "\n"); + + /* FIXME: trace */ + + print_proxy("NdrStubInitialize(_Msg, &_StubMsg, &Object_StubDesc, pRpcChannelBuffer);\n"); + fprintf(proxy, "\n"); + + print_proxy("RpcTryFinally\n"); + print_proxy("{\n"); + indent++; + print_proxy("if ((_Msg->DataRepresentation&0xffff) != NDR_LOCAL_DATA_REPRESENTATION)\n"); + indent++; + print_proxy("NdrConvert( &_StubMsg, &__MIDL_ProcFormatString.Format[0]);\n" ); + indent--; + fprintf(proxy, "\n"); + + stub_unmarshall( cur->args ); + fprintf(proxy, "\n"); + + print_proxy("*_pdwStubPhase = STUB_CALL_SERVER;\n"); + fprintf(proxy, "\n"); + print_proxy(""); + if (has_ret) fprintf(proxy, "_RetVal = "); + fprintf(proxy, "%s_", iface->name); + if (cas) fprintf(proxy, "%s_Stub", cas); + else write_name(proxy, def); + fprintf(proxy, "(_This"); + arg = cur->args; + if (arg) { + END_OF_LIST(arg); + while (arg) { + fprintf(proxy, ", "); + write_name(proxy, arg); + arg = PREV_LINK(arg); + } + } + fprintf(proxy, ");\n"); + fprintf(proxy, "\n"); + print_proxy("*_pdwStubPhase = STUB_MARSHAL;\n"); + fprintf(proxy, "\n"); + + stub_genmarshall( cur->args ); + fprintf(proxy, "\n"); + + if (has_ret) { + /* + * FIXME: We only need to round the buffer up if it could be unaligned... + * We should calculate how much buffer we used and output the following + * line only if necessary. + */ + print_proxy( "_StubMsg.Buffer = (unsigned char *)(((long)_StubMsg.Buffer + 3) & ~ 0x3);\n"); + + print_proxy( "*(" ); + write_type(proxy, def->type, def, def->tname); + fprintf(proxy, " *)_StubMsg.Buffer = _RetVal;\n"); + print_proxy("_StubMsg.Buffer += sizeof("); + write_type(proxy, def->type, def, def->tname); + fprintf(proxy, ");\n"); + } + + indent--; + print_proxy("}\n"); + print_proxy("RpcFinally\n"); + print_proxy("{\n"); + print_proxy("}\n"); + print_proxy("RpcEndFinally\n"); + + print_proxy("_Msg->BufferLength = _StubMsg.Buffer - (unsigned char *)_Msg->Buffer;\n"); + indent--; + + print_proxy("}\n"); + print_proxy("\n"); +} + +static int write_proxy_methods(type_t *iface) +{ + func_t *cur = iface->funcs; + int i = 0; + + END_OF_LIST(cur); + + if (iface->ref) i = write_proxy_methods(iface->ref); + while (cur) { + var_t *def = cur->def; + if (!is_callas(def->attrs)) { + if (i) fprintf(proxy, ",\n"); + print_proxy( "%s_", iface->name); + write_name(proxy, def); + fprintf(proxy, "_Proxy"); + i++; + } + cur = PREV_LINK(cur); + } + return i; +} + +static int write_stub_methods(type_t *iface) +{ + func_t *cur = iface->funcs; + int i = 0; + + END_OF_LIST(cur); + + if (iface->ref) i = write_stub_methods(iface->ref); + else return i; /* skip IUnknown */ + while (cur) { + var_t *def = cur->def; + if (!is_local(def->attrs)) { + if (i) fprintf(proxy,",\n"); + print_proxy( "%s_", iface->name); + write_name(proxy, def); + fprintf(proxy, "_Stub"); + i++; + } + cur = PREV_LINK(cur); + } + return i; +} + +static void write_proxy(type_t *iface) +{ + int midx = -1, stubs; + func_t *cur = iface->funcs; + + if (!cur) return; + + END_OF_LIST(cur); + + /* FIXME: check for [oleautomation], shouldn't generate proxies/stubs if specified */ + + fprintf(proxy, "/*****************************************************************************\n"); + fprintf(proxy, " * %s interface\n", iface->name); + fprintf(proxy, " */\n"); + while (cur) { + const var_t *def = cur->def; + if (!is_local(def->attrs)) { + const var_t *cas = is_callas(def->attrs); + const char *cname = cas ? cas->name : NULL; + int idx = cur->idx; + if (cname) { + const func_t *m = iface->funcs; + while (m && strcmp(get_name(m->def), cname)) + m = NEXT_LINK(m); + idx = m->idx; + } + gen_proxy(iface, cur, idx); + gen_stub(iface, cur, cname); + if (midx == -1) midx = idx; + else if (midx != idx) yyerror("method index mismatch in write_proxy"); + midx++; + } + cur = PREV_LINK(cur); + } + + /* proxy vtable */ + print_proxy( "const CINTERFACE_PROXY_VTABLE(%d) _%sProxyVtbl =\n", midx, iface->name); + print_proxy( "{\n"); + indent++; + print_proxy( "{\n", iface->name); + indent++; + print_proxy( "&IID_%s,\n", iface->name); + indent--; + print_proxy( "},\n"); + print_proxy( "{\n"); + indent++; + write_proxy_methods(iface); + fprintf(proxy, "\n"); + indent--; + print_proxy( "}\n"); + indent--; + print_proxy( "};\n"); + fprintf(proxy, "\n\n"); + + /* stub vtable */ + print_proxy( "static const PRPC_STUB_FUNCTION %s_table[] =\n", iface->name); + print_proxy( "{\n"); + indent++; + stubs = write_stub_methods(iface); + fprintf(proxy, "\n"); + indent--; + fprintf(proxy, "};\n"); + print_proxy( "\n"); + print_proxy( "const CInterfaceStubVtbl _%sStubVtbl =\n", iface->name); + print_proxy( "{\n"); + indent++; + print_proxy( "{\n"); + indent++; + print_proxy( "&IID_%s,\n", iface->name); + print_proxy( "0,\n"); + print_proxy( "%d,\n", stubs+3); + print_proxy( "&%s_table[-3],\n", iface->name); + indent--; + print_proxy( "},\n", iface->name); + print_proxy( "{\n"); + indent++; + print_proxy( "CStdStubBuffer_METHODS\n"); + indent--; + print_proxy( "}\n"); + indent--; + print_proxy( "};\n"); + print_proxy( "\n"); +} + +void write_proxies(ifref_t *ifaces) +{ + ifref_t *lcur = ifaces; + ifref_t *cur; + char *file_id = proxy_token; + int c; + + if (!do_proxies) return; + if (!lcur) return; + END_OF_LIST(lcur); + + init_proxy(); + if(!proxy) return; + + cur = lcur; + while (cur) { + if (is_object(cur->iface->attrs) && !is_local(cur->iface->attrs)) + write_proxy(cur->iface); + cur = PREV_LINK(cur); + } + + if (!proxy) return; + + write_stubdesc(); + + print_proxy( "#if !defined(__RPC_WIN32__)\n"); + print_proxy( "#error Currently only Wine and WIN32 are supported.\n"); + print_proxy( "#endif\n"); + print_proxy( "\n"); + write_formatstring( 1 ); + write_formatstring( 0 ); + + fprintf(proxy, "const CInterfaceProxyVtbl* _%s_ProxyVtblList[] =\n", file_id); + fprintf(proxy, "{\n"); + cur = lcur; + while (cur) { + if(cur->iface->ref && cur->iface->funcs && + is_object(cur->iface->attrs) && !is_local(cur->iface->attrs)) + fprintf(proxy, " (CInterfaceProxyVtbl*)&_%sProxyVtbl,\n", cur->iface->name); + cur = PREV_LINK(cur); + } + fprintf(proxy, " 0\n"); + fprintf(proxy, "};\n"); + fprintf(proxy, "\n"); + + fprintf(proxy, "const CInterfaceStubVtbl* _%s_StubVtblList[] =\n", file_id); + fprintf(proxy, "{\n"); + cur = lcur; + while (cur) { + if(cur->iface->ref && cur->iface->funcs && + is_object(cur->iface->attrs) && !is_local(cur->iface->attrs)) + fprintf(proxy, " (CInterfaceStubVtbl*)&_%sStubVtbl,\n", cur->iface->name); + cur = PREV_LINK(cur); + } + fprintf(proxy, " 0\n"); + fprintf(proxy, "};\n"); + fprintf(proxy, "\n"); + + fprintf(proxy, "PCInterfaceName const _%s_InterfaceNamesList[] =\n", file_id); + fprintf(proxy, "{\n"); + cur = lcur; + while (cur) { + if(cur->iface->ref && cur->iface->funcs && + is_object(cur->iface->attrs) && !is_local(cur->iface->attrs)) + fprintf(proxy, " \"%s\",\n", cur->iface->name); + cur = PREV_LINK(cur); + } + fprintf(proxy, " 0\n"); + fprintf(proxy, "};\n"); + fprintf(proxy, "\n"); + + fprintf(proxy, "#define _%s_CHECK_IID(n) IID_GENERIC_CHECK_IID(_%s, pIID, n)\n", file_id, file_id); + fprintf(proxy, "\n"); + fprintf(proxy, "int __stdcall _%s_IID_Lookup(const IID* pIID, int* pIndex)\n", file_id); + fprintf(proxy, "{\n"); + cur = lcur; + c = 0; + while (cur) { + if(cur->iface->ref) + { + fprintf(proxy, " if (!_%s_CHECK_IID(%d))\n", file_id, c); + fprintf(proxy, " {\n"); + fprintf(proxy, " *pIndex = %d;\n", c); + fprintf(proxy, " return 1;\n"); + fprintf(proxy, " }\n"); + c++; + } + cur = PREV_LINK(cur); + } + fprintf(proxy, " return 0;\n"); + fprintf(proxy, "}\n"); + fprintf(proxy, "\n"); + + fprintf(proxy, "const ExtendedProxyFileInfo %s_ProxyFileInfo =\n", file_id); + fprintf(proxy, "{\n"); + fprintf(proxy, " (PCInterfaceProxyVtblList*)&_%s_ProxyVtblList,\n", file_id); + fprintf(proxy, " (PCInterfaceStubVtblList*)&_%s_StubVtblList,\n", file_id); + fprintf(proxy, " (const PCInterfaceName*)&_%s_InterfaceNamesList,\n", file_id); + fprintf(proxy, " 0,\n"); + fprintf(proxy, " &_%s_IID_Lookup,\n", file_id); + fprintf(proxy, " %d,\n", c); + fprintf(proxy, " 1,\n"); + fprintf(proxy, " 0,\n"); + fprintf(proxy, " 0,\n"); + fprintf(proxy, " 0,\n"); + fprintf(proxy, " 0\n"); + fprintf(proxy, "};\n"); + + fclose(proxy); +} diff --git a/reactos/tools/widl_new/server.c b/reactos/tools/widl_new/server.c new file mode 100644 index 00000000000..72d5ae700f2 --- /dev/null +++ b/reactos/tools/widl_new/server.c @@ -0,0 +1,656 @@ +/* + * IDL Compiler + * + * Copyright 2005-2006 Eric Kohl + * + * 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 +#include +#ifdef HAVE_UNISTD_H +# include +#endif +#include +#include +#include +#include + +#include "widl.h" +#include "utils.h" +#include "parser.h" +#include "header.h" +#include "windef.h" + +#include "widl.h" +#include "typelib.h" +#include "typelib_struct.h" +#include "typegen.h" + +static FILE* server; +static int indent = 0; + + +static int print_server(const char *format, ...) +{ + va_list va; + int i, r; + + va_start(va, format); + for (i = 0; i < indent; i++) + fprintf(server, " "); + r = vfprintf(server, format, va); + va_end(va); + return r; +} + + +static void write_parameters_init(const func_t *func) +{ + const var_t *var; + + if (!func->args) + return; + + var = func->args; + while (NEXT_LINK(var)) var = NEXT_LINK(var); + while (var) + { + if (var->type->type != RPC_FC_BIND_PRIMITIVE) + print_server("%s = 0;\n", var->name); + + var = PREV_LINK(var); + } + fprintf(server, "\n"); +} + + +static void declare_args(const func_t *func) +{ + int in_attr, out_attr; + int i = 0; + var_t *var; + + if (!func->args) + return; + + var = func->args; + while (NEXT_LINK(var)) var = NEXT_LINK(var); + while (var) + { + const expr_t *size_is = get_attrp(var->attrs, ATTR_SIZEIS); + int has_size = size_is && (size_is->type != EXPR_VOID); + int is_string = is_attr(var->attrs, ATTR_STRING); + + in_attr = is_attr(var->attrs, ATTR_IN); + out_attr = is_attr(var->attrs, ATTR_OUT); + if (!out_attr && !in_attr) + in_attr = 1; + + if (!in_attr && !has_size && !is_string) + { + int indirection; + print_server(""); + write_type(server, var->type, NULL, var->tname); + for (indirection = 0; indirection < var->ptr_level - 1; indirection++) + fprintf(server, "*"); + fprintf(server, " _W%u;\n", i++); + } + + print_server(""); + write_type(server, var->type, var, var->tname); + fprintf(server, " "); + write_name(server, var); + write_array(server, var->array, 0); + fprintf(server, ";\n"); + + var = PREV_LINK(var); + } +} + + +static void assign_out_args(const func_t *func) +{ + int in_attr, out_attr; + int i = 0, sep = 0; + var_t *var; + const expr_t *size_is; + int has_size; + + if (!func->args) + return; + + var = func->args; + while (NEXT_LINK(var)) var = NEXT_LINK(var); + while (var) + { + int is_string = is_attr(var->attrs, ATTR_STRING); + size_is = get_attrp(var->attrs, ATTR_SIZEIS); + has_size = size_is && (size_is->type != EXPR_VOID); + in_attr = is_attr(var->attrs, ATTR_IN); + out_attr = is_attr(var->attrs, ATTR_OUT); + if (!out_attr && !in_attr) + in_attr = 1; + + if (!in_attr) + { + print_server(""); + write_name(server, var); + + if (has_size) + { + unsigned int size; + type_t *type = var->type; + while (type->type == 0 && type->ref) + type = type->ref; + + fprintf(server, " = NdrAllocate(&_StubMsg, "); + write_expr(server, size_is, 1); + size = get_type_memsize(type); + fprintf(server, " * %u);\n", size); + } + else if (!is_string) + { + fprintf(server, " = &_W%u;\n", i); + if (var->ptr_level > 1) + print_server("_W%u = 0;\n", i); + i++; + } + + sep = 1; + } + + var = PREV_LINK(var); + } + + if (sep) + fprintf(server, "\n"); +} + + +static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsigned int *type_offset) +{ + char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE); + int explicit_handle = is_attr(iface->attrs, ATTR_EXPLICIT_HANDLE); + const func_t *func = iface->funcs; + const var_t *var; + const var_t* explicit_handle_var; + + while (NEXT_LINK(func)) func = NEXT_LINK(func); + while (func) + { + const var_t *def = func->def; + unsigned long buffer_size = 0; + unsigned int type_offset_func; + + /* check for a defined binding handle */ + explicit_handle_var = get_explicit_handle_var(func); + if (explicit_handle) + { + if (!explicit_handle_var) + { + error("%s() does not define an explicit binding handle!\n", def->name); + return; + } + } + else if (implicit_handle) + { + if (explicit_handle_var) + { + error("%s() must not define a binding handle!\n", def->name); + return; + } + } + + fprintf(server, "void __RPC_STUB\n"); + fprintf(server, "%s_", iface->name); + write_name(server, def); + fprintf(server, "(\n"); + indent++; + print_server("PRPC_MESSAGE _pRpcMessage)\n"); + indent--; + + /* write the functions body */ + fprintf(server, "{\n"); + indent++; + + /* declare return value '_RetVal' */ + if (!is_void(def->type, NULL)) + { + print_server(""); + write_type(server, def->type, def, def->tname); + fprintf(server, " _RetVal;\n"); + } + + /* Declare arguments */ + declare_args(func); + + print_server("MIDL_STUB_MESSAGE _StubMsg;\n"); + print_server("RPC_STATUS _Status;\n"); + fprintf(server, "\n"); + + + print_server("((void)(_Status));\n"); + print_server("NdrServerInitializeNew(\n"); + indent++; + print_server("_pRpcMessage,\n"); + print_server("&_StubMsg,\n"); + print_server("&%s_StubDesc);\n", iface->name); + indent--; + fprintf(server, "\n"); + + write_parameters_init(func); + + if (explicit_handle_var) + { + print_server("%s = _pRpcMessage->Handle;\n", explicit_handle_var->name); + fprintf(server, "\n"); + } + + print_server("RpcTryFinally\n"); + print_server("{\n"); + indent++; + print_server("RpcTryExcept\n"); + print_server("{\n"); + indent++; + + if (func->args) + { + print_server("if ((_pRpcMessage->DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION)\n"); + indent++; + print_server("NdrConvert(\n"); + indent++; + print_server("(PMIDL_STUB_MESSAGE)&_StubMsg,\n"); + print_server("(PFORMAT_STRING)&__MIDL_ProcFormatString.Format[%u]);\n", *proc_offset); + indent -= 2; + fprintf(server, "\n"); + + /* make a copy so we don't increment the type offset twice */ + type_offset_func = *type_offset; + + /* unmarshall arguments */ + write_remoting_arguments(server, indent, func, &type_offset_func, PASS_IN, PHASE_UNMARSHAL); + } + + print_server("if (_StubMsg.Buffer > _StubMsg.BufferEnd)\n"); + print_server("{\n"); + indent++; + print_server("RpcRaiseException(RPC_X_BAD_STUB_DATA);\n"); + indent--; + print_server("}\n"); + indent--; + print_server("}\n"); + print_server("RpcExcept(RPC_BAD_STUB_DATA_EXCEPTION_FILTER)\n"); + print_server("{\n"); + indent++; + print_server("RpcRaiseException(RPC_X_BAD_STUB_DATA);\n"); + indent--; + print_server("}\n"); + print_server("RpcEndExcept\n"); + fprintf(server, "\n"); + + /* Assign 'out' arguments */ + assign_out_args(func); + + /* Call the real server function */ + if (!is_void(def->type, NULL)) + print_server("_RetVal = "); + else + print_server(""); + write_name(server, def); + + if (func->args) + { + int first_arg = 1; + + fprintf(server, "(\n"); + indent++; + var = func->args; + while (NEXT_LINK(var)) var = NEXT_LINK(var); + while (var) + { + if (first_arg) + first_arg = 0; + else + fprintf(server, ",\n"); + print_server(""); + write_name(server, var); + var = PREV_LINK(var); + } + fprintf(server, ");\n"); + indent--; + } + else + { + fprintf(server, "();\n"); + } + + if (func->args) + { + const var_t *var = func->args; + while (NEXT_LINK(var)) var = NEXT_LINK(var); + while (var) + { + if (is_attr(var->attrs, ATTR_OUT)) + { + unsigned int alignment; + buffer_size += get_required_buffer_size(var, &alignment, PASS_OUT); + buffer_size += alignment; + } + + var = PREV_LINK(var); + } + } + + if (!is_void(def->type, NULL)) + { + unsigned int alignment; + buffer_size += get_required_buffer_size(def, &alignment, PASS_RETURN); + buffer_size += alignment; + } + + if (has_out_arg_or_return(func)) + { + fprintf(server, "\n"); + print_server("_StubMsg.BufferLength = %u;\n", buffer_size); + + type_offset_func = *type_offset; + write_remoting_arguments(server, indent, func, &type_offset_func, PASS_OUT, PHASE_BUFFERSIZE); + + print_server("_pRpcMessage->BufferLength = _StubMsg.BufferLength;\n"); + fprintf(server, "\n"); + print_server("_Status = I_RpcGetBuffer(_pRpcMessage);\n"); + print_server("if (_Status)\n"); + indent++; + print_server("RpcRaiseException(_Status);\n"); + indent--; + fprintf(server, "\n"); + print_server("_StubMsg.Buffer = (unsigned char *)_pRpcMessage->Buffer;\n"); + fprintf(server, "\n"); + } + + type_offset_func = *type_offset; + + /* marshall arguments */ + write_remoting_arguments(server, indent, func, type_offset, PASS_OUT, PHASE_MARSHAL); + + /* marshall the return value */ + if (!is_void(def->type, NULL)) + print_phase_basetype(server, indent, PHASE_MARSHAL, PASS_RETURN, def, "_RetVal"); + + indent--; + print_server("}\n"); + print_server("RpcFinally\n"); + print_server("{\n"); + indent++; + + write_remoting_arguments(server, indent, func, &type_offset_func, PASS_OUT, PHASE_FREE); + + indent--; + print_server("}\n"); + print_server("RpcEndFinally\n"); + + /* calculate buffer length */ + fprintf(server, "\n"); + print_server("_pRpcMessage->BufferLength =\n"); + indent++; + print_server("(unsigned int)(_StubMsg.Buffer - (unsigned char *)_pRpcMessage->Buffer);\n"); + indent--; + indent--; + fprintf(server, "}\n"); + fprintf(server, "\n"); + + /* update proc_offset */ + if (func->args) + { + var = func->args; + while (NEXT_LINK(var)) var = NEXT_LINK(var); + while (var) + { + *proc_offset += get_size_procformatstring_var(var); + var = PREV_LINK(var); + } + } + if (!is_void(def->type, NULL)) + *proc_offset += get_size_procformatstring_var(def); + else + *proc_offset += 2; /* FC_END and FC_PAD */ + + func = PREV_LINK(func); + } +} + + +static void write_dispatchtable(type_t *iface) +{ + unsigned long ver = get_attrv(iface->attrs, ATTR_VERSION); + unsigned long method_count = 0; + func_t *func = iface->funcs; + + print_server("static RPC_DISPATCH_FUNCTION %s_table[] =\n", iface->name); + print_server("{\n"); + indent++; + while (NEXT_LINK(func)) func = NEXT_LINK(func); + while (func) + { + var_t *def = func->def; + + print_server("%s_", iface->name); + write_name(server, def); + fprintf(server, ",\n"); + + method_count++; + func = PREV_LINK(func); + } + print_server("0\n"); + indent--; + print_server("};\n"); + print_server("RPC_DISPATCH_TABLE %s_v%d_%d_DispatchTable =\n", iface->name, LOWORD(ver), HIWORD(ver)); + print_server("{\n"); + indent++; + print_server("%u,\n", method_count); + print_server("%s_table\n", iface->name); + indent--; + print_server("};\n"); + fprintf(server, "\n"); +} + + +static void write_stubdescdecl(type_t *iface) +{ + print_server("static const MIDL_STUB_DESC %s_StubDesc;\n", iface->name); + fprintf(server, "\n"); +} + + +static void write_stubdescriptor(type_t *iface, int expr_eval_routines) +{ + print_server("static const MIDL_STUB_DESC %s_StubDesc =\n", iface->name); + print_server("{\n"); + indent++; + print_server("(void *)& %s___RpcServerInterface,\n", iface->name); + print_server("MIDL_user_allocate,\n"); + print_server("MIDL_user_free,\n"); + print_server("{\n"); + indent++; + print_server("0,\n"); + indent--; + print_server("},\n"); + print_server("0,\n"); + print_server("0,\n"); + if (expr_eval_routines) + print_server("ExprEvalRoutines,\n"); + else + print_server("0,\n"); + print_server("0,\n"); + print_server("__MIDL_TypeFormatString.Format,\n"); + print_server("1, /* -error bounds_check flag */\n"); + print_server("0x10001, /* Ndr library version */\n"); + print_server("0,\n"); + print_server("0x50100a4, /* MIDL Version 5.1.164 */\n"); + print_server("0,\n"); + print_server("0,\n"); + print_server("0, /* notify & notify_flag routine table */\n"); + print_server("1, /* Flags */\n"); + print_server("0, /* Reserved3 */\n"); + print_server("0, /* Reserved4 */\n"); + print_server("0 /* Reserved5 */\n"); + indent--; + print_server("};\n"); + fprintf(server, "\n"); +} + + +static void write_serverinterfacedecl(type_t *iface) +{ + unsigned long ver = get_attrv(iface->attrs, ATTR_VERSION); + UUID *uuid = get_attrp(iface->attrs, ATTR_UUID); + + print_server("extern RPC_DISPATCH_TABLE %s_v%d_%d_DispatchTable;\n", iface->name, LOWORD(ver), HIWORD(ver)); + fprintf(server, "\n"); + print_server("static const RPC_SERVER_INTERFACE %s___RpcServerInterface =\n", iface->name ); + print_server("{\n"); + indent++; + print_server("sizeof(RPC_SERVER_INTERFACE),\n"); + print_server("{{0x%08lx,0x%04x,0x%04x,{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x}},{%d,%d}},\n", + 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], LOWORD(ver), HIWORD(ver)); + print_server("{{0x8a885d04,0x1ceb,0x11c9,{0x9f,0xe8,0x08,0x00,0x2b,0x10,0x48,0x60}},{2,0}},\n"); /* FIXME */ + print_server("&%s_v%d_%d_DispatchTable,\n", iface->name, LOWORD(ver), HIWORD(ver)); + print_server("0,\n"); + print_server("0,\n"); + print_server("0,\n"); + print_server("0,\n"); + print_server("0,\n"); + indent--; + print_server("};\n"); + if (old_names) + print_server("RPC_IF_HANDLE %s_ServerIfHandle = (RPC_IF_HANDLE)& %s___RpcServerInterface;\n", + iface->name, iface->name); + else + print_server("RPC_IF_HANDLE %s_v%d_%d_s_ifspec = (RPC_IF_HANDLE)& %s___RpcServerInterface;\n", + iface->name, LOWORD(ver), HIWORD(ver), iface->name); + fprintf(server, "\n"); +} + +static void write_formatdesc( const char *str ) +{ + print_server("typedef struct _MIDL_%s_FORMAT_STRING\n", str ); + print_server("{\n"); + indent++; + print_server("short Pad;\n"); + print_server("unsigned char Format[%s_FORMAT_STRING_SIZE];\n", str); + indent--; + print_server("} MIDL_%s_FORMAT_STRING;\n", str); + print_server("\n"); +} + + +static void write_formatstringsdecl(ifref_t *ifaces) +{ + print_server("#define TYPE_FORMAT_STRING_SIZE %d\n", + get_size_typeformatstring(ifaces)); + + print_server("#define PROC_FORMAT_STRING_SIZE %d\n", + get_size_procformatstring(ifaces)); + + fprintf(server, "\n"); + write_formatdesc("TYPE"); + write_formatdesc("PROC"); + fprintf(server, "\n"); + print_server("static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString;\n"); + print_server("static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString;\n"); + print_server("\n"); +} + + +static void init_server(void) +{ + if (server) + return; + if (!(server = fopen(server_name, "w"))) + error("Could not open %s for output\n", server_name); + + print_server("/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n", WIDL_FULLVERSION, input_name); + print_server("#include \n"); + fprintf(server, "\n"); + print_server("#include \"%s\"\n", header_name); + fprintf(server, "\n"); +} + + +void write_server(ifref_t *ifaces) +{ + unsigned int proc_offset = 0; + unsigned int type_offset = 2; + ifref_t *iface = ifaces; + + if (!do_server) + return; + if (!ifaces) + return; + END_OF_LIST(iface); + + init_server(); + if (!server) + return; + + write_formatstringsdecl(ifaces); + + for (; iface; iface = PREV_LINK(iface)) + { + if (is_object(iface->iface->attrs) || is_local(iface->iface->attrs)) + continue; + + fprintf(server, "/*****************************************************************************\n"); + fprintf(server, " * %s interface\n", iface->iface->name); + fprintf(server, " */\n"); + fprintf(server, "\n"); + + if (iface->iface->funcs) + { + int expr_eval_routines; + + write_serverinterfacedecl(iface->iface); + write_stubdescdecl(iface->iface); + + write_function_stubs(iface->iface, &proc_offset, &type_offset); + + print_server("#if !defined(__RPC_WIN32__)\n"); + print_server("#error Invalid build platform for this stub.\n"); + print_server("#endif\n"); + + fprintf(server, "\n"); + + expr_eval_routines = write_expr_eval_routines(server, iface->iface->name); + if (expr_eval_routines) + write_expr_eval_routine_list(server, iface->iface->name); + + write_stubdescriptor(iface->iface, expr_eval_routines); + write_dispatchtable(iface->iface); + } + } + + fprintf(server, "\n"); + + write_procformatstring(server, ifaces); + write_typeformatstring(server, ifaces); + + fclose(server); +} diff --git a/reactos/tools/widl_new/typegen.c b/reactos/tools/widl_new/typegen.c new file mode 100644 index 00000000000..68941b361ee --- /dev/null +++ b/reactos/tools/widl_new/typegen.c @@ -0,0 +1,2090 @@ +/* + * Format String Generator for IDL Compiler + * + * Copyright 2005-2006 Eric Kohl + * Copyright 2005-2006 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 "wine/port.h" + +#include +#include +#ifdef HAVE_UNISTD_H +# include +#endif +#include +#include +#include +#include +#include + +#include "widl.h" +#include "utils.h" +#include "parser.h" +#include "header.h" +#include "windef.h" +#include "wine/list.h" + +#include "widl.h" +#include "typegen.h" + +static const func_t *current_func; +static const type_t *current_structure; + +/* name of the structure variable for structure callbacks */ +#define STRUCT_EXPR_EVAL_VAR "pS" + +static struct list expr_eval_routines = LIST_INIT(expr_eval_routines); + +struct expr_eval_routine +{ + struct list entry; + const type_t *structure; + size_t structure_size; + const expr_t *expr; +}; + +static size_t type_memsize(const type_t *t, int ptr_level, const expr_t *array); +static size_t fields_memsize(const var_t *v); + +static int compare_expr(const expr_t *a, const expr_t *b) +{ + int ret; + + if (a->type != b->type) + return a->type - b->type; + + switch (a->type) + { + case EXPR_NUM: + case EXPR_HEXNUM: + case EXPR_TRUEFALSE: + return a->u.lval - b->u.lval; + case EXPR_IDENTIFIER: + return strcmp(a->u.sval, b->u.sval); + case EXPR_COND: + ret = compare_expr(a->ref, b->ref); + if (ret != 0) + return ret; + ret = compare_expr(a->u.ext, b->u.ext); + if (ret != 0) + return ret; + return compare_expr(a->ext2, b->ext2); + case EXPR_OR: + case EXPR_AND: + case EXPR_ADD: + case EXPR_SUB: + case EXPR_MUL: + case EXPR_DIV: + case EXPR_SHL: + case EXPR_SHR: + ret = compare_expr(a->ref, b->ref); + if (ret != 0) + return ret; + return compare_expr(a->u.ext, b->u.ext); + case EXPR_NOT: + case EXPR_NEG: + case EXPR_PPTR: + case EXPR_CAST: + case EXPR_SIZEOF: + return compare_expr(a->ref, b->ref); + case EXPR_VOID: + return 0; + } + return -1; +} + +#define WRITE_FCTYPE(file, fctype, typestring_offset) \ + do { \ + if (file) \ + fprintf(file, "/* %2u */\n", typestring_offset); \ + print_file((file), 2, "0x%02x, /* " #fctype " */\n", RPC_##fctype); \ + } \ + while (0) + +static int print_file(FILE *file, int indent, const char *format, ...) +{ + va_list va; + int i, r; + + if (!file) return 0; + + va_start(va, format); + for (i = 0; i < indent; i++) + fprintf(file, " "); + r = vfprintf(file, format, va); + va_end(va); + return r; +} + +static inline int type_has_ref(const type_t *type) +{ + return (type->type == 0 && type->ref); +} + +static inline int is_base_type(unsigned char type) +{ + switch (type) + { + case RPC_FC_BYTE: + case RPC_FC_CHAR: + case RPC_FC_USMALL: + case RPC_FC_SMALL: + case RPC_FC_WCHAR: + case RPC_FC_USHORT: + case RPC_FC_SHORT: + case RPC_FC_ULONG: + case RPC_FC_LONG: + case RPC_FC_HYPER: + case RPC_FC_IGNORE: + case RPC_FC_FLOAT: + case RPC_FC_DOUBLE: + case RPC_FC_ENUM16: + case RPC_FC_ENUM32: + case RPC_FC_ERROR_STATUS_T: + case RPC_FC_BIND_PRIMITIVE: + return TRUE; + + default: + return FALSE; + } +} + +static size_t write_procformatstring_var(FILE *file, int indent, + const var_t *var, int is_return, unsigned int *type_offset) +{ + size_t size; + int ptr_level = var->ptr_level; + const type_t *type = var->type; + + int is_in = is_attr(var->attrs, ATTR_IN); + int is_out = is_attr(var->attrs, ATTR_OUT); + + if (!is_in && !is_out) is_in = TRUE; + + if (ptr_level == 0 && type_has_ref(type)) + type = type->ref; + + if (ptr_level == 0 && !var->array && is_base_type(type->type)) + { + if (is_return) + print_file(file, indent, "0x53, /* FC_RETURN_PARAM_BASETYPE */\n"); + else + print_file(file, indent, "0x4e, /* FC_IN_PARAM_BASETYPE */\n"); + + switch(type->type) + { +#define CASE_BASETYPE(fctype) \ + case RPC_##fctype: \ + print_file(file, indent, "0x%02x, /* " #fctype " */\n", RPC_##fctype); \ + size = 2; /* includes param type prefix */ \ + break + + CASE_BASETYPE(FC_BYTE); + CASE_BASETYPE(FC_CHAR); + CASE_BASETYPE(FC_WCHAR); + CASE_BASETYPE(FC_USHORT); + CASE_BASETYPE(FC_SHORT); + CASE_BASETYPE(FC_ULONG); + CASE_BASETYPE(FC_LONG); + CASE_BASETYPE(FC_HYPER); + CASE_BASETYPE(FC_IGNORE); + CASE_BASETYPE(FC_USMALL); + CASE_BASETYPE(FC_SMALL); + CASE_BASETYPE(FC_FLOAT); + CASE_BASETYPE(FC_DOUBLE); + CASE_BASETYPE(FC_ERROR_STATUS_T); +#undef CASE_BASETYPE + + case RPC_FC_BIND_PRIMITIVE: + print_file(file, indent, "0x%02x, /* FC_IGNORE */\n", RPC_FC_IGNORE); + size = 2; /* includes param type prefix */ + break; + + default: + error("Unknown/unsupported type: %s (0x%02x)\n", var->name, type->type); + size = 0; + } + } + else + { + if (is_return) + print_file(file, indent, "0x52, /* FC_RETURN_PARAM */\n"); + else if (is_in && is_out) + print_file(file, indent, "0x50, /* FC_IN_OUT_PARAM */\n"); + else if (is_out) + print_file(file, indent, "0x51, /* FC_OUT_PARAM */\n"); + else + print_file(file, indent, "0x4d, /* FC_IN_PARAM */\n"); + + print_file(file, indent, "0x01,\n"); + print_file(file, indent, "NdrFcShort(0x%x),\n", *type_offset); + size = 4; /* includes param type prefix */ + } + *type_offset += get_size_typeformatstring_var(var); + return size; +} + +void write_procformatstring(FILE *file, const ifref_t *ifaces) +{ + const ifref_t *iface = ifaces; + int indent = 0; + var_t *var; + unsigned int type_offset = 2; + + print_file(file, indent, "static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString =\n"); + print_file(file, indent, "{\n"); + indent++; + print_file(file, indent, "0,\n"); + print_file(file, indent, "{\n"); + indent++; + + END_OF_LIST(iface); + + for (; iface; iface = PREV_LINK(iface)) + { + if (is_object(iface->iface->attrs) || is_local(iface->iface->attrs)) + continue; + + if (iface->iface->funcs) + { + func_t *func = iface->iface->funcs; + while (NEXT_LINK(func)) func = NEXT_LINK(func); + for (; func; func = PREV_LINK(func)) + { + /* emit argument data */ + if (func->args) + { + var = func->args; + while (NEXT_LINK(var)) var = NEXT_LINK(var); + while (var) + { + write_procformatstring_var(file, indent, var, FALSE, + &type_offset); + + var = PREV_LINK(var); + } + } + + /* emit return value data */ + var = func->def; + if (is_void(var->type, NULL)) + { + print_file(file, indent, "0x5b, /* FC_END */\n"); + print_file(file, indent, "0x5c, /* FC_PAD */\n"); + } + else + write_procformatstring_var(file, indent, var, TRUE, + &type_offset); + } + } + } + + print_file(file, indent, "0x0\n"); + indent--; + print_file(file, indent, "}\n"); + indent--; + print_file(file, indent, "};\n"); + print_file(file, indent, "\n"); +} + +/* write conformance / variance descriptor */ +static size_t write_conf_or_var_desc(FILE *file, const func_t *func, const type_t *structure, const expr_t *expr) +{ + unsigned char operator_type = 0; + const char *operator_string = "no operators"; + const expr_t *subexpr = expr; + unsigned char correlation_type; + + if (!file) return 4; /* optimisation for sizing pass */ + + if (expr->is_const) + { + if (expr->cval > UCHAR_MAX * (USHRT_MAX + 1) + USHRT_MAX) + error("write_conf_or_var_desc: constant value %ld is greater than " + "the maximum constant size of %d\n", expr->cval, + UCHAR_MAX * (USHRT_MAX + 1) + USHRT_MAX); + + print_file(file, 2, "0x%x, /* Corr desc: constant, val = %ld */\n", + RPC_FC_CONSTANT_CONFORMANCE, expr->cval); + print_file(file, 2, "0x%x,\n", expr->cval & ~USHRT_MAX); + print_file(file, 2, "NdrFcShort(0x%x),\n", expr->cval & USHRT_MAX); + + return 4; + } + + switch (subexpr->type) + { + case EXPR_PPTR: + subexpr = subexpr->ref; + operator_type = RPC_FC_DEREFERENCE; + operator_string = "FC_DEREFERENCE"; + break; + case EXPR_DIV: + if (subexpr->u.ext->is_const && (subexpr->u.ext->cval == 2)) + { + subexpr = subexpr->ref; + operator_type = RPC_FC_DIV_2; + operator_string = "FC_DIV_2"; + } + break; + case EXPR_MUL: + if (subexpr->u.ext->is_const && (subexpr->u.ext->cval == 2)) + { + subexpr = subexpr->ref; + operator_type = RPC_FC_MULT_2; + operator_string = "FC_MULT_2"; + } + break; + case EXPR_SUB: + if (subexpr->u.ext->is_const && (subexpr->u.ext->cval == 1)) + { + subexpr = subexpr->ref; + operator_type = RPC_FC_SUB_1; + operator_string = "FC_SUB_1"; + } + break; + case EXPR_ADD: + if (subexpr->u.ext->is_const && (subexpr->u.ext->cval == 1)) + { + subexpr = subexpr->ref; + operator_type = RPC_FC_ADD_1; + operator_string = "FC_ADD_1"; + } + break; + default: + break; + } + + if (subexpr->type == EXPR_IDENTIFIER) + { + const type_t *correlation_variable = NULL; + unsigned char param_type = 0; + const char *param_type_string = NULL; + size_t offset; + + if (structure) + { + const var_t *var; + + for (offset = 0, var = structure->fields; var; var = NEXT_LINK(var)) + { + offset -= type_memsize(var->type, var->ptr_level, var->array); + if (!strcmp(var->name, subexpr->u.sval)) + { + correlation_variable = var->type; + break; + } + } + if (!correlation_variable) + error("write_conf_or_var_desc: couldn't find variable %s in structure\n", + subexpr->u.sval); + + correlation_type = RPC_FC_NORMAL_CONFORMANCE; + } + else + { + const var_t *var = func->args; + + while (NEXT_LINK(var)) var = NEXT_LINK(var); + /* FIXME: not all stack variables are sizeof(void *) */ + for (offset = 0; var; offset += sizeof(void *), var = PREV_LINK(var)) + { + if (!strcmp(var->name, subexpr->u.sval)) + { + correlation_variable = var->type; + break; + } + } + if (!correlation_variable) + error("write_conf_or_var_desc: couldn't find variable %s in function\n", + subexpr->u.sval); + + correlation_type = RPC_FC_TOP_LEVEL_CONFORMANCE; + } + + while (type_has_ref(correlation_variable)) + correlation_variable = correlation_variable->ref; + + switch (correlation_variable->type) + { + case RPC_FC_CHAR: + case RPC_FC_SMALL: + param_type = RPC_FC_SMALL; + param_type_string = "FC_SMALL"; + break; + case RPC_FC_BYTE: + case RPC_FC_USMALL: + param_type = RPC_FC_USMALL; + param_type_string = "FC_USMALL"; + break; + case RPC_FC_WCHAR: + case RPC_FC_SHORT: + param_type = RPC_FC_SHORT; + param_type_string = "FC_SHORT"; + break; + case RPC_FC_USHORT: + param_type = RPC_FC_USHORT; + param_type_string = "FC_USHORT"; + break; + case RPC_FC_LONG: + param_type = RPC_FC_LONG; + param_type_string = "FC_LONG"; + break; + case RPC_FC_ULONG: + param_type = RPC_FC_ULONG; + param_type_string = "FC_ULONG"; + break; + default: + error("write_conf_or_var_desc: conformance variable type not supported 0x%x\n", + correlation_variable->type); + } + + print_file(file, 2, "0x%x, /* Corr desc: %s%s */\n", + correlation_type | param_type, + correlation_type == RPC_FC_TOP_LEVEL_CONFORMANCE ? "parameter, " : "", + param_type_string); + print_file(file, 2, "0x%x, /* %s */\n", operator_type, operator_string); + print_file(file, 2, "NdrFcShort(0x%x), /* %soffset = %d */\n", + offset, + correlation_type == RPC_FC_TOP_LEVEL_CONFORMANCE ? "x86 stack size / " : "", + offset); + } + else + { + unsigned int callback_offset = 0; + + if (structure) + { + struct expr_eval_routine *eval; + int found = 0; + + LIST_FOR_EACH_ENTRY(eval, &expr_eval_routines, struct expr_eval_routine, entry) + { + if (!strcmp(eval->structure->name, structure->name) && + !compare_expr(eval->expr, expr)) + { + found = 1; + break; + } + callback_offset++; + } + + if (!found) + { + eval = xmalloc(sizeof(*eval)); + eval->structure = structure; + eval->structure_size = fields_memsize(structure->fields); + eval->expr = expr; + list_add_tail(&expr_eval_routines, &eval->entry); + } + + correlation_type = RPC_FC_NORMAL_CONFORMANCE; + } + else + { + error("write_conf_or_var_desc: top-level callback conformance unimplemented\n"); + correlation_type = RPC_FC_TOP_LEVEL_CONFORMANCE; + } + + if (callback_offset > USHRT_MAX) + error("Maximum number of callback routines reached\n"); + + print_file(file, 2, "0x%x, /* Corr desc: %s */\n", + correlation_type, + correlation_type == RPC_FC_TOP_LEVEL_CONFORMANCE ? "parameter" : ""); + print_file(file, 2, "0x%x, /* %s */\n", RPC_FC_CALLBACK, "FC_CALLBACK"); + print_file(file, 2, "NdrFcShort(0x%x), /* %u */\n", callback_offset, callback_offset); + } + return 4; +} + +static size_t fields_memsize(const var_t *v) +{ + size_t size = 0; + const var_t *first = v; + if (!v) return 0; + while (NEXT_LINK(v)) v = NEXT_LINK(v); + while (v) { + size += type_memsize(v->type, v->ptr_level, v->array); + if (v == first) break; + v = PREV_LINK(v); + } + return size; +} + +static size_t type_memsize(const type_t *t, int ptr_level, const expr_t *array) +{ + size_t size = 0; + + if (ptr_level) + return sizeof(void *); + + if (type_has_ref(t)) + return type_memsize(t->ref, 0 /* FIXME */, NULL); + + switch (t->type) + { + case RPC_FC_BYTE: + case RPC_FC_CHAR: + case RPC_FC_USMALL: + case RPC_FC_SMALL: + size = 1; + break; + case RPC_FC_WCHAR: + case RPC_FC_USHORT: + case RPC_FC_SHORT: + case RPC_FC_ENUM16: + size = 2; + break; + case RPC_FC_ULONG: + case RPC_FC_LONG: + case RPC_FC_ERROR_STATUS_T: + case RPC_FC_ENUM32: + case RPC_FC_FLOAT: + size = 4; + break; + case RPC_FC_HYPER: + case RPC_FC_DOUBLE: + size = 8; + break; + case RPC_FC_STRUCT: + case RPC_FC_CVSTRUCT: + case RPC_FC_CPSTRUCT: + case RPC_FC_CSTRUCT: + case RPC_FC_PSTRUCT: + case RPC_FC_BOGUS_STRUCT: + case RPC_FC_ENCAPSULATED_UNION: + case RPC_FC_NON_ENCAPSULATED_UNION: + size = fields_memsize(t->fields); + break; + default: + error("type_memsize: Unknown type %d\n", t->type); + size = 0; + } + + if (array) + { + if (array->is_const) + size *= array->cval; + else + size = 0; + } + + return size; +} + +size_t get_type_memsize(const type_t *type) +{ + return type_memsize(type, 0, NULL); +} + +static int write_pointers(FILE *file, const attr_t *attrs, + const type_t *type, int ptr_level, + const expr_t *array, int level, + unsigned int *typestring_offset) +{ + int pointers_written = 0; + const var_t *v; + + /* don't generate a pointer for first-level arrays since we want to + * descend into them to write their pointers, not stop here */ + if ((level == 0 || ptr_level == 0) && is_array_type(attrs, ptr_level, array)) + { + return write_pointers(file, NULL, type, 0, NULL, level + 1, typestring_offset); + } + + if (ptr_level != 0) + { + /* FIXME: only general algorithm implemented, not the actual writing */ + error("write_pointers: Writing type format string for pointer is unimplemented\n"); + return 1; + } + + /* FIXME: search through all refs for pointers too */ + while(type_has_ref(type)) + type = type->ref; + + switch (type->type) + { + /* note: don't descend into complex structures or unions since these + * will always be generated as a separate type */ + case RPC_FC_STRUCT: + case RPC_FC_CVSTRUCT: + case RPC_FC_CPSTRUCT: + case RPC_FC_CSTRUCT: + case RPC_FC_PSTRUCT: + v = type->fields; + if (!v) break; + while (NEXT_LINK(v)) v = NEXT_LINK(v); + for (; v; v = PREV_LINK(v)) + pointers_written += write_pointers(file, v->attrs, v->type, + v->ptr_level, v->array, + level + 1, + typestring_offset); + + break; + + default: + /* nothing to do */ + break; + } + + return pointers_written; +} + +static size_t write_pointer_description(FILE *file, const attr_t *attrs, + const type_t *type, int ptr_level, + const expr_t *array, int level, + size_t typestring_offset) +{ + size_t size = 0; + const var_t *v; + + /* don't generate a pointer for first-level arrays since we want to + * descend into them to write their pointers, not stop here */ + if ((level == 0 || ptr_level == 0) && is_array_type(attrs, ptr_level, array)) + { + return write_pointer_description(file, NULL, type, 0, NULL, + level + 1, typestring_offset); + } + + if (ptr_level != 0) + { + /* FIXME: only general algorithm implemented, not the actual writing */ + error("write_pointer_description: Writing pointer description is unimplemented\n"); + return 0; + } + + /* FIXME: search through all refs for pointers too */ + + switch (type->type) + { + /* note: don't descend into complex structures or unions since these + * will always be generated as a separate type */ + case RPC_FC_STRUCT: + case RPC_FC_CVSTRUCT: + case RPC_FC_CPSTRUCT: + case RPC_FC_CSTRUCT: + case RPC_FC_PSTRUCT: + v = type->fields; + if (!v) break; + while (NEXT_LINK(v)) v = NEXT_LINK(v); + for (; v; v = PREV_LINK(v)) + size += write_pointer_description(file, v->attrs, v->type, + v->ptr_level, v->array, + level + 1, + typestring_offset); + + break; + + default: + /* nothing to do */ + break; + } + + return size; +} + +static size_t write_string_tfs(FILE *file, const attr_t *attrs, + const type_t *type, const expr_t *array, + const char *name, unsigned int *typestring_offset) +{ + const expr_t *size_is = get_attrp(attrs, ATTR_SIZEIS); + int has_size = size_is && (size_is->type != EXPR_VOID); + size_t start_offset = *typestring_offset; + unsigned char flags = 0; + int pointer_type = get_attrv(attrs, ATTR_POINTERTYPE); + if (!pointer_type) + pointer_type = RPC_FC_RP; + + if (!get_attrp(attrs, ATTR_SIZEIS)) + flags |= RPC_FC_P_SIMPLEPOINTER; + + while (type_has_ref(type)) + type = type->ref; + + if ((type->type != RPC_FC_BYTE) && (type->type != RPC_FC_CHAR) && (type->type != RPC_FC_WCHAR)) + { + error("write_string_tfs: Unimplemented for type 0x%x of name: %s\n", type->type, name); + return start_offset; + } + + print_file(file, 2,"0x%x, 0x%x, /* %s%s */\n", + pointer_type, flags, + pointer_type == RPC_FC_FP ? "FC_FP" : (pointer_type == RPC_FC_UP ? "FC_UP" : "FC_RP"), + (flags & RPC_FC_P_SIMPLEPOINTER) ? " [simple_pointer]" : ""); + *typestring_offset += 2; + + if (!(flags & RPC_FC_P_SIMPLEPOINTER)) + { + print_file(file, 2, "NdrFcShort(0x2),\n"); + *typestring_offset += 2; + } + + if (array && array->is_const) + { + if (array->cval > USHRT_MAX) + error("array size for parameter %s exceeds %d bytes by %ld bytes\n", + name, USHRT_MAX, array->cval - USHRT_MAX); + + if (type->type == RPC_FC_CHAR) + WRITE_FCTYPE(file, FC_CSTRING, *typestring_offset); + else + WRITE_FCTYPE(file, FC_WSTRING, *typestring_offset); + print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD); + *typestring_offset += 2; + + print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", array->cval, array->cval); + *typestring_offset += 2; + + return start_offset; + } + else if (has_size) + { + if (type->type == RPC_FC_CHAR) + WRITE_FCTYPE(file, FC_C_CSTRING, *typestring_offset); + else + WRITE_FCTYPE(file, FC_C_WSTRING, *typestring_offset); + print_file(file, 2, "0x%x, /* FC_STRING_SIZED */\n", RPC_FC_STRING_SIZED); + *typestring_offset += 2; + + *typestring_offset += write_conf_or_var_desc(file, current_func, NULL, size_is); + + return start_offset; + } + else + { + if (type->type == RPC_FC_CHAR) + WRITE_FCTYPE(file, FC_C_CSTRING, *typestring_offset); + else + WRITE_FCTYPE(file, FC_C_WSTRING, *typestring_offset); + print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD); + *typestring_offset += 2; + + return start_offset; + } +} + +static size_t write_array_tfs(FILE *file, const attr_t *attrs, + const type_t *type, const expr_t *array, + const char *name, unsigned int *typestring_offset) +{ + const expr_t *length_is = get_attrp(attrs, ATTR_LENGTHIS); + const expr_t *size_is = get_attrp(attrs, ATTR_SIZEIS); + int has_length = length_is && (length_is->type != EXPR_VOID); + int has_size = (size_is && (size_is->type != EXPR_VOID)) || !array->is_const; + size_t start_offset; + int pointer_type = get_attrv(attrs, ATTR_POINTERTYPE); + if (!pointer_type) + pointer_type = RPC_FC_RP; + + print_file(file, 2, "0x%x, 0x00, /* %s */\n", + pointer_type, + pointer_type == RPC_FC_FP ? "FC_FP" : (pointer_type == RPC_FC_UP ? "FC_UP" : "FC_RP")); + print_file(file, 2, "NdrFcShort(0x2),\n"); + *typestring_offset += 4; + + if (array && NEXT_LINK(array)) /* multi-dimensional array */ + { + error("write_array_tfs: Multi-dimensional arrays not implemented yet (param %s)\n", name); + return 0; + } + else + { + size_t pointer_start_offset = *typestring_offset; + int has_pointer = 0; + + if (write_pointers(file, attrs, type, 0, array, 0, typestring_offset) > 0) + has_pointer = 1; + + start_offset = *typestring_offset; + + if (!has_length && !has_size) + { + /* fixed array */ + size_t size = type_memsize(type, 0, array); + if (size < USHRT_MAX) + { + WRITE_FCTYPE(file, FC_SMFARRAY, *typestring_offset); + /* alignment */ + print_file(file, 2, "0x%x, /* 0 */\n", 0); + /* size */ + print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", size, size); + *typestring_offset += 4; + } + else + { + WRITE_FCTYPE(file, FC_LGFARRAY, *typestring_offset); + /* alignment */ + print_file(file, 2, "0x%x, /* 0 */\n", 0); + /* size */ + print_file(file, 2, "NdrFcLong(0x%x), /* %d */\n", size, size); + *typestring_offset += 6; + } + + if (has_pointer) + { + print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP); + print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD); + *typestring_offset += 2; + *typestring_offset = write_pointer_description(file, attrs, + type, 0, array, 0, pointer_start_offset); + print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END); + *typestring_offset += 1; + } + + print_file(file, 2, "0x0, /* FIXME: write out conversion data */\n"); + print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END); + *typestring_offset += 2; + + return start_offset; + } + else if (has_length && !has_size) + { + /* varying array */ + size_t element_size = type_memsize(type, 0, NULL); + size_t elements = array->cval; + size_t total_size = element_size * elements; + + if (total_size < USHRT_MAX) + { + WRITE_FCTYPE(file, FC_SMVARRAY, *typestring_offset); + /* alignment */ + print_file(file, 2, "0x%x, /* 0 */\n", 0); + /* total size */ + print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", total_size, total_size); + /* number of elements */ + print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", elements, elements); + *typestring_offset += 6; + } + else + { + WRITE_FCTYPE(file, FC_LGVARRAY, *typestring_offset); + /* alignment */ + print_file(file, 2, "0x%x, /* 0 */\n", 0); + /* total size */ + print_file(file, 2, "NdrFcLong(0x%x), /* %d */\n", total_size, total_size); + /* number of elements */ + print_file(file, 2, "NdrFcLong(0x%x), /* %d */\n", elements, elements); + *typestring_offset += 10; + } + /* element size */ + print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", element_size, element_size); + *typestring_offset += 2; + + *typestring_offset += write_conf_or_var_desc(file, current_func, + current_structure, + length_is); + + if (has_pointer) + { + print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP); + print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD); + *typestring_offset += 2; + *typestring_offset += write_pointer_description(file, attrs, + type, 0, array, 0, pointer_start_offset); + print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END); + *typestring_offset += 1; + } + + print_file(file, 2, "0x0, /* FIXME: write out conversion data */\n"); + print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END); + *typestring_offset += 2; + + return start_offset; + } + else if (!has_length && has_size) + { + /* conformant array */ + size_t element_size = type_memsize(type, 0, NULL); + + WRITE_FCTYPE(file, FC_CARRAY, *typestring_offset); + /* alignment */ + print_file(file, 2, "0x%x, /* 0 */\n", 0); + /* element size */ + print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", element_size, element_size); + *typestring_offset += 4; + + *typestring_offset += write_conf_or_var_desc(file, current_func, + current_structure, + size_is ? size_is : array); + + if (has_pointer) + { + print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP); + print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD); + *typestring_offset += 2; + *typestring_offset += write_pointer_description(file, attrs, + type, 0, array, 0, pointer_start_offset); + print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END); + *typestring_offset += 1; + } + + print_file(file, 2, "0x%x, /* FIXME: write out conversion data */\n", type->type); + print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END); + *typestring_offset += 2; + + return start_offset; + } + else + { + /* conformant varying array */ + size_t element_size = type_memsize(type, 0, NULL); + + WRITE_FCTYPE(file, FC_CVARRAY, *typestring_offset); + /* alignment */ + print_file(file, 2, "0x%x, /* 0 */\n", 0); + /* element size */ + print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", element_size, element_size); + *typestring_offset += 4; + + *typestring_offset += write_conf_or_var_desc(file, current_func, + current_structure, + size_is ? size_is : array); + *typestring_offset += write_conf_or_var_desc(file, current_func, + current_structure, + length_is); + + if (has_pointer) + { + print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP); + print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD); + *typestring_offset += 2; + *typestring_offset += write_pointer_description(file, attrs, + type, 0, array, 0, pointer_start_offset); + print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END); + *typestring_offset += 1; + } + + print_file(file, 2, "0x0, /* FIXME: write out conversion data */\n"); + print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END); + *typestring_offset += 2; + + return start_offset; + } + } +} + +static const var_t *find_array_or_string_in_struct(const type_t *type) +{ + /* last field is the first in the fields linked list */ + const var_t *last_field = type->fields; + if (is_array_type(last_field->attrs, last_field->ptr_level, last_field->array)) + return last_field; + + assert((last_field->type->type == RPC_FC_CSTRUCT) || + (last_field->type->type == RPC_FC_CPSTRUCT) || + (last_field->type->type == RPC_FC_CVSTRUCT)); + + return find_array_or_string_in_struct(last_field->type); +} + +static size_t write_struct_members(FILE *file, const type_t *type) +{ + size_t typestring_size = 0; + var_t *field; + + field = type->fields; + while (NEXT_LINK(field)) field = NEXT_LINK(field); + for (; field; field = PREV_LINK(field)) + { + if (is_base_type(field->type->type)) + { + switch (field->type->type) + { +#define CASE_BASETYPE(fctype) \ + case RPC_##fctype: \ + print_file(file, 2, "0x%02x,\t\t/* " #fctype " */\n", RPC_##fctype); \ + typestring_size++; \ + break; + CASE_BASETYPE(FC_BYTE); + CASE_BASETYPE(FC_CHAR); + CASE_BASETYPE(FC_SMALL); + CASE_BASETYPE(FC_USMALL); + CASE_BASETYPE(FC_WCHAR); + CASE_BASETYPE(FC_SHORT); + CASE_BASETYPE(FC_USHORT); + CASE_BASETYPE(FC_LONG); + CASE_BASETYPE(FC_ULONG); + CASE_BASETYPE(FC_FLOAT); + CASE_BASETYPE(FC_HYPER); + CASE_BASETYPE(FC_DOUBLE); + CASE_BASETYPE(FC_ENUM16); + CASE_BASETYPE(FC_ENUM32); + CASE_BASETYPE(FC_IGNORE); + CASE_BASETYPE(FC_ERROR_STATUS_T); + default: + break; +#undef CASE_BASETYPE + } + } + else + error("Unsupported member type 0x%x\n", field->type->type); + } + + if (typestring_size % 1) + { + print_file(file, 2, "0x%x,\t\t/* FC_PAD */\n", RPC_FC_PAD); + typestring_size++; + } + + print_file(file, 2, "0x%x,\t\t/* FC_END */\n", RPC_FC_END); + typestring_size++; + + return typestring_size; +} + +static size_t write_struct_tfs(FILE *file, const type_t *type, + const char *name, unsigned int *typestring_offset) +{ + unsigned int total_size; + const var_t *array; + size_t start_offset; + size_t array_offset; + size_t pointer_offset; + + switch (type->type) + { + case RPC_FC_STRUCT: + case RPC_FC_PSTRUCT: + total_size = type_memsize(type, 0, NULL); + + if (total_size > USHRT_MAX) + error("structure size for parameter %s exceeds %d bytes by %d bytes\n", + name, USHRT_MAX, total_size - USHRT_MAX); + + if (type->type == RPC_FC_PSTRUCT) + { + pointer_offset = *typestring_offset; + write_pointers(file, NULL, type, 0, NULL, 0, typestring_offset); + } + else pointer_offset = 0; /* silence warning */ + + start_offset = *typestring_offset; + if (type->type == RPC_FC_STRUCT) + WRITE_FCTYPE(file, FC_STRUCT, *typestring_offset); + else + WRITE_FCTYPE(file, FC_PSTRUCT, *typestring_offset); + /* alignment */ + print_file(file, 2, "0x3,\n"); /* FIXME */ + /* total size */ + print_file(file, 2, "NdrFcShort(0x%x), /* %u */\n", total_size, total_size); + *typestring_offset += 4; + + if (type->type == RPC_FC_PSTRUCT) + { + print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP); + print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD); + *typestring_offset += 2; + *typestring_offset += write_pointer_description(file, NULL, + type, 0, NULL, 0, pointer_offset); + print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END); + *typestring_offset += 1; + } + + /* member layout */ + *typestring_offset += write_struct_members(file, type); + return start_offset; + case RPC_FC_CSTRUCT: + case RPC_FC_CPSTRUCT: + total_size = type_memsize(type, 0, NULL); + + if (total_size > USHRT_MAX) + error("structure size for parameter %s exceeds %d bytes by %d bytes\n", + name, USHRT_MAX, total_size - USHRT_MAX); + + array = find_array_or_string_in_struct(type); + current_structure = type; + array_offset = write_array_tfs(file, array->attrs, array->type, + array->array, array->name, + typestring_offset); + current_structure = NULL; + + if (type->type == RPC_FC_CPSTRUCT) + { + pointer_offset = *typestring_offset; + write_pointers(file, NULL, type, 0, NULL, 0, typestring_offset); + } + else pointer_offset = 0; /* silence warning */ + + start_offset = *typestring_offset; + if (type->type == RPC_FC_CSTRUCT) + WRITE_FCTYPE(file, FC_CSTRUCT, *typestring_offset); + else + WRITE_FCTYPE(file, FC_CPSTRUCT, *typestring_offset); + /* alignment */ + print_file(file, 2, "0x0,\n"); + /* total size */ + print_file(file, 2, "NdrFcShort(0x%x), /* %u */\n", total_size, total_size); + *typestring_offset += 4; + print_file(file, 2, "NdrFcShort(0x%x), /* offset = %d (%u) */\n", + array_offset - *typestring_offset, + array_offset - *typestring_offset, + array_offset); + *typestring_offset += 2; + + if (type->type == RPC_FC_CPSTRUCT) + { + print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP); + print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD); + *typestring_offset += 2; + *typestring_offset += write_pointer_description(file, NULL, + type, 0, NULL, 0, pointer_offset); + print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END); + *typestring_offset += 1; + } + + print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END); + *typestring_offset += 1; + + return start_offset; + case RPC_FC_CVSTRUCT: + total_size = type_memsize(type, 0, NULL); + + if (total_size > USHRT_MAX) + error("structure size for parameter %s exceeds %d bytes by %d bytes\n", + name, USHRT_MAX, total_size - USHRT_MAX); + + array = find_array_or_string_in_struct(type); + current_structure = type; + if (is_attr(array->attrs, ATTR_STRING)) + array_offset = write_string_tfs(file, array->attrs, array->type, + array->array, array->name, + typestring_offset); + else + array_offset = write_array_tfs(file, array->attrs, array->type, + array->array, array->name, + typestring_offset); + current_structure = NULL; + + pointer_offset = *typestring_offset; + if (!write_pointers(file, NULL, type, 0, NULL, 0, typestring_offset)) + pointer_offset = 0; + + start_offset = *typestring_offset; + WRITE_FCTYPE(file, FC_CVSTRUCT, *typestring_offset); + /* alignment */ + print_file(file, 2, "0x0,\n"); + /* total size */ + print_file(file, 2, "NdrFcShort(0x%x), /* %u */\n", total_size, total_size); + *typestring_offset += 4; + print_file(file, 2, "NdrFcShort(0x%x), /* offset = %d (%u) */\n", + array_offset - *typestring_offset, + array_offset - *typestring_offset, + array_offset); + *typestring_offset += 2; + + if (pointer_offset != 0) + { + print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP); + print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD); + *typestring_offset += 2; + *typestring_offset += write_pointer_description(file, NULL, + type, 0, NULL, 0, pointer_offset); + print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END); + *typestring_offset += 1; + } + + print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END); + *typestring_offset += 1; + + return start_offset; + default: + error("write_struct_tfs: Unimplemented for type 0x%x\n", type->type); + return *typestring_offset; + } +} + +static void write_pointer_only_tfs(FILE *file, const attr_t *attrs, size_t offset, unsigned int *typeformat_offset) +{ + int in_attr, out_attr; + unsigned char flags = 0; + int pointer_type = get_attrv(attrs, ATTR_POINTERTYPE); + if (!pointer_type) pointer_type = RPC_FC_RP; + in_attr = is_attr(attrs, ATTR_IN); + out_attr = is_attr(attrs, ATTR_OUT); + if (!in_attr && !out_attr) in_attr = 1; + + if (out_attr && !in_attr && pointer_type == RPC_FC_RP) + flags |= 0x04; + + print_file(file, 2, "0x%x, 0x%x,\t\t/* %s%s */\n", + pointer_type, + flags, + pointer_type == RPC_FC_FP ? "FC_FP" : (pointer_type == RPC_FC_UP ? "FC_UP" : "FC_RP"), + (flags & 0x04) ? " [allocated_on_stack]" : ""); + print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", offset, offset); + *typeformat_offset += 4; +} + +static size_t write_union_tfs(FILE *file, const attr_t *attrs, + const type_t *type, const char *name, + unsigned int *typeformat_offset) +{ + error("write_union_tfs: Unimplemented\n"); + return *typeformat_offset; +} + +static size_t write_typeformatstring_var(FILE *file, int indent, + const var_t *var, unsigned int *typeformat_offset) +{ + const type_t *type = var->type; + int ptr_level = var->ptr_level; + + chat("write_typeformatstring_var: %s\n", var->name); + + while (TRUE) + { + chat("write_typeformatstring: type->type = 0x%x, type->name = %s, ptr_level = %d\n", type->type, type->name, ptr_level); + + if (is_string_type(var->attrs, ptr_level, var->array)) + return write_string_tfs(file, var->attrs, type, var->array, var->name, typeformat_offset); + + if (is_array_type(var->attrs, ptr_level, var->array)) + return write_array_tfs(file, var->attrs, type, var->array, var->name, typeformat_offset); + + if (ptr_level == 0) + { + /* follow reference if the type has one */ + if (type_has_ref(type)) + { + type = type->ref; + /* FIXME: get new ptr_level from type */ + continue; + } + + /* basic types don't need a type format string */ + if (is_base_type(type->type)) + return 0; + + switch (type->type) + { + case RPC_FC_STRUCT: + case RPC_FC_PSTRUCT: + case RPC_FC_CSTRUCT: + case RPC_FC_CPSTRUCT: + case RPC_FC_CVSTRUCT: + case RPC_FC_BOGUS_STRUCT: + return write_struct_tfs(file, type, var->name, typeformat_offset); + case RPC_FC_ENCAPSULATED_UNION: + case RPC_FC_NON_ENCAPSULATED_UNION: + return write_union_tfs(file, var->attrs, type, var->name, typeformat_offset); + case RPC_FC_IGNORE: + case RPC_FC_BIND_PRIMITIVE: + /* nothing to do */ + return 0; + default: + error("write_typeformatstring_var: Unsupported type 0x%x for variable %s\n", type->type, var->name); + } + } + else if (ptr_level == 1 && !type_has_ref(type)) + { + size_t start_offset = *typeformat_offset; + int in_attr = is_attr(var->attrs, ATTR_IN); + int out_attr = is_attr(var->attrs, ATTR_OUT); + int pointer_type = get_attrv(var->attrs, ATTR_POINTERTYPE); + if (!pointer_type) pointer_type = RPC_FC_RP; + + /* special case for pointers to base types */ + switch (type->type) + { +#define CASE_BASETYPE(fctype) \ + case RPC_##fctype: \ + print_file(file, indent, "0x%x, 0x%x, /* %s %s[simple_pointer] */\n", \ + pointer_type, \ + (!in_attr && out_attr) ? 0x0C : 0x08, \ + pointer_type == RPC_FC_FP ? "FC_FP" : (pointer_type == RPC_FC_UP ? "FC_UP" : "FC_RP"), \ + (!in_attr && out_attr) ? "[allocated_on_stack] " : ""); \ + print_file(file, indent, "0x%02x, /* " #fctype " */\n", RPC_##fctype); \ + print_file(file, indent, "0x5c, /* FC_PAD */\n"); \ + *typeformat_offset += 4; \ + return start_offset + CASE_BASETYPE(FC_BYTE); + CASE_BASETYPE(FC_CHAR); + CASE_BASETYPE(FC_SMALL); + CASE_BASETYPE(FC_USMALL); + CASE_BASETYPE(FC_WCHAR); + CASE_BASETYPE(FC_SHORT); + CASE_BASETYPE(FC_USHORT); + CASE_BASETYPE(FC_LONG); + CASE_BASETYPE(FC_ULONG); + CASE_BASETYPE(FC_FLOAT); + CASE_BASETYPE(FC_HYPER); + CASE_BASETYPE(FC_DOUBLE); + CASE_BASETYPE(FC_ENUM16); + CASE_BASETYPE(FC_ENUM32); + CASE_BASETYPE(FC_IGNORE); + CASE_BASETYPE(FC_ERROR_STATUS_T); + default: + break; + } + } + + assert(ptr_level > 0); + + if (file) + fprintf(file, "/* %2u */\n", *typeformat_offset); + write_pointer_only_tfs(file, var->attrs, 2, typeformat_offset); + + ptr_level--; + } +} + + +void write_typeformatstring(FILE *file, const ifref_t *ifaces) +{ + int indent = 0; + var_t *var; + unsigned int typeformat_offset; + const ifref_t *iface = ifaces; + + print_file(file, indent, "static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString =\n"); + print_file(file, indent, "{\n"); + indent++; + print_file(file, indent, "0,\n"); + print_file(file, indent, "{\n"); + indent++; + print_file(file, indent, "NdrFcShort(0x0),\n"); + typeformat_offset = 2; + + END_OF_LIST(iface); + + for (; iface; iface = PREV_LINK(iface)) + { + if (is_object(iface->iface->attrs) || is_local(iface->iface->attrs)) + continue; + + if (iface->iface->funcs) + { + func_t *func = iface->iface->funcs; + while (NEXT_LINK(func)) func = NEXT_LINK(func); + for (; func; func = PREV_LINK(func)) + { + current_func = func; + if (func->args) + { + var = func->args; + while (NEXT_LINK(var)) var = NEXT_LINK(var); + while (var) + { + write_typeformatstring_var(file, indent, var, + &typeformat_offset); + var = PREV_LINK(var); + } + } + } + } + } + + print_file(file, indent, "0x0\n"); + indent--; + print_file(file, indent, "}\n"); + indent--; + print_file(file, indent, "};\n"); + print_file(file, indent, "\n"); +} + +static unsigned int get_required_buffer_size_type( + const type_t *type, int ptr_level, const expr_t *array, + const char *name, unsigned int *alignment) +{ + *alignment = 0; + if (ptr_level == 0 && !array && !type_has_ref(type)) + { + switch (type->type) + { + case RPC_FC_BYTE: + case RPC_FC_CHAR: + case RPC_FC_USMALL: + case RPC_FC_SMALL: + *alignment = 4; + return 1; + + case RPC_FC_WCHAR: + case RPC_FC_USHORT: + case RPC_FC_SHORT: + *alignment = 4; + return 2; + + case RPC_FC_ULONG: + case RPC_FC_LONG: + case RPC_FC_FLOAT: + case RPC_FC_ERROR_STATUS_T: + *alignment = 4; + return 4; + + case RPC_FC_HYPER: + case RPC_FC_DOUBLE: + *alignment = 8; + return 8; + + case RPC_FC_IGNORE: + case RPC_FC_BIND_PRIMITIVE: + return 0; + + case RPC_FC_STRUCT: + { + size_t size = 0; + const var_t *field; + for (field = type->fields; field; field = NEXT_LINK(field)) + { + unsigned int alignment; + size += get_required_buffer_size_type( + field->type, field->ptr_level, field->array, field->name, + &alignment); + } + return size; + } + + default: + error("get_required_buffer_size: Unknown/unsupported type: %s (0x%02x)\n", name, type->type); + return 0; + } + } + if (ptr_level == 0 && type_has_ref(type)) + return get_required_buffer_size_type(type->ref, 0 /* FIXME */, array, name, alignment); + return 0; +} + +unsigned int get_required_buffer_size(const var_t *var, unsigned int *alignment, enum pass pass) +{ + expr_t *size_is = get_attrp(var->attrs, ATTR_SIZEIS); + int has_size = (size_is && (size_is->type != EXPR_VOID)); + int in_attr = is_attr(var->attrs, ATTR_IN); + int out_attr = is_attr(var->attrs, ATTR_OUT); + + if (!in_attr && !out_attr) + in_attr = 1; + + *alignment = 0; + + if (pass == PASS_OUT) + { + if (out_attr && var->ptr_level > 0) + { + type_t *type = var->type; + while (type->type == 0 && type->ref) + type = type->ref; + + if (type->type == RPC_FC_STRUCT) + { + const var_t *field; + unsigned int size = 36; + for (field = type->fields; field; field = NEXT_LINK(field)) + { + unsigned int align; + size += get_required_buffer_size_type( + field->type, field->ptr_level, field->array, field->name, + &align); + } + return size; + } + else + return get_required_buffer_size_type(var->type, 0 /* FIXME */, var->array, var->name, alignment); + } + return 0; + } + else + { + if ((!out_attr || in_attr) && !has_size && !is_attr(var->attrs, ATTR_STRING) && !var->array) + { + if (var->ptr_level > 0 || (var->ptr_level == 0 && type_has_ref(var->type))) + { + type_t *type = var->type; + while (type->type == 0 && type->ref) + type = type->ref; + + if (is_base_type(type->type)) + { + return 25; + } + else if (type->type == RPC_FC_STRUCT) + { + unsigned int size = 36; + const var_t *field; + for (field = type->fields; field; field = NEXT_LINK(field)) + { + unsigned int align; + size += get_required_buffer_size_type( + field->type, field->ptr_level, field->array, field->name, + &align); + } + return size; + } + } + } + + return get_required_buffer_size_type(var->type, var->ptr_level, var->array, var->name, alignment); + } +} + +static void print_phase_function(FILE *file, int indent, const char *type, + enum remoting_phase phase, + const char *varname, unsigned int type_offset) +{ + const char *function; + switch (phase) + { + case PHASE_BUFFERSIZE: + function = "BufferSize"; + break; + case PHASE_MARSHAL: + function = "Marshall"; + break; + case PHASE_UNMARSHAL: + function = "Unmarshall"; + break; + case PHASE_FREE: + function = "Free"; + break; + default: + assert(0); + return; + } + + print_file(file, indent, "Ndr%s%s(\n", type, function); + indent++; + print_file(file, indent, "&_StubMsg,\n"); + print_file(file, indent, "%s%s,\n", + (phase == PHASE_UNMARSHAL) ? "(unsigned char **)&" : "(unsigned char *)", + varname); + print_file(file, indent, "(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%d]%s\n", + type_offset, (phase == PHASE_UNMARSHAL) ? "," : ");"); + if (phase == PHASE_UNMARSHAL) + print_file(file, indent, "0);\n"); + indent--; +} + +void print_phase_basetype(FILE *file, int indent, enum remoting_phase phase, + enum pass pass, const var_t *var, + const char *varname) +{ + const type_t *type = var->type; + unsigned int size; + unsigned int alignment = 0; + + /* no work to do for other phases, buffer sizing is done elsewhere */ + if (phase != PHASE_MARSHAL && phase != PHASE_UNMARSHAL) + return; + + while (type_has_ref(type)) + type = type->ref; + + switch (type->type) + { + case RPC_FC_BYTE: + case RPC_FC_CHAR: + case RPC_FC_SMALL: + case RPC_FC_USMALL: + size = 1; + alignment = 1; + break; + + case RPC_FC_WCHAR: + case RPC_FC_USHORT: + case RPC_FC_SHORT: + size = 2; + alignment = 2; + break; + + case RPC_FC_ULONG: + case RPC_FC_LONG: + case RPC_FC_FLOAT: + case RPC_FC_ERROR_STATUS_T: + size = 4; + alignment = 4; + break; + + case RPC_FC_HYPER: + case RPC_FC_DOUBLE: + size = 8; + alignment = 8; + break; + + case RPC_FC_IGNORE: + case RPC_FC_BIND_PRIMITIVE: + /* no marshalling needed */ + return; + + default: + error("print_phase_basetype: Unsupported type: %s (0x%02x, ptr_level: 0)\n", var->name, type->type); + size = 0; + } + + print_file(file, indent, "_StubMsg.Buffer = (unsigned char *)(((long)_StubMsg.Buffer + %u) & ~0x%x);\n", + alignment - 1, alignment - 1); + + if (phase == PHASE_MARSHAL) + { + print_file(file, indent, "*("); + write_type(file, var->type, NULL, var->tname); + if (var->ptr_level) + fprintf(file, " *)_StubMsg.Buffer = *"); + else + fprintf(file, " *)_StubMsg.Buffer = "); + fprintf(file, varname); + fprintf(file, ";\n"); + } + else if (phase == PHASE_UNMARSHAL) + { + if (pass == PASS_IN || pass == PASS_RETURN) + print_file(file, indent, ""); + else + print_file(file, indent, "*"); + fprintf(file, varname); + if (pass == PASS_IN && var->ptr_level) + fprintf(file, " = ("); + else + fprintf(file, " = *("); + write_type(file, var->type, NULL, var->tname); + fprintf(file, " *)_StubMsg.Buffer;\n"); + } + + print_file(file, indent, "_StubMsg.Buffer += sizeof("); + write_type(file, var->type, NULL, var->tname); + fprintf(file, ");\n"); +} + +/* returns whether the MaxCount, Offset or ActualCount members need to be + * filled in for the specified phase */ +static inline int is_size_needed_for_phase(enum remoting_phase phase) +{ + return (phase != PHASE_UNMARSHAL); +} + +void write_remoting_arguments(FILE *file, int indent, const func_t *func, + unsigned int *type_offset, enum pass pass, + enum remoting_phase phase) +{ + const expr_t *length_is; + const expr_t *size_is; + int in_attr, out_attr, has_length, has_size, pointer_type; + var_t *var; + + if (!func->args) + return; + + var = func->args; + while (NEXT_LINK(var)) var = NEXT_LINK(var); + for (; var; *type_offset += get_size_typeformatstring_var(var), var = PREV_LINK(var)) + { + const type_t *type = var->type; + length_is = get_attrp(var->attrs, ATTR_LENGTHIS); + size_is = get_attrp(var->attrs, ATTR_SIZEIS); + has_length = length_is && (length_is->type != EXPR_VOID); + has_size = (size_is && (size_is->type != EXPR_VOID)) || (var->array && !var->array->is_const); + + pointer_type = get_attrv(var->attrs, ATTR_POINTERTYPE); + if (!pointer_type) + pointer_type = RPC_FC_RP; + + in_attr = is_attr(var->attrs, ATTR_IN); + out_attr = is_attr(var->attrs, ATTR_OUT); + if (!in_attr && !out_attr) + in_attr = 1; + + switch (pass) + { + case PASS_IN: + if (!in_attr) + continue; + break; + case PASS_OUT: + if (!out_attr) + continue; + break; + case PASS_RETURN: + break; + } + + while (type_has_ref(type)) + type = type->ref; + + if (is_string_type(var->attrs, var->ptr_level, var->array)) + { + if (var->array && var->array->is_const) + print_phase_function(file, indent, "NonConformantString", phase, var->name, *type_offset); + else + { + if (size_is && is_size_needed_for_phase(phase)) + { + print_file(file, indent, "_StubMsg.MaxCount = (unsigned long)"); + write_expr(file, size_is, 1); + fprintf(file, ";\n"); + } + + if ((phase == PHASE_FREE) || (pointer_type == RPC_FC_UP)) + print_phase_function(file, indent, "Pointer", phase, var->name, *type_offset); + else + print_phase_function(file, indent, "ConformantString", phase, var->name, + *type_offset + (has_size ? 4 : 2)); + } + } + else if (is_array_type(var->attrs, var->ptr_level, var->array)) + { + const char *array_type; + + if (var->array && NEXT_LINK(var->array)) /* multi-dimensional array */ + array_type = "ComplexArray"; + else + { + if (!has_length && !has_size) + array_type = "FixedArray"; + else if (has_length && !has_size) + { + if (is_size_needed_for_phase(phase)) + { + print_file(file, indent, "_StubMsg.Offset = (unsigned long)0;\n"); /* FIXME */ + print_file(file, indent, "_StubMsg.ActualCount = (unsigned long)"); + write_expr(file, length_is, 1); + fprintf(file, ";\n\n"); + } + array_type = "VaryingArray"; + } + else if (!has_length && has_size) + { + if (is_size_needed_for_phase(phase) && phase != PHASE_FREE) + { + print_file(file, indent, "_StubMsg.MaxCount = (unsigned long)"); + write_expr(file, size_is ? size_is : var->array, 1); + fprintf(file, ";\n\n"); + } + array_type = "ConformantArray"; + } + else + { + if (is_size_needed_for_phase(phase)) + { + print_file(file, indent, "_StubMsg.MaxCount = (unsigned long)"); + write_expr(file, size_is ? size_is : var->array, 1); + fprintf(file, ";\n"); + print_file(file, indent, "_StubMsg.Offset = (unsigned long)0;\n"); /* FIXME */ + print_file(file, indent, "_StubMsg.ActualCount = (unsigned long)"); + write_expr(file, length_is, 1); + fprintf(file, ";\n\n"); + } + array_type = "ConformantVaryingArray"; + } + } + + if (!in_attr && phase == PHASE_FREE) + { + print_file(file, indent, "if (%s)\n", var->name); + indent++; + print_file(file, indent, "_StubMsg.pfnFree(%s);\n", var->name); + } + else if (phase != PHASE_FREE) + { + if (pointer_type == RPC_FC_UP) + print_phase_function(file, indent, "Pointer", phase, var->name, *type_offset); + else + print_phase_function(file, indent, array_type, phase, var->name, *type_offset + 4); + } + } + else if (var->ptr_level == 0 && is_base_type(type->type)) + { + print_phase_basetype(file, indent, phase, pass, var, var->name); + } + else if (var->ptr_level == 0) + { + const char *ndrtype; + + switch (type->type) + { + case RPC_FC_STRUCT: + ndrtype = "SimpleStruct"; + break; + case RPC_FC_CSTRUCT: + case RPC_FC_CPSTRUCT: + ndrtype = "ConformantStruct"; + break; + case RPC_FC_CVSTRUCT: + ndrtype = "ConformantVaryingStruct"; + break; + case RPC_FC_BOGUS_STRUCT: + ndrtype = "ComplexStruct"; + break; + default: + error("write_remoting_arguments: Unsupported type: %s (0x%02x, ptr_level: %d)\n", + var->name, type->type, var->ptr_level); + ndrtype = NULL; + } + + print_phase_function(file, indent, ndrtype, phase, var->name, *type_offset); + } + else + { + if ((var->ptr_level == 1) && (pointer_type == RPC_FC_RP) && is_base_type(type->type)) + { + print_phase_basetype(file, indent, phase, pass, var, var->name); + } + else if ((var->ptr_level == 1) && (pointer_type == RPC_FC_RP) && (type->type == RPC_FC_STRUCT)) + { + if (phase != PHASE_BUFFERSIZE && phase != PHASE_FREE) + print_phase_function(file, indent, "SimpleStruct", phase, var->name, *type_offset + 4); + } + else + { + print_phase_function(file, indent, "Pointer", phase, var->name, *type_offset); + } + } + fprintf(file, "\n"); + } +} + + +size_t get_size_procformatstring_var(const var_t *var) +{ + unsigned int type_offset = 2; + return write_procformatstring_var(NULL, 0, var, FALSE, &type_offset); +} + + +size_t get_size_typeformatstring_var(const var_t *var) +{ + unsigned int type_offset = 0; + write_typeformatstring_var(NULL, 0, var, &type_offset); + return type_offset; +} + +size_t get_size_procformatstring(const ifref_t *ifaces) +{ + const ifref_t *iface = ifaces; + size_t size = 1; + func_t *func; + var_t *var; + + END_OF_LIST(iface); + + for (; iface; iface = PREV_LINK(iface)) + { + if (is_object(iface->iface->attrs) || is_local(iface->iface->attrs)) + continue; + + if (iface->iface->funcs) + { + func = iface->iface->funcs; + while (NEXT_LINK(func)) func = NEXT_LINK(func); + while (func) + { + /* argument list size */ + if (func->args) + { + var = func->args; + while (NEXT_LINK(var)) var = NEXT_LINK(var); + while (var) + { + size += get_size_procformatstring_var(var); + var = PREV_LINK(var); + } + } + + var = func->def; + /* return value size */ + if (is_void(var->type, NULL)) + size += 2; + else + size += get_size_procformatstring_var(var); + + func = PREV_LINK(func); + } + } + } + return size; +} + +size_t get_size_typeformatstring(const ifref_t *ifaces) +{ + const ifref_t *iface = ifaces; + size_t size = 3; + func_t *func; + var_t *var; + + END_OF_LIST(iface); + + for (; iface; iface = PREV_LINK(iface)) + { + if (is_object(iface->iface->attrs) || is_local(iface->iface->attrs)) + continue; + + if (iface->iface->funcs) + { + func = iface->iface->funcs; + while (NEXT_LINK(func)) func = NEXT_LINK(func); + while (func) + { + /* argument list size */ + if (func->args) + { + var = func->args; + while (NEXT_LINK(var)) var = NEXT_LINK(var); + while (var) + { + size += get_size_typeformatstring_var(var); + var = PREV_LINK(var); + } + } + + func = PREV_LINK(func); + } + } + } + return size; +} + +static void write_struct_expr(FILE *h, const expr_t *e, int brackets, + const var_t *fields, const char *structvar) +{ + switch (e->type) { + case EXPR_VOID: + break; + case EXPR_NUM: + fprintf(h, "%ld", e->u.lval); + break; + case EXPR_HEXNUM: + fprintf(h, "0x%lx", e->u.lval); + break; + case EXPR_TRUEFALSE: + if (e->u.lval == 0) + fprintf(h, "FALSE"); + else + fprintf(h, "TRUE"); + break; + case EXPR_IDENTIFIER: + { + const var_t *field; + for (field = fields; field; field = NEXT_LINK(field)) + { + if (!strcmp(e->u.sval, field->name)) + { + fprintf(h, "%s->%s", structvar, e->u.sval); + break; + } + } + if (!field) error("no field found for identifier %s\n", e->u.sval); + break; + } + case EXPR_NEG: + fprintf(h, "-"); + write_struct_expr(h, e->ref, 1, fields, structvar); + break; + case EXPR_NOT: + fprintf(h, "~"); + write_struct_expr(h, e->ref, 1, fields, structvar); + break; + case EXPR_PPTR: + fprintf(h, "*"); + write_struct_expr(h, e->ref, 1, fields, structvar); + break; + case EXPR_CAST: + fprintf(h, "("); + write_type(h, e->u.tref->ref, NULL, e->u.tref->name); + fprintf(h, ")"); + write_struct_expr(h, e->ref, 1, fields, structvar); + break; + case EXPR_SIZEOF: + fprintf(h, "sizeof("); + write_type(h, e->u.tref->ref, NULL, e->u.tref->name); + fprintf(h, ")"); + break; + case EXPR_SHL: + case EXPR_SHR: + case EXPR_MUL: + case EXPR_DIV: + case EXPR_ADD: + case EXPR_SUB: + case EXPR_AND: + case EXPR_OR: + if (brackets) fprintf(h, "("); + write_struct_expr(h, e->ref, 1, fields, structvar); + switch (e->type) { + case EXPR_SHL: fprintf(h, " << "); break; + case EXPR_SHR: fprintf(h, " >> "); break; + case EXPR_MUL: fprintf(h, " * "); break; + case EXPR_DIV: fprintf(h, " / "); break; + case EXPR_ADD: fprintf(h, " + "); break; + case EXPR_SUB: fprintf(h, " - "); break; + case EXPR_AND: fprintf(h, " & "); break; + case EXPR_OR: fprintf(h, " | "); break; + default: break; + } + write_struct_expr(h, e->u.ext, 1, fields, structvar); + if (brackets) fprintf(h, ")"); + break; + case EXPR_COND: + if (brackets) fprintf(h, "("); + write_struct_expr(h, e->ref, 1, fields, structvar); + fprintf(h, " ? "); + write_struct_expr(h, e->u.ext, 1, fields, structvar); + fprintf(h, " : "); + write_struct_expr(h, e->ext2, 1, fields, structvar); + if (brackets) fprintf(h, ")"); + break; + } +} + +int write_expr_eval_routines(FILE *file, const char *iface) +{ + int result = 0; + struct expr_eval_routine *eval; + unsigned short callback_offset = 0; + + LIST_FOR_EACH_ENTRY(eval, &expr_eval_routines, struct expr_eval_routine, entry) + { + int indent = 0; + result = 1; + print_file(file, indent, "static void __RPC_USER %s_%sExprEval_%04u(PMIDL_STUB_MESSAGE pStubMsg)\n", + iface, eval->structure->name, callback_offset); + print_file(file, indent, "{\n"); + indent++; + print_file(file, indent, "struct %s *" STRUCT_EXPR_EVAL_VAR " = (struct %s *)(pStubMsg->StackTop - %u);\n", + eval->structure->name, eval->structure->name, eval->structure_size); + fprintf(file, "\n"); + print_file(file, indent, "pStubMsg->Offset = 0;\n"); /* FIXME */ + print_file(file, indent, "pStubMsg->MaxCount = (unsigned long)"); + write_struct_expr(file, eval->expr, 1, eval->structure->fields, STRUCT_EXPR_EVAL_VAR); + fprintf(file, ";\n"); + indent--; + print_file(file, indent, "}\n\n"); + callback_offset++; + } + return result; +} + +void write_expr_eval_routine_list(FILE *file, const char *iface) +{ + struct expr_eval_routine *eval; + struct expr_eval_routine *cursor; + unsigned short callback_offset = 0; + + fprintf(file, "static const EXPR_EVAL ExprEvalRoutines[] =\n"); + fprintf(file, "{\n"); + + LIST_FOR_EACH_ENTRY_SAFE(eval, cursor, &expr_eval_routines, struct expr_eval_routine, entry) + { + print_file(file, 1, "%s_%sExprEval_%04u,\n", + iface, eval->structure->name, callback_offset); + + callback_offset++; + list_remove(&eval->entry); + free(eval); + } + + fprintf(file, "};\n\n"); +} diff --git a/reactos/tools/widl_new/typegen.h b/reactos/tools/widl_new/typegen.h new file mode 100644 index 00000000000..eb4c4c7689b --- /dev/null +++ b/reactos/tools/widl_new/typegen.h @@ -0,0 +1,49 @@ +/* + * Format String Generator for IDL Compiler + * + * Copyright 2005-2006 Eric Kohl + * Copyright 2005 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 + */ + + +enum pass +{ + PASS_IN, + PASS_OUT, + PASS_RETURN +}; + +enum remoting_phase +{ + PHASE_BUFFERSIZE, + PHASE_MARSHAL, + PHASE_UNMARSHAL, + PHASE_FREE +}; + +void write_procformatstring(FILE *file, const ifref_t *ifaces); +void write_typeformatstring(FILE *file, const ifref_t *ifaces); +size_t get_type_memsize(const type_t *type); +unsigned int get_required_buffer_size(const var_t *var, unsigned int *alignment, enum pass pass); +void print_phase_basetype(FILE *file, int indent, enum remoting_phase phase, enum pass pass, const var_t *var, const char *varname); +void write_remoting_arguments(FILE *file, int indent, const func_t *func, unsigned int *type_offset, enum pass pass, enum remoting_phase phase); +size_t get_size_procformatstring_var(const var_t *var); +size_t get_size_typeformatstring_var(const var_t *var); +size_t get_size_procformatstring(const ifref_t *ifaces); +size_t get_size_typeformatstring(const ifref_t *ifaces); +int write_expr_eval_routines(FILE *file, const char *iface); +void write_expr_eval_routine_list(FILE *file, const char *iface); diff --git a/reactos/tools/widl_new/typelib.c b/reactos/tools/widl_new/typelib.c new file mode 100644 index 00000000000..5ff101beeb6 --- /dev/null +++ b/reactos/tools/widl_new/typelib.c @@ -0,0 +1,417 @@ +/* + * IDL Compiler + * + * Copyright 2004 Ove Kaaven + * Copyright 2006 Jacek Caban for CodeWeavers + * + * 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 "wine/wpp.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#define NONAMELESSUNION +#define NONAMELESSSTRUCT + +#include "windef.h" +#include "winbase.h" + +#include "widl.h" +#include "utils.h" +#include "parser.h" +#include "header.h" +#include "typelib.h" +#include "widltypes.h" +#include "typelib_struct.h" + +int in_typelib = 0; + +static typelib_t *typelib; + +/* List of oleauto types that should be recognized by name. + * (most of) these seem to be intrinsic types in mktyplib. */ + +static struct oatype { + const char *kw; + unsigned short vt; +} oatypes[] = { + {"BSTR", VT_BSTR}, + {"CURRENCY", VT_CY}, + {"DATE", VT_DATE}, + {"DECIMAL", VT_DECIMAL}, + {"HRESULT", VT_HRESULT}, + {"LPSTR", VT_LPSTR}, + {"LPWSTR", VT_LPWSTR}, + {"SCODE", VT_ERROR}, + {"VARIANT", VT_VARIANT}, + {"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) +{ + return strcmp(KWP(s1)->kw, KWP(s2)->kw); +} + +static unsigned short builtin_vt(const char *kw) +{ + struct oatype key, *kwp; + key.kw = kw; +#ifdef KW_BSEARCH + kwp = bsearch(&key, oatypes, NTYPES, sizeof(oatypes[0]), kw_cmp_func); +#else + { + unsigned int i; + for (kwp=NULL, i=0; i < NTYPES; i++) + if (!kw_cmp_func(&key, &oatypes[i])) { + kwp = &oatypes[i]; + break; + } + } +#endif + if (kwp) { + return kwp->vt; + } + return 0; +} + +static int match(const char*n, const char*m) +{ + if (!n) return 0; + return !strcmp(n, m); +} + +unsigned short get_type_vt(type_t *t) +{ + unsigned short vt; + + chat("get_type_vt: %p type->name %s\n", t, t->name); + if (t->name) { + vt = builtin_vt(t->name); + if (vt) return vt; + } + + switch (t->type) { + case RPC_FC_BYTE: + case RPC_FC_USMALL: + return VT_UI1; + case RPC_FC_CHAR: + case RPC_FC_SMALL: + return VT_I1; + case RPC_FC_WCHAR: + return VT_I2; /* mktyplib seems to parse wchar_t as short */ + case RPC_FC_SHORT: + return VT_I2; + case RPC_FC_USHORT: + return VT_UI2; + case RPC_FC_LONG: + if (t->ref && match(t->ref->name, "int")) return VT_INT; + return VT_I4; + case RPC_FC_ULONG: + if (t->ref && match(t->ref->name, "int")) return VT_UINT; + return VT_UI4; + case RPC_FC_HYPER: + if (t->sign < 0) return VT_UI8; + if (t->ref && match(t->ref->name, "MIDL_uhyper")) return VT_UI8; + return VT_I8; + case RPC_FC_FLOAT: + return VT_R4; + case RPC_FC_DOUBLE: + return VT_R8; + case RPC_FC_RP: + case RPC_FC_UP: + case RPC_FC_OP: + case RPC_FC_FP: + if(t->ref) + return VT_PTR; + + error("get_type_vt: unknown-deref-type: %d\n", t->ref->type); + break; + case RPC_FC_IP: + if(match(t->name, "IUnknown")) + return VT_UNKNOWN; + if(match(t->name, "IDispatch")) + return VT_DISPATCH; + return VT_USERDEFINED; + + case RPC_FC_ENUM16: + case RPC_FC_STRUCT: + case RPC_FC_PSTRUCT: + case RPC_FC_CSTRUCT: + case RPC_FC_CPSTRUCT: + case RPC_FC_CVSTRUCT: + case RPC_FC_BOGUS_STRUCT: + return VT_USERDEFINED; + case 0: + if(t->attrs) + return VT_USERDEFINED; + return 0; + default: + error("get_type_vt: unknown type: 0x%02x\n", t->type); + } + return 0; +} + +unsigned short get_var_vt(var_t *v) +{ + unsigned short vt; + + chat("get_var_vt: %p tname %s\n", v, v->tname); + if (v->tname) { + vt = builtin_vt(v->tname); + if (vt) return vt; + } + + return get_type_vt(v->type); +} + +void start_typelib(char *name, attr_t *attrs) +{ + in_typelib++; + if (!do_typelib) return; + + typelib = xmalloc(sizeof(*typelib)); + typelib->name = xstrdup(name); + typelib->filename = xstrdup(typelib_name); + typelib->attrs = attrs; +} + +void end_typelib(void) +{ + in_typelib--; + if (!typelib) return; + + create_msft_typelib(typelib); + return; +} + +void add_interface(type_t *iface) +{ + typelib_entry_t *entry; + if (!typelib) return; + + chat("add interface: %s\n", iface->name); + entry = xmalloc(sizeof(*entry)); + entry->kind = TKIND_INTERFACE; + entry->u.interface = iface; + LINK(entry, typelib->entry); + typelib->entry = entry; +} + +void add_coclass(type_t *cls) +{ + typelib_entry_t *entry; + + if (!typelib) return; + + chat("add coclass: %s\n", cls->name); + + entry = xmalloc(sizeof(*entry)); + entry->kind = TKIND_COCLASS; + entry->u.class = cls; + LINK(entry, typelib->entry); + typelib->entry = entry; +} + +void add_module(type_t *module) +{ + typelib_entry_t *entry; + if (!typelib) return; + + chat("add module: %s\n", module->name); + entry = xmalloc(sizeof(*entry)); + entry->kind = TKIND_MODULE; + entry->u.module = module; + LINK(entry, typelib->entry); + typelib->entry = entry; +} + +void add_struct(type_t *structure) +{ + typelib_entry_t *entry; + if (!typelib) return; + + chat("add struct: %s\n", structure->name); + entry = xmalloc(sizeof(*entry)); + entry->kind = TKIND_RECORD; + entry->u.structure = structure; + LINK(entry, typelib->entry); + typelib->entry = entry; +} + +void add_enum(type_t *enumeration) +{ + typelib_entry_t *entry; + if (!typelib) return; + + chat("add enum: %s\n", enumeration->name); + entry = xmalloc(sizeof(*entry)); + entry->kind = TKIND_ENUM; + entry->u.enumeration = enumeration; + LINK(entry, typelib->entry); + typelib->entry = entry; +} + +void add_typedef(type_t *tdef, var_t *name) +{ + typelib_entry_t *entry; + if (!typelib) return; + + chat("add typedef: %s\n", name->name); + entry = xmalloc(sizeof(*entry)); + entry->kind = TKIND_ALIAS; + entry->u.tdef = xmalloc(sizeof(*entry->u.tdef)); + memcpy(entry->u.tdef, name, sizeof(*name)); + entry->u.tdef->type = tdef; + entry->u.tdef->name = xstrdup(name->name); + LINK(entry, typelib->entry); + typelib->entry = entry; +} + +static void tlb_read(int fd, void *buf, size_t count) +{ + if(read(fd, buf, count) < count) + error("error while reading importlib.\n"); +} + +static void tlb_lseek(int fd, off_t offset) +{ + 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; + int *typeinfo_offs; + int i; + + importlib->allocated = 0; + + tlb_lseek(fd, 0); + tlb_read(fd, &header, sizeof(header)); + + importlib->version = header.version; + + 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->importinfos = xmalloc(importlib->ntypeinfos*sizeof(importinfo_t)); + + for(i=0; i < importlib->ntypeinfos; i++) { + MSFT_TypeInfoBase base; + 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].offset = -1; + importlib->importinfos[i].id = i; + + if(base.posguid != -1) { + importlib->importinfos[i].flags |= MSFT_IMPINFO_OFFSET_IS_GUID; + msft_read_guid(fd, &segdir, base.posguid, &importlib->importinfos[i].guid); + } + + tlb_lseek(fd, segdir.pNametab.offset + base.NameOffset); + tlb_read(fd, &nameintro, sizeof(nameintro)); + + len = nameintro.namelen & 0xff; + + importlib->importinfos[i].name = xmalloc(len+1); + tlb_read(fd, importlib->importinfos[i].name, len); + importlib->importinfos[i].name[len] = 0; + } + + free(typeinfo_offs); +} + +static void read_importlib(importlib_t *importlib) +{ + int fd; + INT magic; + char *file_name; + + file_name = wpp_find_include(importlib->name, NULL); + if(file_name) { + fd = open(file_name, O_RDONLY); + free(file_name); + }else { + fd = open(importlib->name, O_RDONLY); + } + + if(fd < 0) + error("Could not open importlib %s.\n", importlib->name); + + tlb_read(fd, &magic, sizeof(magic)); + + switch(magic) { + case MSFT_MAGIC: + read_msft_importlib(importlib, fd); + break; + default: + error("Wrong or unsupported typelib magic %x\n", magic); + }; + + close(fd); +} + +void add_importlib(const char *name) +{ + importlib_t *importlib; + + if(!typelib) return; + + for(importlib = typelib->importlibs; importlib; importlib = NEXT_LINK(importlib)) { + if(!strcmp(name, importlib->name)) + return; + } + + chat("add_importlib: %s\n", name); + + importlib = xmalloc(sizeof(*importlib)); + importlib->name = xstrdup(name); + + read_importlib(importlib); + + LINK(importlib, typelib->importlibs); + typelib->importlibs = importlib; +} diff --git a/reactos/tools/widl_new/typelib.h b/reactos/tools/widl_new/typelib.h new file mode 100644 index 00000000000..9fb5bdd9345 --- /dev/null +++ b/reactos/tools/widl_new/typelib.h @@ -0,0 +1,93 @@ +/* + * IDL Compiler + * + * Copyright 2004 Ove Kaaven + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __WIDL_TYPELIB_H +#define __WIDL_TYPELIB_H + +extern int in_typelib; +extern void start_typelib(char *name, attr_t *attrs); +extern void end_typelib(void); +extern void add_interface(type_t *iface); +extern void add_coclass(type_t *cls); +extern void add_module(type_t *module); +extern void add_struct(type_t *structure); +extern void add_enum(type_t *enumeration); +extern void add_typedef(type_t *tdef, var_t *name); +extern void add_importlib(const char *name); + +/* Copied from wtypes.h. Not included directly because that would create a + * circular dependency (after all, wtypes.h is generated by widl...) */ + +enum VARENUM { + VT_EMPTY = 0, + VT_NULL = 1, + VT_I2 = 2, + VT_I4 = 3, + VT_R4 = 4, + VT_R8 = 5, + VT_CY = 6, + VT_DATE = 7, + VT_BSTR = 8, + VT_DISPATCH = 9, + VT_ERROR = 10, + VT_BOOL = 11, + VT_VARIANT = 12, + VT_UNKNOWN = 13, + VT_DECIMAL = 14, + VT_I1 = 16, + VT_UI1 = 17, + VT_UI2 = 18, + VT_UI4 = 19, + VT_I8 = 20, + VT_UI8 = 21, + VT_INT = 22, + VT_UINT = 23, + VT_VOID = 24, + VT_HRESULT = 25, + VT_PTR = 26, + VT_SAFEARRAY = 27, + VT_CARRAY = 28, + VT_USERDEFINED = 29, + VT_LPSTR = 30, + VT_LPWSTR = 31, + VT_RECORD = 36, + VT_FILETIME = 64, + VT_BLOB = 65, + VT_STREAM = 66, + VT_STORAGE = 67, + VT_STREAMED_OBJECT = 68, + VT_STORED_OBJECT = 69, + VT_BLOB_OBJECT = 70, + VT_CF = 71, + VT_CLSID = 72, + VT_BSTR_BLOB = 0xfff, + VT_VECTOR = 0x1000, + VT_ARRAY = 0x2000, + VT_BYREF = 0x4000, + VT_RESERVED = 0x8000, + VT_ILLEGAL = 0xffff, + VT_ILLEGALMASKED = 0xfff, + VT_TYPEMASK = 0xfff +}; +extern unsigned short get_type_vt(type_t *t); +extern unsigned short get_var_vt(var_t *v); + +extern int create_msft_typelib(typelib_t *typelib); +#endif diff --git a/reactos/tools/widl_new/typelib_struct.h b/reactos/tools/widl_new/typelib_struct.h new file mode 100644 index 00000000000..d3b2ab5b2ba --- /dev/null +++ b/reactos/tools/widl_new/typelib_struct.h @@ -0,0 +1,605 @@ +/* + * typelib_struct.h internal wine data structures + * used to decode typelib's + * + * Copyright 1999 Rein KLazes + * + * 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 _WIDL_TYPELIB_STRUCT_H +#define _WIDL_TYPELIB_STRUCT_H + +#define HELPDLLFLAG (0x0100) +#define DO_NOT_SEEK (-1) + +#define MSFT_HREFTYPE_INTHISFILE(href) (!((href) & 3)) +#define MSFT_HREFTYPE_INDEX(href) ((href) /sizeof(MSFT_TypeInfoBase)) + +/*-------------------------FILE STRUCTURES-----------------------------------*/ + +/* There are two known file formats, those created with ICreateTypeLib + * have the signature "SLTG" as their first four bytes, while those created + * with ICreateTypeLib2 have "MSFT". + */ + +#define MSFT_MAGIC 0x5446534d + +/***************************************************** + * MSFT typelibs + * + * These are TypeLibs created with ICreateTypeLib2 + * + */ + +/* + * structure of the typelib type2 header + * it is at the beginning of a type lib file + * + */ +typedef struct tagMSFT_Header { +/*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 */ + /* the lower nibble is syskind */ + /* 0x40 always seems to be set */ + /* 0x10 set with a helpfile defined */ + /* 0x100 set with a helpstringdll defined - in this + 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 */ + /* 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 */ +} 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 */ + /* 0x03 in the typeinfo_data */ +} MSFT_pSeg; + +/* layout of the main segment directory */ +typedef struct tagMSFT_SegDir { +/*1*/MSFT_pSeg pTypeInfoTab; /* each type info get an entry of 0x64 bytes */ + /* (25 ints) */ +/*2*/MSFT_pSeg pImpInfo; /* table with info for imported types */ +/*3*/MSFT_pSeg pImpFiles; /* import libaries */ +/*4*/MSFT_pSeg pRefTab; /* References table */ +/*5*/MSFT_pSeg pLibtab; /* always exists, alway same size (0x80) */ + /* hash table w offsets to guid????? */ +/*6*/MSFT_pSeg pGuidTab; /* all guids are stored here together with */ + /* offset in some table???? */ +/*7*/MSFT_pSeg res07; /* always created, alway same size (0x200) */ + /* purpose largely unknown */ +/*8*/MSFT_pSeg pNametab; /* name tables */ +/*9*/MSFT_pSeg pStringtab; /* string table */ +/*A*/MSFT_pSeg pTypdescTab; /* table with type descriptors */ +/*B*/MSFT_pSeg pArrayDescriptions; +/*C*/MSFT_pSeg pCustData; /* data table, used for custom data and default */ + /* parameter values */ +/*D*/MSFT_pSeg pCDGuids; /* table with offsets for the guids and into */ + /* the customer data table */ +/*E*/MSFT_pSeg res0e; /* unknown */ +/*F*/MSFT_pSeg res0f; /* unknown */ +} MSFT_SegDir; + + +/* base type info data */ +typedef struct tagMSFT_TypeInfoBase { +/*000*/ INT typekind; /* it is the TKIND_xxx */ + /* some byte alignment stuf */ + INT memoffset; /* points past the file, if no elements */ + INT res2; /* zero if no element, N*0x40 */ + INT res3; /* -1 if no lement, (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 */ + /* FIXME: name of this field */ + INT datatype1; /* position in type description table */ + /* or in base intefaces */ + /* if coclass: offset in reftable */ + /* if interface: reference to inherited if */ + 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 */ +} MSFT_TypeInfoBase; + +/* layout of an entry with information on imported types */ +typedef struct tagMSFT_ImpInfo { + 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) */ +} MSFT_ImpInfo; + +#define MSFT_IMPINFO_OFFSET_IS_GUID 0x00010000 + +/* function description data */ +typedef struct { +/* INT recsize; record size including some xtra 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 */ + /* meaning (bit 0 is the lsb): */ + /* bits 0 - 2: FUNCKIND */ + /* bits 3 - 6: INVOKEKIND */ + /* bit 7: custom data present */ + /* bits 8 - 11: CALLCONV */ + /* bit 12: parameters have default values */ + /* 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 + /* optional attribute fields, the number of them is variable */ + 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; + // 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 // +*/ +} MSFT_FuncRecord; + +/* after this may follow an array with default value pointers if the + * appropriate bit in the FKCCIC field has been set: + * INT oDefautlValue[nrargs]; + */ + + /* Parameter info one per argument*/ +typedef struct { + INT DataType; + INT oName; + INT Flags; + } MSFT_ParameterInfo; + +/* Variable description data */ +typedef struct { +/* INT recsize; // record size including some xtra 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 */ + /* 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; + +} MSFT_VarRecord; + +/* Structure of the reference data */ +typedef struct { + 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 */ +} MSFT_RefRecord; + +/* this is how a guid is stored */ +typedef struct { + GUID 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 */ +} MSFT_GuidEntry; +/* some data preceding entries in the name table */ +typedef struct { + 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 */ + /* 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 */ + /* upper 16 bits are hash code */ +} MSFT_NameIntro; +/* the custom data table directory has enties like this */ +typedef struct { + INT GuidOffset; + INT DataOffset; + INT next; /* next offset in the table, -1 if it's the last */ +} MSFT_CDGuid; + + +/*********************************************************** + * + * SLTG typelibs. + * + * These are created with ICreateTypeLib + * + */ + +#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 */ +} 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; +} 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 */ + +/* 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" */ +} SLTG_Magic; + +#define SLTG_COMPOBJ_MAGIC "CompObj" +#define SLTG_DIR_MAGIC "dir" + +/* Next we have SLTG_Header.nrOfFileBlks - 2 of Index strings. These +are presumably unique to within the file and look something like +"AAAAAAAAAA" with the first character incremented from 'A' to ensure +uniqueness. I guess successive chars increment when we need to wrap +the first one. */ + +typedef struct { +/*00*/ CHAR string[11]; +} SLTG_Index; + + +/* This is followed by SLTG_pad9 */ +typedef struct { +/*00*/ CHAR pad[9]; /* 9 '\0's */ +} SLTG_Pad9; + + +/* Now we have the noOfFileBlks - 1 worth of blocks. The length of +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; + +/* 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; +} SLTG_LibBlk; + +#define SLTG_LIBBLK_MAGIC 0x51cc + +/* 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; +} SLTG_OtherTypeInfo; + +/* Next we get WORD 0x0003 followed by a DWORD which if we add to +0x216 gives the offset to the name table from the start of the LibBlk +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 */ +} 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; +} 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 */ +} 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 */ +} SLTG_EnumItem; + +#define SLTG_ENUMITEM_MAGIC 0x120a + +typedef struct { +/*00*/ WORD vt; /* vartype, 0xffff marks end. */ +/*02*/ WORD 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 + 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 */ +/* Param list starts, repeat next two as required */ +#if 0 + WORD name; /* offset to 2nd letter of name */ + WORD+ type; /* VT_ of param */ +#endif +} SLTG_Function; + +#define SLTG_FUNCTION_MAGIC 0x4c +#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 */ +/*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]; + /* 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 + * the xxxx (which maybe fewer than 4 digits) is the offset into the name + * table to a string "*\G{}#1.0#0#C:\WINNT\System32\stdole32.tlb#" + * The guid is the typelib guid; the ref again refers to the nth type of + * the imported typelib. + */ + +/*xx*/ BYTE 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 ?? */ +} 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, ? */ +} 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; /* ?? */ +} SLTG_RecordItem; + +#define SLTG_RECORD_MAGIC 0x0a + + +/* CARRAYs look like this +WORD type == VT_CARRAY +WORD offset from start of block to SAFEARRAY +WORD typeofarray +*/ + +#include "poppack.h" + +/*---------------------------END--------------------------------------------*/ +#endif diff --git a/reactos/tools/widl_new/utils.c b/reactos/tools/widl_new/utils.c new file mode 100644 index 00000000000..9f82184cd94 --- /dev/null +++ b/reactos/tools/widl_new/utils.c @@ -0,0 +1,197 @@ +/* + * Utility routines + * + * Copyright 1998 Bertho A. Stultiens + * Copyright 2002 Ove Kaaven + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "wine/port.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "widl.h" +#include "utils.h" +#include "parser.h" + +/* #define WANT_NEAR_INDICATION */ + +#ifdef WANT_NEAR_INDICATION +void make_print(char *str) +{ + while(*str) + { + if(!isprint(*str)) + *str = ' '; + str++; + } +} +#endif + +static void generic_msg(const char *s, const char *t, const char *n, va_list ap) +{ + fprintf(stderr, "%s:%d: %s: ", input_name ? input_name : "stdin", line_number, t); + vfprintf(stderr, s, ap); +#ifdef WANT_NEAR_INDICATION + { + char *cpy; + if(n) + { + cpy = xstrdup(n); + make_print(cpy); + fprintf(stderr, " near '%s'", cpy); + free(cpy); + } + } +#endif + fprintf(stderr, "\n"); +} + + +int yyerror(const char *s, ...) +{ + va_list ap; + va_start(ap, s); + generic_msg(s, "Error", yytext, ap); + va_end(ap); + exit(1); + return 1; +} + +int yywarning(const char *s, ...) +{ + va_list ap; + va_start(ap, s); + generic_msg(s, "Warning", yytext, ap); + va_end(ap); + return 0; +} + +void internal_error(const char *file, int line, const char *s, ...) +{ + va_list ap; + va_start(ap, s); + fprintf(stderr, "Internal error (please report) %s %d: ", file, line); + vfprintf(stderr, s, ap); + va_end(ap); + exit(3); +} + +void error(const char *s, ...) +{ + va_list ap; + va_start(ap, s); + fprintf(stderr, "error: "); + vfprintf(stderr, s, ap); + va_end(ap); + exit(2); +} + +void warning(const char *s, ...) +{ + va_list ap; + va_start(ap, s); + fprintf(stderr, "warning: "); + vfprintf(stderr, s, ap); + va_end(ap); +} + +void chat(const char *s, ...) +{ + if(debuglevel & DEBUGLEVEL_CHAT) + { + va_list ap; + va_start(ap, s); + fprintf(stderr, "chat: "); + vfprintf(stderr, s, ap); + va_end(ap); + } +} + +char *dup_basename(const char *name, const char *ext) +{ + int namelen; + int extlen = strlen(ext); + char *base; + char *slash; + + if(!name) + name = "widl.tab"; + + slash = strrchr(name, '/'); + if (slash) + name = slash + 1; + + namelen = strlen(name); + + /* +4 for later extension and +1 for '\0' */ + base = (char *)xmalloc(namelen +4 +1); + strcpy(base, name); + if(!strcasecmp(name + namelen-extlen, ext)) + { + base[namelen - extlen] = '\0'; + } + return base; +} + +void *xmalloc(size_t size) +{ + void *res; + + assert(size > 0); + res = malloc(size); + if(res == NULL) + { + error("Virtual memory exhausted.\n"); + } + /* + * We set it to 0. + * This is *paramount* because we depend on it + * just about everywhere in the rest of the code. + */ + memset(res, 0, size); + return res; +} + + +void *xrealloc(void *p, size_t size) +{ + void *res; + + assert(size > 0); + res = realloc(p, size); + if(res == NULL) + { + error("Virtual memory exhausted.\n"); + } + return res; +} + +char *xstrdup(const char *str) +{ + char *s; + + assert(str != NULL); + s = (char *)xmalloc(strlen(str)+1); + return strcpy(s, str); +} diff --git a/reactos/tools/widl_new/utils.h b/reactos/tools/widl_new/utils.h new file mode 100644 index 00000000000..089607dd538 --- /dev/null +++ b/reactos/tools/widl_new/utils.h @@ -0,0 +1,45 @@ +/* + * Utility routines' prototypes etc. + * + * Copyright 1998 Bertho A. Stultiens (BS) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __WIDL_UTILS_H +#define __WIDL_UTILS_H + +#include "widltypes.h" + +#include /* size_t */ + +void *xmalloc(size_t); +void *xrealloc(void *, size_t); +char *xstrdup(const char *str); + +#ifndef __GNUC__ +#define __attribute__(X) +#endif + +int yyerror(const char *s, ...) __attribute__((format (printf, 1, 2))); +int yywarning(const char *s, ...) __attribute__((format (printf, 1, 2))); +void internal_error(const char *file, int line, const char *s, ...) __attribute__((format (printf, 3, 4))); +void error(const char *s, ...) __attribute__((format (printf, 1, 2))); +void warning(const char *s, ...) __attribute__((format (printf, 1, 2))); +void chat(const char *s, ...) __attribute__((format (printf, 1, 2))); + +char *dup_basename(const char *name, const char *ext); + +#endif diff --git a/reactos/tools/widl_new/widl.c b/reactos/tools/widl_new/widl.c new file mode 100644 index 00000000000..c6c4a1cd84c --- /dev/null +++ b/reactos/tools/widl_new/widl.c @@ -0,0 +1,392 @@ +/* + * IDL Compiler + * + * Copyright 2002 Ove Kaaven + * based on WRC code by Bertho Stultiens + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "wine/port.h" + +#include +#include +#ifdef HAVE_UNISTD_H +# include +#endif +#include +#include +#include +#include +#ifdef HAVE_GETOPT_H +# include +#endif + +#include "widl.h" +#include "utils.h" +#include "parser.h" +#include "wine/wpp.h" +#include "header.h" + +/* future options to reserve characters for: */ +/* a = alignment of structures */ +/* A = ACF input filename */ +/* J = do not search standard include path */ +/* O = generate interpreted stubs */ +/* u = UUID file only? */ +/* U = UUID filename */ +/* w = select win16/win32 output (?) */ + +static char usage[] = +"Usage: widl [options...] infile.idl\n" +" -c Generate client stub\n" +" -C file Name of client stub file (default is infile_c.c)\n" +" -d n Set debug level to 'n'\n" +" -D id[=val] Define preprocessor identifier id=val\n" +" -E Preprocess only\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" +" -N Do not preprocess input\n" +" --oldnames Use old naming conventions\n" +" -p Generate proxy\n" +" -P file Name of proxy file (default is infile_p.c)\n" +" -s Generate server stub\n" +" -S file Name of server stub file (default is infile_s.c)\n" +" -t Generate typelib\n" +" -T file Name of typelib file (default is infile.tlb)\n" +" -V Print version and exit\n" +" -W Enable pedantic warnings\n" +"Debug level 'n' is a bitmask with following meaning:\n" +" * 0x01 Tell which resource is parsed (verbose mode)\n" +" * 0x02 Dump internal structures\n" +" * 0x04 Create a parser trace (yydebug=1)\n" +" * 0x08 Preprocessor messages\n" +" * 0x10 Preprocessor lex messages\n" +" * 0x20 Preprocessor yacc trace\n" +; + +static const char version_string[] = "Wine IDL Compiler version " PACKAGE_VERSION "\n" + "Copyright 2002 Ove Kaaven\n"; + +int win32 = 1; +int debuglevel = DEBUGLEVEL_NONE; +int yy_flex_debug; + +int pedantic = 0; +static int do_everything = 1; +int preprocess_only = 0; +int do_header = 0; +int do_typelib = 0; +int do_proxies = 0; +int do_client = 0; +int do_server = 0; +int no_preprocess = 0; +int old_names = 0; + +char *input_name; +char *header_name; +char *header_token; +char *typelib_name; +char *proxy_name; +char *proxy_token; +char *client_name; +char *client_token; +char *server_name; +char *server_token; +char *temp_name; + +int line_number = 1; + +FILE *header; +FILE *proxy; + +time_t now; + +static const char *short_options = + "cC:d:D:EhH:I:NpP:sS:tT:VW"; +static struct option long_options[] = { + { "oldnames", 0, 0, 1 }, + { 0, 0, 0, 0 } +}; + +static void rm_tempfile(void); +static void segvhandler(int sig); + +static char *make_token(const char *name) +{ + char *token; + char *slash; + int i; + + slash = strrchr(name, '/'); + if (slash) name = slash + 1; + + token = xstrdup(name); + for (i=0; token[i]; i++) { + if (!isalnum(token[i])) token[i] = '_'; + else token[i] = toupper(token[i]); + } + return token; +} + +/* 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 ); + /* map invalid characters to '_' */ + for (p = ret; *p; p++) if (!isalnum(*p)) *p = '_'; + return ret; +} + +/* clean things up when aborting on a signal */ +static void exit_on_signal( int sig ) +{ + exit(1); /* this will call the atexit functions */ +} + +int main(int argc,char *argv[]) +{ + extern char* optarg; + extern int optind; + int optc; + int ret = 0; + int opti = 0; + + signal(SIGSEGV, segvhandler); + 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(argc, argv, short_options, long_options, &opti)) != EOF) { + switch(optc) { + case 1: + old_names = 1; + break; + case 'c': + do_everything = 0; + do_client = 1; + break; + case 'C': + client_name = strdup(optarg); + break; + case 'd': + debuglevel = strtol(optarg, NULL, 0); + break; + case 'D': + wpp_add_cmdline_define(optarg); + break; + case 'E': + do_everything = 0; + preprocess_only = 1; + break; + case 'h': + do_everything = 0; + do_header = 1; + break; + case 'H': + header_name = strdup(optarg); + break; + case 'I': + wpp_add_include_path(optarg); + break; + case 'N': + no_preprocess = 1; + break; + case 'p': + do_everything = 0; + do_proxies = 1; + break; + case 'P': + proxy_name = strdup(optarg); + break; + case 's': + do_everything = 0; + do_server = 1; + break; + case 'S': + server_name = strdup(optarg); + break; + case 't': + do_everything = 0; + do_typelib = 1; + break; + case 'T': + typelib_name = strdup(optarg); + break; + case 'V': + printf(version_string); + return 0; + case 'W': + pedantic = 1; + break; + default: + fprintf(stderr, usage); + return 1; + } + } + + if(do_everything) { + do_header = do_typelib = do_proxies = do_client = do_server = 1; + } + if(optind < argc) { + input_name = xstrdup(argv[optind]); + } + else { + fprintf(stderr, usage); + return 1; + } + + if(debuglevel) + { + setbuf(stdout,0); + setbuf(stderr,0); + } + + yydebug = debuglevel & DEBUGLEVEL_TRACE ? 1 : 0; + yy_flex_debug = debuglevel & DEBUGLEVEL_TRACE ? 1 : 0; + + wpp_set_debug( (debuglevel & DEBUGLEVEL_PPLEX) != 0, + (debuglevel & DEBUGLEVEL_PPTRACE) != 0, + (debuglevel & DEBUGLEVEL_PPMSG) != 0 ); + + if (!header_name) { + header_name = dup_basename(input_name, ".idl"); + strcat(header_name, ".h"); + } + + if (!typelib_name && do_typelib) { + typelib_name = dup_basename(input_name, ".idl"); + strcat(typelib_name, ".tlb"); + } + + if (!proxy_name && do_proxies) { + proxy_name = dup_basename(input_name, ".idl"); + strcat(proxy_name, "_p.c"); + } + + if (!client_name && do_client) { + client_name = dup_basename(input_name, ".idl"); + strcat(client_name, "_c.c"); + } + + if (!server_name && do_server) { + server_name = dup_basename(input_name, ".idl"); + strcat(server_name, "_s.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"); + if (do_server) server_token = dup_basename_token(server_name,"_s.c"); + + wpp_add_cmdline_define("__WIDL__"); + + atexit(rm_tempfile); + if (!no_preprocess) + { + chat("Starting preprocess\n"); + + if (!preprocess_only) + { + ret = wpp_parse_temp( input_name, header_name, &temp_name ); + } + else + { + ret = wpp_parse( input_name, stdout ); + } + + if(ret) exit(1); + if(preprocess_only) exit(0); + if(!(yyin = fopen(temp_name, "r"))) { + fprintf(stderr, "Could not open %s for input\n", temp_name); + return 1; + } + } + else { + if(!(yyin = fopen(input_name, "r"))) { + fprintf(stderr, "Could not open %s for input\n", input_name); + return 1; + } + } + + if(do_header) { + header_token = make_token(header_name); + + if(!(header = fopen(header_name, "w"))) { + fprintf(stderr, "Could not open %s for output\n", header_name); + return 1; + } + fprintf(header, "/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n", PACKAGE_VERSION, input_name); + fprintf(header, "#include \n" ); + fprintf(header, "#include \n\n" ); + fprintf(header, "#ifndef __WIDL_%s\n", header_token); + fprintf(header, "#define __WIDL_%s\n", header_token); + fprintf(header, "#ifdef __cplusplus\n"); + fprintf(header, "extern \"C\" {\n"); + fprintf(header, "#endif\n"); + } + + ret = yyparse(); + + if(do_header) { + fprintf(header, "/* Begin additional prototypes for all interfaces */\n"); + fprintf(header, "\n"); + write_user_types(); + fprintf(header, "\n"); + fprintf(header, "/* End additional prototypes */\n"); + fprintf(header, "\n"); + fprintf(header, "#ifdef __cplusplus\n"); + fprintf(header, "}\n"); + fprintf(header, "#endif\n"); + fprintf(header, "#endif /* __WIDL_%s */\n", header_token); + fclose(header); + } + + fclose(yyin); + + if(ret) { + exit(1); + } + header_name = NULL; + client_name = NULL; + server_name = NULL; + return 0; +} + +static void rm_tempfile(void) +{ + abort_import(); + if(temp_name) + unlink(temp_name); + if (header_name) + unlink(header_name); + if (client_name) + unlink(client_name); + if (server_name) + unlink(server_name); +} + +static void segvhandler(int sig) +{ + fprintf(stderr, "\n%s:%d: Oops, segment violation\n", input_name, line_number); + fflush(stdout); + fflush(stderr); + abort(); +} diff --git a/reactos/tools/widl_new/widl.h b/reactos/tools/widl_new/widl.h new file mode 100644 index 00000000000..d41ca7074a4 --- /dev/null +++ b/reactos/tools/widl_new/widl.h @@ -0,0 +1,68 @@ +/* + * IDL Compiler + * + * Copyright 2002 Ove Kaaven + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __WIDL_WIDL_H +#define __WIDL_WIDL_H + +#include "widltypes.h" + +#include + +#define WIDL_FULLVERSION "0.1" + +extern int debuglevel; +#define DEBUGLEVEL_NONE 0x0000 +#define DEBUGLEVEL_CHAT 0x0001 +#define DEBUGLEVEL_DUMP 0x0002 +#define DEBUGLEVEL_TRACE 0x0004 +#define DEBUGLEVEL_PPMSG 0x0008 +#define DEBUGLEVEL_PPLEX 0x0010 +#define DEBUGLEVEL_PPTRACE 0x0020 + +extern int win32; +extern int pedantic; +extern int do_header; +extern int do_typelib; +extern int do_proxies; +extern int do_client; +extern int do_server; +extern int old_names; + +extern char *input_name; +extern char *header_name; +extern char *typelib_name; +extern char *proxy_name; +extern char *proxy_token; +extern char *client_name; +extern char *client_token; +extern char *server_name; +extern char *server_token; +extern time_t now; + +extern int line_number; +extern int char_number; + +extern FILE* header; + +extern void write_proxies(ifref_t *ifaces); +extern void write_client(ifref_t *ifaces); +extern void write_server(ifref_t *ifaces); + +#endif diff --git a/reactos/tools/widl_new/widl.mak b/reactos/tools/widl_new/widl.mak new file mode 100644 index 00000000000..84d35c1f85f --- /dev/null +++ b/reactos/tools/widl_new/widl.mak @@ -0,0 +1,131 @@ +WIDL_BASE = $(TOOLS_BASE)$(SEP)widl +WIDL_BASE_ = $(WIDL_BASE)$(SEP) +WIDL_INT = $(INTERMEDIATE_)$(WIDL_BASE) +WIDL_INT_ = $(WIDL_INT)$(SEP) +WIDL_OUT = $(OUTPUT_)$(WIDL_BASE) +WIDL_OUT_ = $(WIDL_OUT)$(SEP) + +$(WIDL_INT): | $(TOOLS_INT) + $(ECHO_MKDIR) + ${mkdir} $@ + +ifneq ($(INTERMEDIATE),$(OUTPUT)) +$(WIDL_OUT): | $(TOOLS_OUT) + $(ECHO_MKDIR) + ${mkdir} $@ +endif + +WIDL_PORT_BASE = $(WIDL_BASE)$(SEP)port +WIDL_PORT_BASE_ = $(WIDL_PORT_BASE)$(SEP) +WIDL_PORT_INT = $(INTERMEDIATE_)$(WIDL_PORT_BASE) +WIDL_PORT_INT_ = $(WIDL_PORT_INT)$(SEP) +WIDL_PORT_OUT = $(OUTPUT_)$(WIDL_PORT_BASE) +WIDL_PORT_OUT_ = $(WIDL_PORT_OUT)$(SEP) + +$(WIDL_PORT_INT): | $(WIDL_INT) + $(ECHO_MKDIR) + ${mkdir} $@ + +ifneq ($(INTERMEDIATE),$(OUTPUT)) +$(WIDL_PORT_OUT): | $(WIDL_OUT) + $(ECHO_MKDIR) + ${mkdir} $@ +endif + +WIDL_TARGET = \ + $(EXEPREFIX)$(WIDL_OUT_)widl$(EXEPOSTFIX) + +WIDL_DEPENDS = $(BUILDNO_H) + +WIDL_SOURCES = $(addprefix $(WIDL_BASE_), \ + client.c \ + hash.c \ + header.c \ + lex.yy.c \ + proxy.c \ + server.c \ + typegen.c \ + typelib.c \ + utils.c \ + widl.c \ + write_msft.c \ + parser.tab.c \ + port$(SEP)mkstemps.c \ + ) + +WIDL_OBJECTS = \ + $(addprefix $(INTERMEDIATE_), $(WIDL_SOURCES:.c=.o)) + +WIDL_HOST_CFLAGS = $(TOOLS_CFLAGS) \ + -DINT16=SHORT -D__USE_W32API -DYYDEBUG=1 -D__REACTOS__=1 \ + -I$(WIDL_BASE) -I$(WPP_BASE) \ + -Iinclude/reactos/wine -Iinclude/reactos -Iinclude -Iinclude/psdk \ + -I$(INTERMEDIATE_)include + +WIDL_HOST_LFLAGS = $(TOOLS_LFLAGS) + +WIDL_LIBS = $(WPP_TARGET) + +.PHONY: widl +widl: $(WIDL_TARGET) + +$(WIDL_TARGET): $(WIDL_OBJECTS) $(WIDL_LIBS) | $(WIDL_OUT) + $(ECHO_LD) + ${host_gcc} $(WIDL_OBJECTS) $(WIDL_LIBS) $(WIDL_HOST_LFLAGS) -o $@ + +$(WIDL_INT_)client.o: $(WIDL_BASE_)client.c $(WIDL_DEPENDS) | $(WIDL_INT) + $(ECHO_CC) + ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ + +$(WIDL_INT_)hash.o: $(WIDL_BASE_)hash.c $(WIDL_DEPENDS) | $(WIDL_INT) + $(ECHO_CC) + ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ + +$(WIDL_INT_)header.o: $(WIDL_BASE_)header.c $(WIDL_DEPENDS) | $(WIDL_INT) + $(ECHO_CC) + ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ + +$(WIDL_INT_)lex.yy.o: $(WIDL_BASE_)lex.yy.c $(WIDL_DEPENDS) | $(WIDL_INT) + $(ECHO_CC) + ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ + +$(WIDL_INT_)proxy.o: $(WIDL_BASE_)proxy.c $(WIDL_DEPENDS) | $(WIDL_INT) + $(ECHO_CC) + ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ + +$(WIDL_INT_)server.o: $(WIDL_BASE_)server.c $(WIDL_DEPENDS) | $(WIDL_INT) + $(ECHO_CC) + ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ + +$(WIDL_INT_)typegen.o: $(WIDL_BASE_)typegen.c $(WIDL_DEPENDS) | $(WIDL_INT) + $(ECHO_CC) + ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ + +$(WIDL_INT_)typelib.o: $(WIDL_BASE_)typelib.c $(WIDL_DEPENDS) | $(WIDL_INT) + $(ECHO_CC) + ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ + +$(WIDL_INT_)utils.o: $(WIDL_BASE_)utils.c $(WIDL_DEPENDS) | $(WIDL_INT) + $(ECHO_CC) + ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ + +$(WIDL_INT_)widl.o: $(WIDL_BASE_)widl.c $(WIDL_DEPENDS) | $(WIDL_INT) + $(ECHO_CC) + ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ + +$(WIDL_INT_)write_msft.o: $(WIDL_BASE_)write_msft.c $(WIDL_DEPENDS) | $(WIDL_INT) + $(ECHO_CC) + ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ + +$(WIDL_INT_)parser.tab.o: $(WIDL_BASE_)parser.tab.c $(WIDL_DEPENDS) | $(WIDL_INT) + $(ECHO_CC) + ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ + +$(WIDL_PORT_INT_)mkstemps.o: $(WIDL_PORT_BASE_)mkstemps.c $(WIDL_DEPENDS) | $(WIDL_PORT_INT) + $(ECHO_CC) + ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ + +.PHONY: widl_clean +widl_clean: + -@$(rm) $(WIDL_TARGET) $(WIDL_OBJECTS) 2>$(NUL) +clean: widl_clean diff --git a/reactos/tools/widl_new/widl.man.in b/reactos/tools/widl_new/widl.man.in new file mode 100644 index 00000000000..2d9ac8034e8 --- /dev/null +++ b/reactos/tools/widl_new/widl.man.in @@ -0,0 +1,88 @@ +.\" -*- nroff -*- +.TH WIDL 1 "October 2005" "@PACKAGE_STRING@" "Wine Developers Manual" +.SH NAME +widl \- Wine Interface Definition Language Compiler +.SH SYNOPSIS +.BR "widl "\fI[options]\fR " \fIinfile.idl\fR" +.SH DESCRIPTION +.B widl +is a Wine tool which purpose is to compile Interface Definition Language (IDL) files. +.PP +.SH OPTIONS +.B Help mode: +.nf +No options are used. +The program prints the help info and then exits. +.PP +.B General options: +.IP "\fB-V\fR" +Print version number and exits from the program. +.PP +.B Header options: +.IP "\fB-h\fR" +Generate header files. +.IP "\fB-H \fIfile\fR" +Name of header file to generate. The default header +filename is infile.h. +.IP "\fB--oldnames\fR" +Use old naming conventions. +.PP +.B Type library options: +.IP \fB-t\fR +Generate a type library. +.IP "\fB-T \fIfile\fR" +Define the name of the type library to be generated. +The default filename is infile.tlb. +.PP +.B Proxy/stub generation options: +.IP "\fB-c\fR" +Generate client stub. +.IP "\fB-C \fIfile\fR" +Name of client stub file (default is infile_c.c) +.IP "\fB-p\fR" +Generate proxy. +.IP "\fB-P \fIfile\fR" +Name of proxy file (default is infile_p.c) +.IP "\fB-s\fR" +Generate server stub. +.IP "\fB-S \fIfile\fR" +Name of server stub file (default is infile_s.c) +.PP +.B Preprocessor options: +.IP "\fB-I \fIpath\fR" +Add a header search dir to path. Multiple search +dirs are allowed. +.IP "\fB-D \fIid[=val]\fR" +Define preprocessor identifier id value. +.IP "\fB-E\fR" +Preprocess only. +.IP "\fB-N\fR" +Do not preprocess input. +.PP +.B Debug options: +.IP "\fB-W\fR" +Enable pedantic warnings. +.IP "\fB-d \fIn\fR" +.nf +Set debug level to n. +n may be '0x01', '0x02', '0x04', '0x08', '0x10' or '0x20'. +(See section \fBDebug\fR) +.PP +.SH Debug +Debug level 'n' is a bitmask with the following meaning: + * 0x01 Tell which resource is parsed (verbose mode) + * 0x02 Dump internal structures + * 0x04 Create a parser trace (yydebug=1) + * 0x08 Preprocessor messages + * 0x10 Preprocessor lex messages + * 0x20 Preprocessor yacc trace +.SH BUGS +Typelib generation doesn't work at the moment. It is still under development. +.SH AUTHORS +.B widl +was written by Ove Kaaven. This man page was written by Hannu +Valtonen. +.SH "SEE ALSO" +The Winelib User Guide +.nf +The Wine Developers Guide diff --git a/reactos/tools/widl_new/widltypes.h b/reactos/tools/widl_new/widltypes.h new file mode 100644 index 00000000000..7bf22291994 --- /dev/null +++ b/reactos/tools/widl_new/widltypes.h @@ -0,0 +1,300 @@ +/* + * IDL Compiler + * + * Copyright 2002 Ove Kaaven + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __WIDL_WIDLTYPES_H +#define __WIDL_WIDLTYPES_H + +#include +#include "guiddef.h" +#include "wine/rpcfc.h" + +#ifndef UUID_DEFINED +#define UUID_DEFINED +typedef GUID UUID; +#endif + +#define TRUE 1 +#define FALSE 0 + +typedef struct _attr_t attr_t; +typedef struct _expr_t expr_t; +typedef struct _type_t type_t; +typedef struct _typeref_t typeref_t; +typedef struct _var_t var_t; +typedef struct _func_t func_t; +typedef struct _ifref_t ifref_t; +typedef struct _typelib_entry_t typelib_entry_t; +typedef struct _importlib_t importlib_t; +typedef struct _importinfo_t importinfo_t; +typedef struct _typelib_t typelib_t; + +#define DECL_LINK(type) \ + type *l_next; \ + type *l_prev + +#define LINK(x,y) do { x->l_next = y; if (y) y->l_prev = x; } while (0) + +#define INIT_LINK(x) do { x->l_next = NULL; x->l_prev = NULL; } while (0) +#define NEXT_LINK(x) ((x)->l_next) +#define PREV_LINK(x) ((x)->l_prev) + +#define END_OF_LIST(list) \ + do { \ + if (list) { \ + while (NEXT_LINK(list)) \ + list = NEXT_LINK(list); \ + } \ + } while(0) + +enum attr_type +{ + ATTR_AGGREGATABLE, + ATTR_APPOBJECT, + ATTR_ASYNC, + ATTR_AUTO_HANDLE, + ATTR_BINDABLE, + ATTR_CALLAS, + ATTR_CASE, + ATTR_CONTEXTHANDLE, + ATTR_CONTROL, + ATTR_DEFAULT, + ATTR_DEFAULTCOLLELEM, + ATTR_DEFAULTVALUE_EXPR, + ATTR_DEFAULTVALUE_STRING, + ATTR_DEFAULTVTABLE, + ATTR_DISPINTERFACE, + ATTR_DISPLAYBIND, + ATTR_DLLNAME, + ATTR_DUAL, + ATTR_ENDPOINT, + ATTR_ENTRY_ORDINAL, + ATTR_ENTRY_STRING, + ATTR_EXPLICIT_HANDLE, + ATTR_HANDLE, + ATTR_HELPCONTEXT, + ATTR_HELPFILE, + ATTR_HELPSTRING, + ATTR_HELPSTRINGCONTEXT, + ATTR_HELPSTRINGDLL, + ATTR_HIDDEN, + ATTR_ID, + ATTR_IDEMPOTENT, + ATTR_IIDIS, + ATTR_IMMEDIATEBIND, + ATTR_IMPLICIT_HANDLE, + ATTR_IN, + ATTR_INPUTSYNC, + ATTR_LENGTHIS, + ATTR_LOCAL, + ATTR_NONBROWSABLE, + ATTR_NONCREATABLE, + ATTR_NONEXTENSIBLE, + ATTR_OBJECT, + ATTR_ODL, + ATTR_OLEAUTOMATION, + ATTR_OPTIONAL, + ATTR_OUT, + ATTR_POINTERDEFAULT, + ATTR_POINTERTYPE, + ATTR_PROPGET, + ATTR_PROPPUT, + ATTR_PROPPUTREF, + ATTR_PUBLIC, + ATTR_RANGE, + ATTR_READONLY, + ATTR_REQUESTEDIT, + ATTR_RESTRICTED, + ATTR_RETVAL, + ATTR_SIZEIS, + ATTR_SOURCE, + ATTR_STRING, + ATTR_SWITCHIS, + ATTR_SWITCHTYPE, + ATTR_TRANSMITAS, + ATTR_UUID, + ATTR_V1ENUM, + ATTR_VARARG, + ATTR_VERSION, + ATTR_WIREMARSHAL +}; + +enum expr_type +{ + EXPR_VOID, + EXPR_NUM, + EXPR_HEXNUM, + EXPR_IDENTIFIER, + EXPR_NEG, + EXPR_NOT, + EXPR_PPTR, + EXPR_CAST, + EXPR_SIZEOF, + EXPR_SHL, + EXPR_SHR, + EXPR_MUL, + EXPR_DIV, + EXPR_ADD, + EXPR_SUB, + EXPR_AND, + EXPR_OR, + EXPR_COND, + EXPR_TRUEFALSE, +}; + +enum type_kind +{ + TKIND_PRIMITIVE = -1, + TKIND_ENUM, + TKIND_RECORD, + TKIND_MODULE, + TKIND_INTERFACE, + TKIND_DISPATCH, + TKIND_COCLASS, + TKIND_ALIAS, + TKIND_UNION, + TKIND_MAX +}; + +struct _attr_t { + enum attr_type type; + union { + unsigned long ival; + void *pval; + } u; + /* parser-internal */ + DECL_LINK(attr_t); +}; + +struct _expr_t { + enum expr_type type; + const expr_t *ref; + union { + long lval; + const char *sval; + const expr_t *ext; + const typeref_t *tref; + } u; + const expr_t *ext2; + int is_const; + long cval; + /* parser-internal */ + DECL_LINK(expr_t); +}; + +struct _type_t { + const char *name; + enum type_kind kind; + unsigned char type; + struct _type_t *ref; + const attr_t *attrs; + func_t *funcs; /* interfaces and modules */ + var_t *fields; /* interfaces, structures and enumerations */ + ifref_t *ifaces; /* coclasses */ + int ignore, is_const, sign; + int defined, written, user_types_registered; + int typelib_idx; + /* parser-internal */ + DECL_LINK(type_t); +}; + +struct _typeref_t { + char *name; + type_t *ref; + int uniq; +}; + +struct _var_t { + char *name; + int ptr_level; + expr_t *array; + type_t *type; + var_t *args; /* for function pointers */ + const char *tname; + attr_t *attrs; + expr_t *eval; + + /* parser-internal */ + DECL_LINK(var_t); +}; + +struct _func_t { + var_t *def; + var_t *args; + int ignore, idx; + + /* parser-internal */ + DECL_LINK(func_t); +}; + +struct _ifref_t { + type_t *iface; + attr_t *attrs; + + /* parser-internal */ + DECL_LINK(ifref_t); +}; + +struct _typelib_entry_t { + enum type_kind kind; + union { + type_t *class; + type_t *interface; + type_t *module; + type_t *structure; + type_t *enumeration; + var_t *tdef; + } u; + DECL_LINK(typelib_entry_t); +}; + +struct _importinfo_t { + int offset; + GUID guid; + int flags; + int id; + + char *name; + + importlib_t *importlib; +}; + +struct _importlib_t { + char *name; + + int version; + GUID guid; + + importinfo_t *importinfos; + int ntypeinfos; + + int allocated; + + DECL_LINK(importlib_t); +}; + +struct _typelib_t { + char *name; + char *filename; + attr_t *attrs; + typelib_entry_t *entry; + importlib_t *importlibs; +}; + +#endif diff --git a/reactos/tools/widl_new/write_msft.c b/reactos/tools/widl_new/write_msft.c new file mode 100644 index 00000000000..8148a93dd70 --- /dev/null +++ b/reactos/tools/widl_new/write_msft.c @@ -0,0 +1,2580 @@ +/* + * Typelib v2 (MSFT) generation + * + * Copyright 2004 Alastair Bridgewater + * 2004, 2005 Huw Davies + * + * 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 + * + * -------------------------------------------------------------------------------------- + * Known problems: + * + * Badly incomplete. + * + * Only works on little-endian systems. + * + */ + +#include "config.h" +#include "wine/port.h" + +#include +#include +#include +#include +#include +#include + +#define NONAMELESSUNION +#define NONAMELESSSTRUCT + +#include "winerror.h" +#include "windef.h" +#include "winbase.h" +#include "winnls.h" + +#include "widltypes.h" +#include "typelib.h" +#include "typelib_struct.h" +#include "utils.h" +#include "hash.h" + +enum MSFT_segment_index { + MSFT_SEG_TYPEINFO = 0, /* type information */ + MSFT_SEG_IMPORTINFO, /* import information */ + MSFT_SEG_IMPORTFILES, /* import filenames */ + MSFT_SEG_REFERENCES, /* references (?) */ + MSFT_SEG_GUIDHASH, /* hash table for guids? */ + MSFT_SEG_GUID, /* guid storage */ + MSFT_SEG_NAMEHASH, /* hash table for names */ + MSFT_SEG_NAME, /* name storage */ + MSFT_SEG_STRING, /* string storage */ + MSFT_SEG_TYPEDESC, /* type descriptions */ + MSFT_SEG_ARRAYDESC, /* array descriptions */ + MSFT_SEG_CUSTDATA, /* custom data */ + MSFT_SEG_CUSTDATAGUID, /* custom data guids */ + MSFT_SEG_UNKNOWN, /* ??? */ + MSFT_SEG_UNKNOWN2, /* ??? */ + MSFT_SEG_MAX /* total number of segments */ +}; + +typedef struct tagMSFT_ImpFile { + int guid; + LCID lcid; + int version; + char filename[0]; /* preceded by two bytes of encoded (length << 2) + flags in the low two bits. */ +} MSFT_ImpFile; + +typedef struct _msft_typelib_t +{ + typelib_t *typelib; + MSFT_Header typelib_header; + MSFT_pSeg typelib_segdir[MSFT_SEG_MAX]; + char *typelib_segment_data[MSFT_SEG_MAX]; + int typelib_segment_block_length[MSFT_SEG_MAX]; + + INT typelib_typeinfo_offsets[0x200]; /* Hope that's enough. */ + + INT *typelib_namehash_segment; + INT *typelib_guidhash_segment; + + INT help_string_dll_offset; + + struct _msft_typeinfo_t *typeinfos; + struct _msft_typeinfo_t *last_typeinfo; +} msft_typelib_t; + +typedef struct _msft_typeinfo_t +{ + msft_typelib_t *typelib; + MSFT_TypeInfoBase *typeinfo; + + int typekind; + + unsigned int var_data_allocated; + int *var_data; + + unsigned int func_data_allocated; + int *func_data; + + int vars_allocated; + int *var_indices; + int *var_names; + int *var_offsets; + + int funcs_allocated; + int *func_indices; + int *func_names; + int *func_offsets; + + int datawidth; + + struct _msft_typeinfo_t *next_typeinfo; +} msft_typeinfo_t; + + + +/*================== Internal functions ===================================*/ + +/**************************************************************************** + * ctl2_init_header + * + * Initializes the type library header of a new typelib. + */ +static void ctl2_init_header( + msft_typelib_t *typelib) /* [I] The typelib to initialize. */ +{ + typelib->typelib_header.magic1 = 0x5446534d; + typelib->typelib_header.magic2 = 0x00010002; + typelib->typelib_header.posguid = -1; + typelib->typelib_header.lcid = 0x0409; /* or do we use the current one? */ + typelib->typelib_header.lcid2 = 0x0; + typelib->typelib_header.varflags = 0x40; + typelib->typelib_header.version = 0; + typelib->typelib_header.flags = 0; + typelib->typelib_header.nrtypeinfos = 0; + typelib->typelib_header.helpstring = -1; + typelib->typelib_header.helpstringcontext = 0; + typelib->typelib_header.helpcontext = 0; + typelib->typelib_header.nametablecount = 0; + typelib->typelib_header.nametablechars = 0; + typelib->typelib_header.NameOffset = -1; + typelib->typelib_header.helpfile = -1; + typelib->typelib_header.CustomDataOffset = -1; + typelib->typelib_header.res44 = 0x20; + typelib->typelib_header.res48 = 0x80; + typelib->typelib_header.dispatchpos = -1; + typelib->typelib_header.nimpinfos = 0; +} + +/**************************************************************************** + * ctl2_init_segdir + * + * Initializes the segment directory of a new typelib. + */ +static void ctl2_init_segdir( + msft_typelib_t *typelib) /* [I] The typelib to initialize. */ +{ + int i; + MSFT_pSeg *segdir; + + segdir = &typelib->typelib_segdir[MSFT_SEG_TYPEINFO]; + + for (i = 0; i < 15; i++) { + segdir[i].offset = -1; + segdir[i].length = 0; + segdir[i].res08 = -1; + segdir[i].res0c = 0x0f; + } +} + +/**************************************************************************** + * ctl2_hash_guid + * + * Generates a hash key from a GUID. + * + * RETURNS + * + * The hash key for the GUID. + */ +static int ctl2_hash_guid( + REFGUID guid) /* [I] The guid to hash. */ +{ + int hash; + int i; + + hash = 0; + for (i = 0; i < 8; i ++) { + hash ^= ((const short *)guid)[i]; + } + + return hash & 0x1f; +} + +/**************************************************************************** + * ctl2_find_guid + * + * Locates a guid in a type library. + * + * RETURNS + * + * The offset into the GUID segment of the guid, or -1 if not found. + */ +static int ctl2_find_guid( + msft_typelib_t *typelib, /* [I] The typelib to operate against. */ + int hash_key, /* [I] The hash key for the guid. */ + REFGUID guid) /* [I] The guid to find. */ +{ + int offset; + MSFT_GuidEntry *guidentry; + + offset = typelib->typelib_guidhash_segment[hash_key]; + while (offset != -1) { + guidentry = (MSFT_GuidEntry *)&typelib->typelib_segment_data[MSFT_SEG_GUID][offset]; + + if (!memcmp(guidentry, guid, sizeof(GUID))) return offset; + + offset = guidentry->next_hash; + } + + return offset; +} + +/**************************************************************************** + * ctl2_find_name + * + * Locates a name in a type library. + * + * RETURNS + * + * The offset into the NAME segment of the name, or -1 if not found. + * + * NOTES + * + * The name must be encoded as with ctl2_encode_name(). + */ +static int ctl2_find_name( + msft_typelib_t *typelib, /* [I] The typelib to operate against. */ + char *name) /* [I] The encoded name to find. */ +{ + int offset; + int *namestruct; + + offset = typelib->typelib_namehash_segment[name[2] & 0x7f]; + while (offset != -1) { + namestruct = (int *)&typelib->typelib_segment_data[MSFT_SEG_NAME][offset]; + + if (!((namestruct[2] ^ *((int *)name)) & 0xffff00ff)) { + /* hash codes and lengths match, final test */ + if (!strncasecmp(name+4, (void *)(namestruct+3), name[0])) break; + } + + /* move to next item in hash bucket */ + offset = namestruct[1]; + } + + return offset; +} + +/**************************************************************************** + * ctl2_encode_name + * + * Encodes a name string to a form suitable for storing into a type library + * or comparing to a name stored in a type library. + * + * RETURNS + * + * The length of the encoded name, including padding and length+hash fields. + * + * NOTES + * + * Will throw an exception if name or result are NULL. Is not multithread + * safe in the slightest. + */ +static int ctl2_encode_name( + msft_typelib_t *typelib, /* [I] The typelib to operate against (used for LCID only). */ + const char *name, /* [I] The name string to encode. */ + char **result) /* [O] A pointer to a pointer to receive the encoded name. */ +{ + int length; + static char converted_name[0x104]; + int offset; + int value; + + length = strlen(name); + memcpy(converted_name + 4, name, length); + converted_name[0] = length & 0xff; + + converted_name[length + 4] = 0; + + converted_name[1] = 0x00; + + value = lhash_val_of_name_sys(typelib->typelib_header.varflags & 0x0f, typelib->typelib_header.lcid, converted_name + 4); + + converted_name[2] = value; + converted_name[3] = value >> 8; + + for (offset = (4 - length) & 3; offset; offset--) converted_name[length + offset + 3] = 0x57; + + *result = converted_name; + + return (length + 7) & ~3; +} + +/**************************************************************************** + * ctl2_encode_string + * + * Encodes a string to a form suitable for storing into a type library or + * comparing to a string stored in a type library. + * + * RETURNS + * + * The length of the encoded string, including padding and length fields. + * + * NOTES + * + * Will throw an exception if string or result are NULL. Is not multithread + * safe in the slightest. + */ +static int ctl2_encode_string( + msft_typelib_t *typelib, /* [I] The typelib to operate against (not used?). */ + const char *string, /* [I] The string to encode. */ + char **result) /* [O] A pointer to a pointer to receive the encoded string. */ +{ + int length; + static char converted_string[0x104]; + int offset; + + length = strlen(string); + memcpy(converted_string + 2, string, length); + converted_string[0] = length & 0xff; + converted_string[1] = (length >> 8) & 0xff; + + if(length < 3) { /* strings of this length are padded with up to 8 bytes incl the 2 byte length */ + for(offset = 0; offset < 4; offset++) + converted_string[length + offset + 2] = 0x57; + length += 4; + } + for (offset = (4 - (length + 2)) & 3; offset; offset--) converted_string[length + offset + 1] = 0x57; + + *result = converted_string; + + return (length + 5) & ~3; +} + +/**************************************************************************** + * ctl2_alloc_segment + * + * Allocates memory from a segment in a type library. + * + * RETURNS + * + * Success: The offset within the segment of the new data area. + * Failure: -1 (this is invariably an out of memory condition). + * + * BUGS + * + * Does not (yet) handle the case where the allocated segment memory needs to grow. + */ +static int ctl2_alloc_segment( + msft_typelib_t *typelib, /* [I] The type library in which to allocate. */ + enum MSFT_segment_index segment, /* [I] The segment in which to allocate. */ + int size, /* [I] The amount to allocate. */ + int block_size) /* [I] Initial allocation block size, or 0 for default. */ +{ + int offset; + + if(!typelib->typelib_segment_data[segment]) { + if (!block_size) block_size = 0x2000; + + typelib->typelib_segment_block_length[segment] = block_size; + typelib->typelib_segment_data[segment] = xmalloc(block_size); + if (!typelib->typelib_segment_data[segment]) return -1; + memset(typelib->typelib_segment_data[segment], 0x57, block_size); + } + + while ((typelib->typelib_segdir[segment].length + size) > typelib->typelib_segment_block_length[segment]) { + char *block; + + block_size = typelib->typelib_segment_block_length[segment]; + block = realloc(typelib->typelib_segment_data[segment], block_size << 1); + if (!block) return -1; + + if (segment == MSFT_SEG_TYPEINFO) { + /* TypeInfos have a direct pointer to their memory space, so we have to fix them up. */ + msft_typeinfo_t *typeinfo; + + for (typeinfo = typelib->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) { + typeinfo->typeinfo = (void *)&block[((char *)typeinfo->typeinfo) - typelib->typelib_segment_data[segment]]; + } + } + + memset(block + block_size, 0x57, block_size); + typelib->typelib_segment_block_length[segment] = block_size << 1; + typelib->typelib_segment_data[segment] = block; + } + + offset = typelib->typelib_segdir[segment].length; + typelib->typelib_segdir[segment].length += size; + + return offset; +} + +/**************************************************************************** + * ctl2_alloc_typeinfo + * + * Allocates and initializes a typeinfo structure in a type library. + * + * RETURNS + * + * Success: The offset of the new typeinfo. + * Failure: -1 (this is invariably an out of memory condition). + */ +static int ctl2_alloc_typeinfo( + msft_typelib_t *typelib, /* [I] The type library to allocate in. */ + int nameoffset) /* [I] The offset of the name for this typeinfo. */ +{ + int offset; + MSFT_TypeInfoBase *typeinfo; + + offset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEINFO, sizeof(MSFT_TypeInfoBase), 0); + if (offset == -1) return -1; + + typelib->typelib_typeinfo_offsets[typelib->typelib_header.nrtypeinfos++] = offset; + + typeinfo = (void *)(typelib->typelib_segment_data[MSFT_SEG_TYPEINFO] + offset); + + typeinfo->typekind = (typelib->typelib_header.nrtypeinfos - 1) << 16; + typeinfo->memoffset = -1; /* should be EOF if no elements */ + typeinfo->res2 = 0; + typeinfo->res3 = -1; + typeinfo->res4 = 3; + typeinfo->res5 = 0; + typeinfo->cElement = 0; + typeinfo->res7 = 0; + typeinfo->res8 = 0; + typeinfo->res9 = 0; + typeinfo->resA = 0; + typeinfo->posguid = -1; + typeinfo->flags = 0; + typeinfo->NameOffset = nameoffset; + typeinfo->version = 0; + typeinfo->docstringoffs = -1; + typeinfo->helpstringcontext = 0; + typeinfo->helpcontext = 0; + typeinfo->oCustData = -1; + typeinfo->cbSizeVft = 0; + typeinfo->cImplTypes = 0; + typeinfo->size = 0; + typeinfo->datatype1 = -1; + typeinfo->datatype2 = 0; + typeinfo->res18 = 0; + typeinfo->res19 = -1; + + return offset; +} + +/**************************************************************************** + * ctl2_alloc_guid + * + * Allocates and initializes a GUID structure in a type library. Also updates + * the GUID hash table as needed. + * + * RETURNS + * + * Success: The offset of the new GUID. + * Failure: -1 (this is invariably an out of memory condition). + */ +static int ctl2_alloc_guid( + msft_typelib_t *typelib, /* [I] The type library to allocate in. */ + MSFT_GuidEntry *guid) /* [I] The GUID to store. */ +{ + int offset; + MSFT_GuidEntry *guid_space; + int hash_key; + + hash_key = ctl2_hash_guid(&guid->guid); + + offset = ctl2_find_guid(typelib, hash_key, &guid->guid); + if (offset != -1) return offset; + + offset = ctl2_alloc_segment(typelib, MSFT_SEG_GUID, sizeof(MSFT_GuidEntry), 0); + if (offset == -1) return -1; + + guid_space = (void *)(typelib->typelib_segment_data[MSFT_SEG_GUID] + offset); + *guid_space = *guid; + + guid_space->next_hash = typelib->typelib_guidhash_segment[hash_key]; + typelib->typelib_guidhash_segment[hash_key] = offset; + + return offset; +} + +/**************************************************************************** + * ctl2_alloc_name + * + * Allocates and initializes a name within a type library. Also updates the + * name hash table as needed. + * + * RETURNS + * + * Success: The offset within the segment of the new name. + * Failure: -1 (this is invariably an out of memory condition). + */ +static int ctl2_alloc_name( + msft_typelib_t *typelib, /* [I] The type library to allocate in. */ + const char *name) /* [I] The name to store. */ +{ + int length; + int offset; + MSFT_NameIntro *name_space; + char *encoded_name; + + length = ctl2_encode_name(typelib, name, &encoded_name); + + offset = ctl2_find_name(typelib, encoded_name); + if (offset != -1) return offset; + + offset = ctl2_alloc_segment(typelib, MSFT_SEG_NAME, length + 8, 0); + if (offset == -1) return -1; + + name_space = (void *)(typelib->typelib_segment_data[MSFT_SEG_NAME] + offset); + name_space->hreftype = -1; + name_space->next_hash = -1; + memcpy(&name_space->namelen, encoded_name, length); + + if (typelib->typelib_namehash_segment[encoded_name[2] & 0x7f] != -1) + name_space->next_hash = typelib->typelib_namehash_segment[encoded_name[2] & 0x7f]; + + typelib->typelib_namehash_segment[encoded_name[2] & 0x7f] = offset; + + typelib->typelib_header.nametablecount += 1; + typelib->typelib_header.nametablechars += *encoded_name; + + return offset; +} + +/**************************************************************************** + * ctl2_alloc_string + * + * Allocates and initializes a string in a type library. + * + * RETURNS + * + * Success: The offset within the segment of the new string. + * Failure: -1 (this is invariably an out of memory condition). + */ +static int ctl2_alloc_string( + msft_typelib_t *typelib, /* [I] The type library to allocate in. */ + const char *string) /* [I] The string to store. */ +{ + int length; + int offset; + char *string_space; + char *encoded_string; + + length = ctl2_encode_string(typelib, string, &encoded_string); + + for (offset = 0; offset < typelib->typelib_segdir[MSFT_SEG_STRING].length; + offset += ((((typelib->typelib_segment_data[MSFT_SEG_STRING][offset + 1] << 8) & 0xff) + | (typelib->typelib_segment_data[MSFT_SEG_STRING][offset + 0] & 0xff)) + 5) & ~3) { + if (!memcmp(encoded_string, typelib->typelib_segment_data[MSFT_SEG_STRING] + offset, length)) return offset; + } + + offset = ctl2_alloc_segment(typelib, MSFT_SEG_STRING, length, 0); + if (offset == -1) return -1; + + string_space = typelib->typelib_segment_data[MSFT_SEG_STRING] + offset; + memcpy(string_space, encoded_string, length); + + return offset; +} + +/**************************************************************************** + * alloc_msft_importinfo + * + * Allocates and initializes an import information structure in a type library. + * + * RETURNS + * + * Success: The offset of the new importinfo. + * Failure: -1 (this is invariably an out of memory condition). + */ +static int alloc_msft_importinfo( + msft_typelib_t *typelib, /* [I] The type library to allocate in. */ + MSFT_ImpInfo *impinfo) /* [I] The import information to store. */ +{ + int offset; + MSFT_ImpInfo *impinfo_space; + + for (offset = 0; + offset < typelib->typelib_segdir[MSFT_SEG_IMPORTINFO].length; + offset += sizeof(MSFT_ImpInfo)) { + if (!memcmp(&(typelib->typelib_segment_data[MSFT_SEG_IMPORTINFO][offset]), + impinfo, sizeof(MSFT_ImpInfo))) { + return offset; + } + } + + impinfo->flags |= typelib->typelib_header.nimpinfos++; + + offset = ctl2_alloc_segment(typelib, MSFT_SEG_IMPORTINFO, sizeof(MSFT_ImpInfo), 0); + if (offset == -1) return -1; + + impinfo_space = (void *)(typelib->typelib_segment_data[MSFT_SEG_IMPORTINFO] + offset); + *impinfo_space = *impinfo; + + return offset; +} + +/**************************************************************************** + * alloc_importfile + * + * Allocates and initializes an import file definition in a type library. + * + * RETURNS + * + * Success: The offset of the new importinfo. + * Failure: -1 (this is invariably an out of memory condition). + */ +static int alloc_importfile( + msft_typelib_t *typelib, /* [I] The type library to allocate in. */ + int guidoffset, /* [I] The offset to the GUID for the imported library. */ + int major_version, /* [I] The major version number of the imported library. */ + int minor_version, /* [I] The minor version number of the imported library. */ + const char *filename) /* [I] The filename of the imported library. */ +{ + int length; + int offset; + MSFT_ImpFile *importfile; + char *encoded_string; + + length = ctl2_encode_string(typelib, filename, &encoded_string); + + encoded_string[0] <<= 2; + encoded_string[0] |= 1; + + for (offset = 0; offset < typelib->typelib_segdir[MSFT_SEG_IMPORTFILES].length; + offset += ((((typelib->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset + 0xd] << 8) & 0xff) + | (typelib->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset + 0xc] & 0xff)) >> 2) + 0xc) { + if (!memcmp(encoded_string, typelib->typelib_segment_data[MSFT_SEG_IMPORTFILES] + offset + 0xc, length)) return offset; + } + + offset = ctl2_alloc_segment(typelib, MSFT_SEG_IMPORTFILES, length + 0xc, 0); + if (offset == -1) return -1; + + importfile = (MSFT_ImpFile *)&typelib->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset]; + importfile->guid = guidoffset; + importfile->lcid = typelib->typelib_header.lcid2; + importfile->version = major_version | (minor_version << 16); + memcpy(&importfile->filename, encoded_string, length); + + return offset; +} + +static void alloc_importinfo(msft_typelib_t *typelib, importinfo_t *importinfo) +{ + importlib_t *importlib = importinfo->importlib; + + chat("alloc_importinfo: %s\n", importinfo->name); + + if(!importlib->allocated) { + MSFT_GuidEntry guid; + int guid_idx; + + chat("allocating importlib %s\n", importlib->name); + + importlib->allocated = -1; + + memcpy(&guid.guid, &importlib->guid, sizeof(GUID)); + guid.hreftype = 2; + + guid_idx = ctl2_alloc_guid(typelib, &guid); + + alloc_importfile(typelib, guid_idx, importlib->version&0xffff, + importlib->version>>16, importlib->name); + } + + if(importinfo->offset == -1 || !(importinfo->flags & MSFT_IMPINFO_OFFSET_IS_GUID)) { + MSFT_ImpInfo impinfo; + + impinfo.flags = importinfo->flags; + impinfo.oImpFile = 0; + + if(importinfo->flags & MSFT_IMPINFO_OFFSET_IS_GUID) { + MSFT_GuidEntry guid; + + guid.hreftype = 0; + memcpy(&guid.guid, &importinfo->guid, sizeof(GUID)); + + impinfo.oGuid = ctl2_alloc_guid(typelib, &guid); + + importinfo->offset = alloc_msft_importinfo(typelib, &impinfo); + + typelib->typelib_segment_data[MSFT_SEG_GUID][impinfo.oGuid+sizeof(GUID)] + = importinfo->offset+1; + + if(!strcmp(importinfo->name, "IDispatch")) + typelib->typelib_header.dispatchpos = importinfo->offset+1; + }else { + impinfo.oGuid = importinfo->id; + importinfo->offset = alloc_msft_importinfo(typelib, &impinfo); + } + } +} + +static importinfo_t *find_importinfo(msft_typelib_t *typelib, const char *name) +{ + importlib_t *importlib; + int i; + + chat("search importlib %s\n", name); + + if(!name) + return NULL; + + for(importlib = typelib->typelib->importlibs; importlib; importlib = NEXT_LINK(importlib)) { + for(i=0; i < importlib->ntypeinfos; i++) { + if(!strcmp(name, importlib->importinfos[i].name)) { + chat("Found %s in importlib.\n", name); + return importlib->importinfos+i; + } + } + } + + return NULL; +} + +static void add_structure_typeinfo(msft_typelib_t *typelib, type_t *structure); +static void add_interface_typeinfo(msft_typelib_t *typelib, type_t *interface); +static void add_enum_typeinfo(msft_typelib_t *typelib, type_t *enumeration); +static void add_coclass_typeinfo(msft_typelib_t *typelib, type_t *cls); + + +/**************************************************************************** + * encode_type + * + * Encodes a type, storing information in the TYPEDESC and ARRAYDESC + * segments as needed. + * + * RETURNS + * + * Success: 0. + * Failure: -1. + */ +static int encode_type( + msft_typelib_t *typelib, /* [I] The type library in which to encode the TYPEDESC. */ + int vt, /* [I] vt to encode */ + type_t *type, /* [I] type */ + int *encoded_type, /* [O] The encoded type description. */ + int *width, /* [O] The width of the type, or NULL. */ + int *alignment, /* [O] The alignment of the type, or NULL. */ + int *decoded_size) /* [O] The total size of the unencoded TYPEDESCs, including nested descs. */ +{ + int default_type; + int scratch; + int typeoffset; + int *typedata; + int target_type; + int child_size = 0; + + chat("encode_type vt %d type %p\n", vt, type); + + default_type = 0x80000000 | (vt << 16) | vt; + if (!width) width = &scratch; + if (!alignment) alignment = &scratch; + if (!decoded_size) decoded_size = &scratch; + + + switch (vt) { + case VT_I1: + case VT_UI1: + *encoded_type = default_type; + *width = 1; + *alignment = 1; + break; + + case VT_INT: + *encoded_type = 0x80000000 | (VT_I4 << 16) | VT_INT; + if ((typelib->typelib_header.varflags & 0x0f) == SYS_WIN16) { + *width = 2; + *alignment = 2; + } else { + *width = 4; + *alignment = 4; + } + break; + + case VT_UINT: + *encoded_type = 0x80000000 | (VT_UI4 << 16) | VT_UINT; + if ((typelib->typelib_header.varflags & 0x0f) == SYS_WIN16) { + *width = 2; + *alignment = 2; + } else { + *width = 4; + *alignment = 4; + } + break; + + case VT_UI2: + case VT_I2: + case VT_BOOL: + *encoded_type = default_type; + *width = 2; + *alignment = 2; + break; + + case VT_I4: + case VT_UI4: + case VT_R4: + case VT_ERROR: + case VT_BSTR: + case VT_HRESULT: + *encoded_type = default_type; + *width = 4; + *alignment = 4; + break; + + case VT_R8: + case VT_I8: + case VT_UI8: + *encoded_type = default_type; + *width = 8; + *alignment = 8; + break; + + case VT_CY: + *encoded_type = default_type; + *width = 8; + *alignment = 8; + break; + + case VT_VOID: + *encoded_type = 0x80000000 | (VT_EMPTY << 16) | vt; + *width = 0; + *alignment = 1; + break; + + case VT_UNKNOWN: + case VT_DISPATCH: + *encoded_type = default_type; + *width = 4; + *alignment = 4; + break; + + case VT_VARIANT: + *encoded_type = default_type; + break; + + case VT_PTR: + { + int next_vt; + for(next_vt = 0; type->ref; type = type->ref) { + next_vt = get_type_vt(type->ref); + if (next_vt != 0) + break; + } + /* if no type found then it must be void */ + if (next_vt == 0) + next_vt = VT_VOID; + + encode_type(typelib, next_vt, type->ref, &target_type, NULL, NULL, &child_size); + if(type->ref && (type->ref->type == RPC_FC_IP)) { + chat("encode_type: skipping ptr\n"); + *encoded_type = target_type; + *width = 4; + *alignment = 4; + *decoded_size = child_size; + break; + } + + for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) { + typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; + if (((typedata[0] & 0xffff) == VT_PTR) && (typedata[1] == target_type)) break; + } + + if (typeoffset == typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length) { + int mix_field; + + if (target_type & 0x80000000) { + mix_field = ((target_type >> 16) & 0x3fff) | VT_BYREF; + } else { + typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][target_type]; + mix_field = ((typedata[0] >> 16) == 0x7fff)? 0x7fff: 0x7ffe; + } + + typeoffset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEDESC, 8, 0); + typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; + + typedata[0] = (mix_field << 16) | VT_PTR; + typedata[1] = target_type; + } + + *encoded_type = typeoffset; + + *width = 4; + *alignment = 4; + *decoded_size = 8 /*sizeof(TYPEDESC)*/ + child_size; + break; + } +#if 0 + + + case VT_SAFEARRAY: + /* FIXME: Make with the error checking. */ + FIXME("SAFEARRAY vartype, may not work correctly.\n"); + + ctl2_encode_typedesc(typelib, tdesc->u.lptdesc, &target_type, NULL, NULL, &child_size); + + for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) { + typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; + if (((typedata[0] & 0xffff) == VT_SAFEARRAY) && (typedata[1] == target_type)) break; + } + + if (typeoffset == typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length) { + int mix_field; + + if (target_type & 0x80000000) { + mix_field = ((target_type >> 16) & VT_TYPEMASK) | VT_ARRAY; + } else { + typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][target_type]; + mix_field = ((typedata[0] >> 16) == 0x7fff)? 0x7fff: 0x7ffe; + } + + typeoffset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEDESC, 8, 0); + typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; + + typedata[0] = (mix_field << 16) | VT_SAFEARRAY; + typedata[1] = target_type; + } + + *encoded_tdesc = typeoffset; + + *width = 4; + *alignment = 4; + *decoded_size = sizeof(TYPEDESC) + child_size; + break; + + +#endif + + case VT_USERDEFINED: + { + int typeinfo_offset; + chat("encode_type: VT_USERDEFINED - type %p name = %s type->type %d idx %d\n", type, + type->name, type->type, type->typelib_idx); + + if(type->typelib_idx == -1) { + chat("encode_type: trying to ref not added type\n"); + switch(type->type) { + case RPC_FC_STRUCT: + case RPC_FC_PSTRUCT: + case RPC_FC_CSTRUCT: + case RPC_FC_CPSTRUCT: + case RPC_FC_CVSTRUCT: + case RPC_FC_BOGUS_STRUCT: + add_structure_typeinfo(typelib, type); + break; + case RPC_FC_IP: + add_interface_typeinfo(typelib, type); + break; + case RPC_FC_ENUM16: + add_enum_typeinfo(typelib, type); + break; + case 0: + if (type->kind == TKIND_COCLASS) + add_coclass_typeinfo(typelib, type); + else + error("encode_type: VT_USERDEFINED - can't yet add typedef's on the fly\n"); + break; + default: + error("encode_type: VT_USERDEFINED - unhandled type %d\n", type->type); + } + } + + typeinfo_offset = typelib->typelib_typeinfo_offsets[type->typelib_idx]; + for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) { + typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; + if ((typedata[0] == ((0x7fff << 16) | VT_USERDEFINED)) && (typedata[1] == typeinfo_offset)) break; + } + + if (typeoffset == typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length) { + typeoffset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEDESC, 8, 0); + typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; + + typedata[0] = (0x7fff << 16) | VT_USERDEFINED; + typedata[1] = typeinfo_offset; + } + + *encoded_type = typeoffset; + *width = 0; + *alignment = 1; + + if(type->type == RPC_FC_IP) { + for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) { + typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; + if ((typedata[0] == ((0x7fff << 16) | VT_PTR)) && (typedata[1] == *encoded_type)) break; + } + if (typeoffset == typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length) { + typeoffset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEDESC, 8, 0); + typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; + + typedata[0] = (0x7fff << 16) | VT_PTR; + typedata[1] = *encoded_type; + } + *encoded_type = typeoffset; + *width = 4; + *alignment = 4; + *decoded_size += 8; + } + break; + } + + default: + error("encode_type: unrecognized type %d.\n", vt); + *encoded_type = default_type; + *width = 0; + *alignment = 1; + break; + } + + return 0; +} + +static void dump_type(type_t *t) +{ + chat("dump_type: %p name %s type %d ref %p attrs %p\n", t, t->name, t->type, t->ref, t->attrs); + if(t->ref) dump_type(t->ref); +} + +static int encode_var( + msft_typelib_t *typelib, /* [I] The type library in which to encode the TYPEDESC. */ + var_t *var, /* [I] The type description to encode. */ + int *encoded_type, /* [O] The encoded type description. */ + int *width, /* [O] The width of the type, or NULL. */ + int *alignment, /* [O] The alignment of the type, or NULL. */ + int *decoded_size) /* [O] The total size of the unencoded TYPEDESCs, including nested descs. */ +{ + int typeoffset; + int *typedata; + int target_type; + int child_size; + int vt; + int scratch; + type_t *type; + + if (!width) width = &scratch; + if (!alignment) alignment = &scratch; + if (!decoded_size) decoded_size = &scratch; + *decoded_size = 0; + + chat("encode_var: var %p var->tname %s var->type %p var->ptr_level %d var->type->ref %p\n", var, var->tname, var->type, var->ptr_level, var->type->ref); + if(var->ptr_level) { + int skip_ptr; + var->ptr_level--; + skip_ptr = encode_var(typelib, var, &target_type, NULL, NULL, &child_size); + var->ptr_level++; + + if(skip_ptr == 2) { + chat("encode_var: skipping ptr\n"); + *encoded_type = target_type; + *decoded_size = child_size; + *width = 4; + *alignment = 4; + return 0; + } + + for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) { + typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; + if (((typedata[0] & 0xffff) == VT_PTR) && (typedata[1] == target_type)) break; + } + + if (typeoffset == typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length) { + int mix_field; + + if (target_type & 0x80000000) { + mix_field = ((target_type >> 16) & 0x3fff) | VT_BYREF; + } else { + typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][target_type]; + mix_field = ((typedata[0] >> 16) == 0x7fff)? 0x7fff: 0x7ffe; + } + + typeoffset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEDESC, 8, 0); + typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; + + typedata[0] = (mix_field << 16) | VT_PTR; + typedata[1] = target_type; + } + + *encoded_type = typeoffset; + + *width = 4; + *alignment = 4; + *decoded_size = 8 /*sizeof(TYPEDESC)*/ + child_size; + return 0; + } + + if(var->array) { + expr_t *dim = var->array; + expr_t *array_save; + int num_dims = 1, elements = 1, arrayoffset; + int *arraydata; + + while(NEXT_LINK(dim)) { + dim = NEXT_LINK(dim); + num_dims++; + } + chat("array with %d dimensions\n", num_dims); + array_save = var->array; + var->array = NULL; + encode_var(typelib, var, &target_type, width, alignment, NULL); + var->array = array_save; + arrayoffset = ctl2_alloc_segment(typelib, MSFT_SEG_ARRAYDESC, (2 + 2 * num_dims) * sizeof(long), 0); + arraydata = (void *)&typelib->typelib_segment_data[MSFT_SEG_ARRAYDESC][arrayoffset]; + + arraydata[0] = target_type; + arraydata[1] = num_dims; + arraydata[1] |= ((num_dims * 2 * sizeof(long)) << 16); + + arraydata += 2; + while(dim) { + arraydata[0] = dim->cval; + arraydata[1] = 0; + arraydata += 2; + elements *= dim->cval; + dim = PREV_LINK(dim); + } + + typeoffset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEDESC, 8, 0); + typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; + + typedata[0] = (0x7ffe << 16) | VT_CARRAY; + typedata[1] = arrayoffset; + + *encoded_type = typeoffset; + *width = *width * elements; + *decoded_size = 20 /*sizeof(ARRAYDESC)*/ + (num_dims - 1) * 8 /*sizeof(SAFEARRAYBOUND)*/; + return 0; + } + dump_type(var->type); + + vt = get_var_vt(var); + type = var->type; + while(!vt) { + if(type->ref == NULL) { + vt = VT_VOID; + break; + } + type = type->ref; + vt = get_type_vt(type); + } + encode_type(typelib, vt, type, encoded_type, width, alignment, decoded_size); + if(type->type == RPC_FC_IP) return 2; + return 0; +} + + +static void write_value(msft_typelib_t* typelib, int *out, int vt, void *value) +{ + switch(vt) { + case VT_I2: + case VT_I4: + case VT_R4: + case VT_BOOL: + case VT_I1: + case VT_UI1: + case VT_UI2: + case VT_UI4: + case VT_INT: + case VT_UINT: + case VT_HRESULT: + { + unsigned long *lv = value; + if((*lv & 0x3ffffff) == *lv) { + *out = 0x80000000; + *out |= vt << 26; + *out |= *lv; + } else { + int offset = ctl2_alloc_segment(typelib, MSFT_SEG_CUSTDATA, 8, 0); + *((unsigned short *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset]) = vt; + memcpy(&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+2], value, 4); + *((unsigned short *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+6]) = 0x5757; + *out = offset; + } + return; + } + case VT_BSTR: + { + char *s = (char *) value; + int len = strlen(s), seg_len = (len + 6 + 3) & ~0x3; + int offset = ctl2_alloc_segment(typelib, MSFT_SEG_CUSTDATA, seg_len, 0); + *((unsigned short *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset]) = vt; + *((unsigned int *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+2]) = len; + memcpy(&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+6], value, len); + len += 6; + while(len < seg_len) { + *((char *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+len]) = 0x57; + len++; + } + *out = offset; + return; + } + + default: + warning("can't write value of type %d yet\n", vt); + } + return; +} + +static HRESULT set_custdata(msft_typelib_t *typelib, REFGUID guid, + int vt, void *value, int *offset) +{ + MSFT_GuidEntry guidentry; + int guidoffset; + int custoffset; + int *custdata; + int data_out; + + guidentry.guid = *guid; + + guidentry.hreftype = -1; + guidentry.next_hash = -1; + + guidoffset = ctl2_alloc_guid(typelib, &guidentry); + if (guidoffset == -1) return E_OUTOFMEMORY; + write_value(typelib, &data_out, vt, value); + + custoffset = ctl2_alloc_segment(typelib, MSFT_SEG_CUSTDATAGUID, 12, 0); + if (custoffset == -1) return E_OUTOFMEMORY; + + custdata = (int *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATAGUID][custoffset]; + custdata[0] = guidoffset; + custdata[1] = data_out; + custdata[2] = *offset; + *offset = custoffset; + + return S_OK; +} + +static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, func_t *func, int index) +{ + int offset, name_offset; + int *typedata, typedata_size; + int i, id, next_idx; + int decoded_size, extra_attr = 0; + int num_params = 0, num_defaults = 0; + var_t *arg, *last_arg = NULL; + char *namedata; + const attr_t *attr; + unsigned int funcflags = 0, callconv = 4 /* CC_STDCALL */; + unsigned int funckind, invokekind = 1 /* INVOKE_FUNC */; + int help_context = 0, help_string_context = 0, help_string_offset = -1; + int entry = -1, entry_is_ord = 0; + + chat("add_func_desc(%p,%d)\n", typeinfo, index); + + id = ((0x6000 | (typeinfo->typeinfo->datatype2 & 0xffff)) << 16) | index; + + switch(typeinfo->typekind) { + case TKIND_DISPATCH: + funckind = 0x4; /* FUNC_DISPATCH */ + break; + case TKIND_MODULE: + funckind = 0x3; /* FUNC_STATIC */ + break; + default: + funckind = 0x1; /* FUNC_PUREVIRTUAL */ + break; + } + + for(attr = func->def->attrs; attr; attr = NEXT_LINK(attr)) { + if(attr->type == ATTR_LOCAL) { + chat("add_func_desc: skipping local function\n"); + return S_FALSE; + } + } + + for(arg = func->args; arg; arg = NEXT_LINK(arg)) { + last_arg = arg; + num_params++; + for(attr = arg->attrs; attr; attr = NEXT_LINK(attr)) { + if(attr->type == ATTR_DEFAULTVALUE_EXPR || attr->type == ATTR_DEFAULTVALUE_STRING) { + num_defaults++; + break; + } + } + } + + chat("add_func_desc: num of params %d\n", num_params); + + name_offset = ctl2_alloc_name(typeinfo->typelib, func->def->name); + + for(attr = func->def->attrs; attr; attr = NEXT_LINK(attr)) { + expr_t *expr = attr->u.pval; + switch(attr->type) { + case ATTR_ENTRY_ORDINAL: + extra_attr = max(extra_attr, 3); + entry = expr->cval; + entry_is_ord = 1; + break; + case ATTR_ENTRY_STRING: + extra_attr = max(extra_attr, 3); + entry = ctl2_alloc_string(typeinfo->typelib, attr->u.pval); + break; + case ATTR_HELPCONTEXT: + extra_attr = max(extra_attr, 1); + help_context = expr->u.lval; + break; + case ATTR_HELPSTRING: + extra_attr = max(extra_attr, 2); + help_string_offset = ctl2_alloc_string(typeinfo->typelib, attr->u.pval); + break; + case ATTR_HELPSTRINGCONTEXT: + extra_attr = max(extra_attr, 6); + help_string_context = expr->u.lval; + break; + case ATTR_HIDDEN: + funcflags |= 0x40; /* FUNCFLAG_FHIDDEN */ + break; + case ATTR_ID: + id = expr->cval; + break; + case ATTR_OUT: + break; + case ATTR_PROPGET: + invokekind = 0x2; /* INVOKE_PROPERTYGET */ + break; + case ATTR_PROPPUT: + invokekind = 0x4; /* INVOKE_PROPERTYPUT */ + break; + case ATTR_PROPPUTREF: + invokekind = 0x8; /* INVOKE_PROPERTYPUTREF */ + break; + case ATTR_RESTRICTED: + funcflags |= 0x1; /* FUNCFLAG_FRESTRICTED */ + break; + case ATTR_BINDABLE: + funcflags |= 0x4; /* FUNCFLAG_BINDABLE */ + break; + default: + warning("add_func_desc: ignoring attr %d\n", attr->type); + break; + } + } + + switch(invokekind) { + case 0x2: /* INVOKE_PROPERTYGET */ + if((num_params != 0 && typeinfo->typekind == TKIND_DISPATCH) + || (num_params != 1 && typeinfo->typekind == TKIND_INTERFACE)) { + error("expecting no args on a propget func\n"); + return S_FALSE; + } + break; + case 0x4: /* INVOKE_PROPERTYPUT */ + case 0x8: /* INVOKE_PROPERTYPUTREF */ + if(num_params != 1) { + error("expecting one arg on a propput func\n"); + return S_FALSE; + } + break; + default: + break; + } + + /* allocate type data space for us */ + typedata_size = 0x18 + extra_attr * sizeof(int) + (num_params * (num_defaults ? 16 : 12)); + + if (!typeinfo->func_data) { + typeinfo->func_data = xmalloc(0x100); + typeinfo->func_data_allocated = 0x100; + typeinfo->func_data[0] = 0; + } + + if(typeinfo->func_data[0] + typedata_size + sizeof(int) > typeinfo->func_data_allocated) { + typeinfo->func_data_allocated = max(typeinfo->func_data_allocated * 2, + typeinfo->func_data[0] + typedata_size + sizeof(int)); + typeinfo->func_data = xrealloc(typeinfo->func_data, typeinfo->func_data_allocated); + } + + offset = typeinfo->func_data[0]; + typeinfo->func_data[0] += typedata_size; + typedata = typeinfo->func_data + (offset >> 2) + 1; + + + /* find func with the same name - if it exists use its id */ + for(i = 0; i < (typeinfo->typeinfo->cElement & 0xffff); i++) { + if(name_offset == typeinfo->func_names[i]) { + id = typeinfo->func_indices[i]; + break; + } + } + + /* find the first func with the same id and link via the hiword of typedata[4] */ + next_idx = index; + for(i = 0; i < (typeinfo->typeinfo->cElement & 0xffff); i++) { + if(id == typeinfo->func_indices[i]) { + next_idx = typeinfo->func_data[(typeinfo->func_offsets[i] >> 2) + 1 + 4] >> 16; + typeinfo->func_data[(typeinfo->func_offsets[i] >> 2) + 1 + 4] &= 0xffff; + typeinfo->func_data[(typeinfo->func_offsets[i] >> 2) + 1 + 4] |= (index << 16); + break; + } + } + + /* fill out the basic type information */ + typedata[0] = typedata_size | (index << 16); + encode_var(typeinfo->typelib, func->def, &typedata[1], NULL, NULL, &decoded_size); + typedata[2] = funcflags; + typedata[3] = ((52 /*sizeof(FUNCDESC)*/ + decoded_size) << 16) | typeinfo->typeinfo->cbSizeVft; + typedata[4] = (next_idx << 16) | (callconv << 8) | (invokekind << 3) | funckind; + if(num_defaults) typedata[4] |= 0x1000; + if(entry_is_ord) typedata[4] |= 0x2000; + typedata[5] = num_params; + + /* NOTE: High word of typedata[3] is total size of FUNCDESC + size of all ELEMDESCs for params + TYPEDESCs for pointer params and return types. */ + /* That is, total memory allocation required to reconstitute the FUNCDESC in its entirety. */ + typedata[3] += (16 /*sizeof(ELEMDESC)*/ * num_params) << 16; + typedata[3] += (24 /*sizeof(PARAMDESCEX)*/ * num_defaults) << 16; + + switch(extra_attr) { + case 6: typedata[11] = help_string_context; + case 5: typedata[10] = -1; + case 4: typedata[9] = -1; + case 3: typedata[8] = entry; + case 2: typedata[7] = help_string_offset; + case 1: typedata[6] = help_context; + case 0: + break; + default: + warning("unknown number of optional attrs\n"); + } + + for (arg = last_arg, i = 0; arg; arg = PREV_LINK(arg), i++) { + const attr_t *attr; + int paramflags = 0; + int *paramdata = typedata + 6 + extra_attr + (num_defaults ? num_params : 0) + i * 3; + int *defaultdata = num_defaults ? typedata + 6 + extra_attr + i : NULL; + + if(defaultdata) *defaultdata = -1; + + encode_var(typeinfo->typelib, arg, paramdata, NULL, NULL, &decoded_size); + for(attr = arg->attrs; attr; attr = NEXT_LINK(attr)) { + switch(attr->type) { + case ATTR_DEFAULTVALUE_EXPR: + { + int vt; + expr_t *expr = (expr_t *)attr->u.pval; + if (arg->type->type == RPC_FC_ENUM16) + vt = VT_INT; + else + vt = get_var_vt(arg); + paramflags |= 0x30; /* PARAMFLAG_FHASDEFAULT | PARAMFLAG_FOPT */ + chat("default value %ld\n", expr->cval); + write_value(typeinfo->typelib, defaultdata, vt, &expr->cval); + break; + } + case ATTR_DEFAULTVALUE_STRING: + { + char *s = (char *)attr->u.pval; + int vt; + if (arg->type->type == RPC_FC_ENUM16) + vt = VT_INT; + else + vt = get_var_vt(arg); + paramflags |= 0x30; /* PARAMFLAG_FHASDEFAULT | PARAMFLAG_FOPT */ + chat("default value '%s'\n", s); + write_value(typeinfo->typelib, defaultdata, vt, s); + break; + } + case ATTR_IN: + paramflags |= 0x01; /* PARAMFLAG_FIN */ + break; + case ATTR_OPTIONAL: + paramflags |= 0x10; /* PARAMFLAG_FOPT */ + break; + case ATTR_OUT: + paramflags |= 0x02; /* PARAMFLAG_FOUT */ + break; + case ATTR_RETVAL: + paramflags |= 0x08; /* PARAMFLAG_FRETVAL */ + typedata[4] |= 0x4000; + break; + default: + chat("unhandled param attr %d\n", attr->type); + break; + } + } + paramdata[1] = -1; + paramdata[2] = paramflags; + typedata[3] += decoded_size << 16; + } + + if(typeinfo->funcs_allocated == 0) { + typeinfo->funcs_allocated = 10; + typeinfo->func_indices = xmalloc(typeinfo->funcs_allocated * sizeof(int)); + typeinfo->func_names = xmalloc(typeinfo->funcs_allocated * sizeof(int)); + typeinfo->func_offsets = xmalloc(typeinfo->funcs_allocated * sizeof(int)); + } + if(typeinfo->funcs_allocated == (typeinfo->typeinfo->cElement & 0xffff)) { + typeinfo->funcs_allocated *= 2; + typeinfo->func_indices = xrealloc(typeinfo->func_indices, typeinfo->funcs_allocated * sizeof(int)); + typeinfo->func_names = xrealloc(typeinfo->func_names, typeinfo->funcs_allocated * sizeof(int)); + typeinfo->func_offsets = xrealloc(typeinfo->func_offsets, typeinfo->funcs_allocated * sizeof(int)); + } + + /* update the index data */ + typeinfo->func_indices[typeinfo->typeinfo->cElement & 0xffff] = id; + typeinfo->func_offsets[typeinfo->typeinfo->cElement & 0xffff] = offset; + typeinfo->func_names[typeinfo->typeinfo->cElement & 0xffff] = name_offset; + + /* ??? */ + if (!typeinfo->typeinfo->res2) typeinfo->typeinfo->res2 = 0x20; + typeinfo->typeinfo->res2 <<= 1; + /* ??? */ + if (index < 2) typeinfo->typeinfo->res2 += num_params << 4; + + if (typeinfo->typeinfo->res3 == -1) typeinfo->typeinfo->res3 = 0; + typeinfo->typeinfo->res3 += 0x38 + num_params * 0x10; + if(num_defaults) typeinfo->typeinfo->res3 += num_params * 0x4; + + /* adjust size of VTBL */ + if(funckind != 0x3 /* FUNC_STATIC */) + typeinfo->typeinfo->cbSizeVft += 4; + + /* Increment the number of function elements */ + typeinfo->typeinfo->cElement += 1; + + namedata = typeinfo->typelib->typelib_segment_data[MSFT_SEG_NAME] + name_offset; + if (*((INT *)namedata) == -1) { + *((INT *)namedata) = typeinfo->typelib->typelib_typeinfo_offsets[typeinfo->typeinfo->typekind >> 16]; + if(typeinfo->typekind == TKIND_MODULE) + namedata[9] |= 0x10; + } else + namedata[9] &= ~0x10; + + if(typeinfo->typekind == TKIND_MODULE) + namedata[9] |= 0x20; + + if(invokekind != 0x4 /* INVOKE_PROPERTYPUT */ && invokekind != 0x8 /* INVOKE_PROPERTYPUTREF */) { + /* don't give the arg of a [propput*] func a name */ + for (arg = last_arg, i = 0; arg; arg = PREV_LINK(arg), i++) { + int *paramdata = typedata + 6 + extra_attr + (num_defaults ? num_params : 0) + i * 3; + offset = ctl2_alloc_name(typeinfo->typelib, arg->name); + paramdata[1] = offset; + } + } + return S_OK; +} + +static HRESULT add_var_desc(msft_typeinfo_t *typeinfo, UINT index, var_t* var) +{ + int offset, id; + unsigned int typedata_size; + INT *typedata; + int var_datawidth; + int var_alignment; + int var_type_size, var_kind = 0 /* VAR_PERINSTANCE */; + int alignment; + int varflags = 0; + const attr_t *attr; + char *namedata; + int var_num = (typeinfo->typeinfo->cElement >> 16) & 0xffff; + + chat("add_var_desc(%d,%s) array %p\n", index, var->name, var->array); + + id = 0x40000000 + index; + + for(attr = var->attrs; attr; attr = NEXT_LINK(attr)) { + expr_t *expr = attr->u.pval; + switch(attr->type) { + case ATTR_HIDDEN: + varflags |= 0x40; /* VARFLAG_FHIDDEN */ + break; + case ATTR_ID: + id = expr->cval; + break; + case ATTR_READONLY: + varflags |= 0x01; /* VARFLAG_FREADONLY */ + break; + case ATTR_RESTRICTED: + varflags |= 0x80; /* VARFLAG_FRESTRICTED */ + break; + case ATTR_SOURCE: + varflags |= 0x02; /* VARFLAG_FSOURCE */ + break; + default: + warning("AddVarDesc: unhandled attr type %d\n", attr->type); + break; + } + } + + /* allocate type data space for us */ + typedata_size = 0x14; + + if (!typeinfo->var_data) { + typeinfo->var_data = xmalloc(0x100); + typeinfo->var_data_allocated = 0x100; + typeinfo->var_data[0] = 0; + } + + if(typeinfo->var_data[0] + typedata_size + sizeof(int) > typeinfo->var_data_allocated) { + typeinfo->var_data_allocated = max(typeinfo->var_data_allocated * 2, + typeinfo->var_data[0] + typedata_size + sizeof(int)); + typeinfo->var_data = xrealloc(typeinfo->var_data, typeinfo->var_data_allocated); + } + + offset = typeinfo->var_data[0]; + typeinfo->var_data[0] += typedata_size; + typedata = typeinfo->var_data + (offset >> 2) + 1; + + /* fill out the basic type information */ + typedata[0] = typedata_size | (index << 16); + typedata[2] = varflags; + typedata[3] = (36 /*sizeof(VARDESC)*/ << 16) | 0; + + if(typeinfo->vars_allocated == 0) { + typeinfo->vars_allocated = 10; + typeinfo->var_indices = xmalloc(typeinfo->vars_allocated * sizeof(int)); + typeinfo->var_names = xmalloc(typeinfo->vars_allocated * sizeof(int)); + typeinfo->var_offsets = xmalloc(typeinfo->vars_allocated * sizeof(int)); + } + if(typeinfo->vars_allocated == var_num) { + typeinfo->vars_allocated *= 2; + typeinfo->var_indices = xrealloc(typeinfo->var_indices, typeinfo->vars_allocated * sizeof(int)); + typeinfo->var_names = xrealloc(typeinfo->var_names, typeinfo->vars_allocated * sizeof(int)); + typeinfo->var_offsets = xrealloc(typeinfo->var_offsets, typeinfo->vars_allocated * sizeof(int)); + } + /* update the index data */ + typeinfo->var_indices[var_num] = id; + typeinfo->var_names[var_num] = -1; + typeinfo->var_offsets[var_num] = offset; + + /* figure out type widths and whatnot */ + encode_var(typeinfo->typelib, var, &typedata[1], &var_datawidth, + &var_alignment, &var_type_size); + + /* pad out starting position to data width */ + typeinfo->datawidth += var_alignment - 1; + typeinfo->datawidth &= ~(var_alignment - 1); + + switch(typeinfo->typekind) { + case TKIND_ENUM: + write_value(typeinfo->typelib, &typedata[4], VT_I4, &var->eval->cval); + var_kind = 2; /* VAR_CONST */ + var_type_size += 16; /* sizeof(VARIANT) */ + typeinfo->datawidth = var_datawidth; + break; + case TKIND_RECORD: + typedata[4] = typeinfo->datawidth; + typeinfo->datawidth += var_datawidth; + break; + case TKIND_DISPATCH: + var_kind = 3; /* VAR_DISPATCH */ + typeinfo->datawidth = 4; + var_alignment = 4; + break; + default: + error("add_var_desc: unhandled type kind %d\n", typeinfo->typekind); + break; + } + + /* add type description size to total required allocation */ + typedata[3] += var_type_size << 16 | var_kind; + + /* fix type alignment */ + alignment = (typeinfo->typeinfo->typekind >> 11) & 0x1f; + if (alignment < var_alignment) { + alignment = var_alignment; + typeinfo->typeinfo->typekind &= ~0xffc0; + typeinfo->typeinfo->typekind |= alignment << 11 | alignment << 6; + } + + /* ??? */ + if (!typeinfo->typeinfo->res2) typeinfo->typeinfo->res2 = 0x1a; + if ((index == 0) || (index == 1) || (index == 2) || (index == 4) || (index == 9)) { + typeinfo->typeinfo->res2 <<= 1; + } + + /* ??? */ + if (typeinfo->typeinfo->res3 == -1) typeinfo->typeinfo->res3 = 0; + typeinfo->typeinfo->res3 += 0x2c; + + /* increment the number of variable elements */ + typeinfo->typeinfo->cElement += 0x10000; + + /* pad data width to alignment */ + typeinfo->typeinfo->size = (typeinfo->datawidth + (alignment - 1)) & ~(alignment - 1); + + offset = ctl2_alloc_name(typeinfo->typelib, var->name); + if (offset == -1) return E_OUTOFMEMORY; + + namedata = typeinfo->typelib->typelib_segment_data[MSFT_SEG_NAME] + offset; + if (*((INT *)namedata) == -1) { + *((INT *)namedata) = typeinfo->typelib->typelib_typeinfo_offsets[typeinfo->typeinfo->typekind >> 16]; + if(typeinfo->typekind != TKIND_DISPATCH) + namedata[9] |= 0x10; + } else + namedata[9] &= ~0x10; + + if (typeinfo->typekind == TKIND_ENUM) { + namedata[9] |= 0x20; + } + typeinfo->var_names[var_num] = offset; + + return S_OK; +} + +static HRESULT add_impl_type(msft_typeinfo_t *typeinfo, type_t *ref, importinfo_t *importinfo) +{ + if(importinfo) { + alloc_importinfo(typeinfo->typelib, importinfo); + typeinfo->typeinfo->datatype1 = importinfo->offset+1; + }else { + if(ref->typelib_idx == -1) + add_interface_typeinfo(typeinfo->typelib, ref); + if(ref->typelib_idx == -1) + error("add_impl_type: unable to add inherited interface\n"); + + typeinfo->typeinfo->datatype1 = typeinfo->typelib->typelib_typeinfo_offsets[ref->typelib_idx]; + } + + typeinfo->typeinfo->cImplTypes++; + return S_OK; +} + +static msft_typeinfo_t *create_msft_typeinfo(msft_typelib_t *typelib, enum type_kind kind, + const char *name, const attr_t *attr, int idx) +{ + msft_typeinfo_t *msft_typeinfo; + int nameoffset; + int typeinfo_offset; + MSFT_TypeInfoBase *typeinfo; + MSFT_GuidEntry guidentry; + + chat("create_msft_typeinfo: name %s kind %d\n", name, kind); + + msft_typeinfo = xmalloc(sizeof(*msft_typeinfo)); + + msft_typeinfo->typelib = typelib; + + nameoffset = ctl2_alloc_name(typelib, name); + typeinfo_offset = ctl2_alloc_typeinfo(typelib, nameoffset); + typeinfo = (MSFT_TypeInfoBase *)&typelib->typelib_segment_data[MSFT_SEG_TYPEINFO][typeinfo_offset]; + + typelib->typelib_segment_data[MSFT_SEG_NAME][nameoffset + 9] = 0x38; + *((int *)&typelib->typelib_segment_data[MSFT_SEG_NAME][nameoffset]) = typeinfo_offset; + + msft_typeinfo->typekind = kind; + msft_typeinfo->typeinfo = typeinfo; + + typeinfo->typekind |= kind | 0x20; + + if(kind == TKIND_COCLASS) + typeinfo->flags |= 0x2; /* TYPEFLAG_FCANCREATE */ + + for( ; attr; attr = NEXT_LINK(attr)) { + switch(attr->type) { + case ATTR_AGGREGATABLE: + if (kind == TKIND_COCLASS) + typeinfo->flags |= 0x400; /* TYPEFLAG_FAGGREGATABLE */ + break; + + case ATTR_APPOBJECT: + if (kind == TKIND_COCLASS) + typeinfo->flags |= 0x1; /* TYPEFLAG_FAPPOBJECT */ + break; + + case ATTR_CONTROL: + if (kind == TKIND_COCLASS) + typeinfo->flags |= 0x20; /* TYPEFLAG_FCONTROL */ + break; + + case ATTR_DISPINTERFACE: + break; + + case ATTR_DLLNAME: + { + int offset = ctl2_alloc_string(typelib, attr->u.pval); + typeinfo->datatype1 = offset; + break; + } + + case ATTR_DUAL: + /* FIXME: check interface is compatible */ + typeinfo->typekind = (typeinfo->typekind & ~0xff) | 0x34; + typeinfo->flags |= 0x140; /* TYPEFLAG_FDUAL | TYPEFLAG_FOLEAUTOMATION */ + break; + + case ATTR_HELPCONTEXT: + { + expr_t *expr = (expr_t*)attr->u.pval; + typeinfo->helpcontext = expr->cval; + break; + } + case ATTR_HELPSTRING: + { + int offset = ctl2_alloc_string(typelib, attr->u.pval); + if (offset == -1) break; + typeinfo->docstringoffs = offset; + break; + } + case ATTR_HELPSTRINGCONTEXT: + { + expr_t *expr = (expr_t*)attr->u.pval; + typeinfo->helpstringcontext = expr->cval; + break; + } + case ATTR_HIDDEN: + typeinfo->flags |= 0x10; /* TYPEFLAG_FHIDDEN */ + break; + + case ATTR_NONCREATABLE: + typeinfo->flags &= ~0x2; /* TYPEFLAG_FCANCREATE */ + break; + + case ATTR_NONEXTENSIBLE: + typeinfo->flags |= 0x80; /* TYPEFLAG_FNONEXTENSIBLE */ + break; + + case ATTR_OBJECT: + break; + + case ATTR_ODL: + break; + + case ATTR_OLEAUTOMATION: + typeinfo->flags |= 0x100; /* TYPEFLAG_FOLEAUTOMATION */ + break; + + case ATTR_PUBLIC: + break; + + case ATTR_RESTRICTED: + typeinfo->flags |= 0x200; /* TYPEFLAG_FRESTRICTED */ + break; + + case ATTR_UUID: + guidentry.guid = *(GUID*)attr->u.pval; + guidentry.hreftype = typelib->typelib_typeinfo_offsets[typeinfo->typekind >> 16]; + guidentry.next_hash = -1; + typeinfo->posguid = ctl2_alloc_guid(typelib, &guidentry); +#if 0 + if (IsEqualIID(guid, &IID_IDispatch)) { + typelib->typelib_header.dispatchpos = typelib->typelib_typeinfo_offsets[typeinfo->typekind >> 16]; + } +#endif + break; + + case ATTR_VERSION: + typeinfo->version = attr->u.ival; + break; + + default: + warning("create_msft_typeinfo: ignoring attr %d\n", attr->type); + break; + } + } + + if (typelib->last_typeinfo) typelib->last_typeinfo->next_typeinfo = msft_typeinfo; + typelib->last_typeinfo = msft_typeinfo; + if (!typelib->typeinfos) typelib->typeinfos = msft_typeinfo; + + + return msft_typeinfo; +} + +static void add_dispatch(msft_typelib_t *typelib) +{ + int guid_offset, impfile_offset; + MSFT_GuidEntry guidentry; + MSFT_ImpInfo impinfo; + GUID stdole = {0x00020430,0x0000,0x0000,{0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}}; + GUID iid_idispatch = {0x00020400,0x0000,0x0000,{0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}}; + + if(typelib->typelib_header.dispatchpos != -1) return; + + guidentry.guid = stdole; + guidentry.hreftype = 2; + guidentry.next_hash = -1; + guid_offset = ctl2_alloc_guid(typelib, &guidentry); + impfile_offset = alloc_importfile(typelib, guid_offset, 2, 0, "stdole2.tlb"); + + guidentry.guid = iid_idispatch; + guidentry.hreftype = 1; + guidentry.next_hash = -1; + impinfo.flags = TKIND_INTERFACE << 24 | MSFT_IMPINFO_OFFSET_IS_GUID; + impinfo.oImpFile = impfile_offset; + impinfo.oGuid = ctl2_alloc_guid(typelib, &guidentry); + typelib->typelib_header.dispatchpos = alloc_msft_importinfo(typelib, &impinfo) | 0x01; +} + +static void add_dispinterface_typeinfo(msft_typelib_t *typelib, type_t *dispinterface) +{ + int idx = 0; + func_t *func; + var_t *var; + msft_typeinfo_t *msft_typeinfo; + + if (-1 < dispinterface->typelib_idx) + return; + + dispinterface->typelib_idx = typelib->typelib_header.nrtypeinfos; + msft_typeinfo = create_msft_typeinfo(typelib, TKIND_DISPATCH, dispinterface->name, + dispinterface->attrs, typelib->typelib_header.nrtypeinfos); + + msft_typeinfo->typeinfo->size = 4; + msft_typeinfo->typeinfo->typekind |= 0x2100; + + msft_typeinfo->typeinfo->flags |= 0x1000; /* TYPEFLAG_FDISPATCHABLE */ + add_dispatch(typelib); + msft_typeinfo->typeinfo->cImplTypes = 1; + + /* count the no of funcs, as the variable indicies come after the funcs */ + if((func = dispinterface->funcs)) { + idx++; + while(NEXT_LINK(func)) { + func = NEXT_LINK(func); + idx++; + } + } + + if((var = dispinterface->fields)) { + while(NEXT_LINK(var)) var = NEXT_LINK(var); + while(var) { + add_var_desc(msft_typeinfo, idx, var); + idx++; + var = PREV_LINK(var); + } + } + + idx = 0; + /* the func count above has already left us pointing at the first func */ + while(func) { + if(add_func_desc(msft_typeinfo, func, idx) == S_OK) + idx++; + func = PREV_LINK(func); + } +} + +static void add_interface_typeinfo(msft_typelib_t *typelib, type_t *interface) +{ + int idx = 0; + func_t *func; + type_t *ref; + msft_typeinfo_t *msft_typeinfo; + importinfo_t *ref_importinfo = NULL; + int num_parents = 0, num_funcs = 0; + const attr_t *attr; + const type_t *derived; + + if (-1 < interface->typelib_idx) + return; + + for(attr = interface->attrs; attr; attr = NEXT_LINK(attr)) + if(attr->type == ATTR_DISPINTERFACE) + return add_dispinterface_typeinfo(typelib, interface); + + /* midl adds the parent interface first, unless the parent itself + has no parent (i.e. it stops before IUnknown). */ + + if(interface->ref) { + ref_importinfo = find_importinfo(typelib, interface->ref->name); + + if(!ref_importinfo && interface->ref->ref && interface->ref->typelib_idx == -1) + add_interface_typeinfo(typelib, interface->ref); + } + + interface->typelib_idx = typelib->typelib_header.nrtypeinfos; + msft_typeinfo = create_msft_typeinfo(typelib, TKIND_INTERFACE, interface->name, interface->attrs, + typelib->typelib_header.nrtypeinfos); + msft_typeinfo->typeinfo->size = 4; + msft_typeinfo->typeinfo->typekind |= 0x2200; + + for (derived = interface->ref; derived; derived = derived->ref) + if (derived->name && !strcmp(derived->name, "IDispatch")) + msft_typeinfo->typeinfo->flags |= 0x1000; /* TYPEFLAG_FDISPATCHABLE */ + + /* can't be dual if it doesn't derive from IDispatch */ + if (!(msft_typeinfo->typeinfo->flags & 0x1000)) /* TYPEFLAG_FDISPATCHABLE */ + msft_typeinfo->typeinfo->flags &= ~0x40; /* TYPEFLAG_FDUAL */ + + if(interface->ref) + add_impl_type(msft_typeinfo, interface->ref, ref_importinfo); + + /* count the number of inherited interfaces and non-local functions */ + for(ref = interface->ref; ref; ref = ref->ref) { + num_parents++; + for(func = ref->funcs; func; func = NEXT_LINK(func)) { + const attr_t *attr; + for(attr = func->def->attrs; attr; attr = NEXT_LINK(attr)) + if(attr->type == ATTR_LOCAL) + break; + if(!attr) + num_funcs++; + } + } + msft_typeinfo->typeinfo->datatype2 = num_funcs << 16 | num_parents; + msft_typeinfo->typeinfo->cbSizeVft = num_funcs * 4; + + if((func = interface->funcs)) { + while(NEXT_LINK(func)) func = NEXT_LINK(func); + while(func) { + if(add_func_desc(msft_typeinfo, func, idx) == S_OK) + idx++; + func = PREV_LINK(func); + } + } +} + +static void add_structure_typeinfo(msft_typelib_t *typelib, type_t *structure) +{ + int idx = 0; + var_t *cur = structure->fields; + msft_typeinfo_t *msft_typeinfo; + + if (-1 < structure->typelib_idx) + return; + + structure->typelib_idx = typelib->typelib_header.nrtypeinfos; + msft_typeinfo = create_msft_typeinfo(typelib, TKIND_RECORD, structure->name, structure->attrs, + typelib->typelib_header.nrtypeinfos); + msft_typeinfo->typeinfo->size = 0; + + while(NEXT_LINK(cur)) cur = NEXT_LINK(cur); + while(cur) { + add_var_desc(msft_typeinfo, idx, cur); + idx++; + cur = PREV_LINK(cur); + } +} + +static void add_enum_typeinfo(msft_typelib_t *typelib, type_t *enumeration) +{ + int idx = 0; + var_t *cur = enumeration->fields; + msft_typeinfo_t *msft_typeinfo; + + enumeration->typelib_idx = typelib->typelib_header.nrtypeinfos; + msft_typeinfo = create_msft_typeinfo(typelib, TKIND_ENUM, enumeration->name, enumeration->attrs, + typelib->typelib_header.nrtypeinfos); + msft_typeinfo->typeinfo->size = 0; + + while(NEXT_LINK(cur)) cur = NEXT_LINK(cur); + while(cur) { + add_var_desc(msft_typeinfo, idx, cur); + idx++; + cur = PREV_LINK(cur); + } +} + +static void add_typedef_typeinfo(msft_typelib_t *typelib, var_t *tdef) +{ + msft_typeinfo_t *msft_typeinfo; + int alignment; + const attr_t *attrs; + + if (-1 < tdef->type->typelib_idx) + return; + + tdef->type->typelib_idx = typelib->typelib_header.nrtypeinfos; + msft_typeinfo = create_msft_typeinfo(typelib, TKIND_ALIAS, tdef->name, tdef->type->attrs, + typelib->typelib_header.nrtypeinfos); + attrs = tdef->type->attrs; + tdef->type->attrs = NULL; + encode_var(typelib, tdef, &msft_typeinfo->typeinfo->datatype1, &msft_typeinfo->typeinfo->size, + &alignment, &msft_typeinfo->typeinfo->datatype2); + tdef->type->attrs = attrs; + msft_typeinfo->typeinfo->typekind |= (alignment << 11 | alignment << 6); +} + +static void add_coclass_typeinfo(msft_typelib_t *typelib, type_t *cls) +{ + msft_typeinfo_t *msft_typeinfo; + ifref_t *iref; + int num_ifaces = 0, offset, i; + MSFT_RefRecord *ref, *first = NULL, *first_source = NULL; + int have_default = 0, have_default_source = 0; + const attr_t *attr; + + if (-1 < cls->typelib_idx) + return; + + cls->typelib_idx = typelib->typelib_header.nrtypeinfos; + msft_typeinfo = create_msft_typeinfo(typelib, TKIND_COCLASS, cls->name, cls->attrs, + typelib->typelib_header.nrtypeinfos); + + if((iref = cls->ifaces)) { + num_ifaces++; + while(NEXT_LINK(iref)) { + iref = NEXT_LINK(iref); + num_ifaces++; + } + } + + offset = msft_typeinfo->typeinfo->datatype1 = ctl2_alloc_segment(typelib, MSFT_SEG_REFERENCES, + num_ifaces * sizeof(*ref), 0); + for(i = 0; i < num_ifaces; i++) { + if(iref->iface->typelib_idx == -1) + add_interface_typeinfo(typelib, iref->iface); + ref = (MSFT_RefRecord*) (typelib->typelib_segment_data[MSFT_SEG_REFERENCES] + offset + i * sizeof(*ref)); + ref->reftype = typelib->typelib_typeinfo_offsets[iref->iface->typelib_idx]; + ref->flags = 0; + ref->oCustData = -1; + ref->onext = -1; + if(i < num_ifaces - 1) + ref->onext = offset + (i + 1) * sizeof(*ref); + + for(attr = iref->attrs; attr; attr = NEXT_LINK(attr)) { + switch(attr->type) { + case ATTR_DEFAULT: + ref->flags |= 0x1; /* IMPLTYPEFLAG_FDEFAULT */ + break; + case ATTR_RESTRICTED: + ref->flags |= 0x4; /* IMPLTYPEFLAG_FRESTRICTED */ + break; + case ATTR_SOURCE: + ref->flags |= 0x2; /* IMPLTYPEFLAG_FSOURCE */ + break; + default: + warning("add_coclass_typeinfo: unhandled attr %d\n", attr->type); + } + } + if(ref->flags & 0x1) { /* IMPLTYPEFLAG_FDEFAULT */ + if(ref->flags & 0x2) /* IMPLTYPEFLAG_SOURCE */ + have_default_source = 1; + else + have_default = 1; + } + + /* If the interface is non-restricted and we haven't already had one then + remember it so that we can use it as a default later */ + if((ref->flags & 0x4) == 0) { /* IMPLTYPEFLAG_FRESTRICTED */ + if(ref->flags & 0x2) { /* IMPLTYPEFLAG_FSOURCE */ + if(!first_source) + first_source = ref; + } + else if(!first) + first = ref; + } + iref = PREV_LINK(iref); + } + + /* If we haven't had a default interface, then set the default flags on the + first ones */ + if(!have_default && first) + first->flags |= 0x1; + if(!have_default_source && first_source) + first_source->flags |= 0x1; + + msft_typeinfo->typeinfo->cImplTypes = num_ifaces; + msft_typeinfo->typeinfo->size = 4; + msft_typeinfo->typeinfo->typekind |= 0x2200; +} + +static void add_module_typeinfo(msft_typelib_t *typelib, type_t *module) +{ + int idx = 0; + func_t *func; + msft_typeinfo_t *msft_typeinfo; + + if (-1 < module->typelib_idx) + return; + + module->typelib_idx = typelib->typelib_header.nrtypeinfos; + msft_typeinfo = create_msft_typeinfo(typelib, TKIND_MODULE, module->name, module->attrs, + typelib->typelib_header.nrtypeinfos); + msft_typeinfo->typeinfo->typekind |= 0x0a00; + + if((func = module->funcs)) { + while(NEXT_LINK(func)) func = NEXT_LINK(func); + while(func) { + if(add_func_desc(msft_typeinfo, func, idx) == S_OK) + idx++; + func = PREV_LINK(func); + } + } + msft_typeinfo->typeinfo->size = idx; +} + +static void add_entry(msft_typelib_t *typelib, typelib_entry_t *entry) +{ + switch(entry->kind) { + case TKIND_INTERFACE: + add_interface_typeinfo(typelib, entry->u.interface); + break; + + case TKIND_RECORD: + add_structure_typeinfo(typelib, entry->u.structure); + break; + + case TKIND_ENUM: + add_enum_typeinfo(typelib, entry->u.enumeration); + break; + + case TKIND_ALIAS: + add_typedef_typeinfo(typelib, entry->u.tdef); + break; + + case TKIND_COCLASS: + add_coclass_typeinfo(typelib, entry->u.class); + break; + + case TKIND_MODULE: + add_module_typeinfo(typelib, entry->u.module); + break; + + default: + error("add_entry: unhandled type %d\n", entry->kind); + break; + } +} + +static void set_name(msft_typelib_t *typelib) +{ + int offset; + + offset = ctl2_alloc_name(typelib, typelib->typelib->name); + if (offset == -1) return; + typelib->typelib_header.NameOffset = offset; + return; +} + +static void set_version(msft_typelib_t *typelib) +{ + long version = MAKELONG(0,0); + const attr_t *attr; + + for(attr = typelib->typelib->attrs; attr; attr = NEXT_LINK(attr)) { + if(attr->type == ATTR_VERSION) { + version = attr->u.ival; + } + } + typelib->typelib_header.version = version; + return; +} + +static void set_guid(msft_typelib_t *typelib) +{ + MSFT_GuidEntry guidentry; + int offset; + const attr_t *attr; + GUID guid = {0,0,0,{0,0,0,0,0,0}}; + + guidentry.guid = guid; + guidentry.hreftype = -2; + guidentry.next_hash = -1; + + for(attr = typelib->typelib->attrs; attr; attr = NEXT_LINK(attr)) { + if(attr->type == ATTR_UUID) { + guidentry.guid = *(GUID*)(attr->u.pval); + } + } + + offset = ctl2_alloc_guid(typelib, &guidentry); + + if (offset == -1) return; + + typelib->typelib_header.posguid = offset; + + return; +} + +static void set_doc_string(msft_typelib_t *typelib) +{ + const attr_t *attr; + int offset; + + for(attr = typelib->typelib->attrs; attr; attr = NEXT_LINK(attr)) { + if(attr->type == ATTR_HELPSTRING) { + offset = ctl2_alloc_string(typelib, attr->u.pval); + if (offset == -1) return; + typelib->typelib_header.helpstring = offset; + } + } + return; +} + +static void set_help_file_name(msft_typelib_t *typelib) +{ + int offset; + const attr_t *attr; + for(attr = typelib->typelib->attrs; attr; attr = NEXT_LINK(attr)) { + if(attr->type == ATTR_HELPFILE) { + offset = ctl2_alloc_string(typelib, attr->u.pval); + if (offset == -1) return; + typelib->typelib_header.helpfile = offset; + typelib->typelib_header.varflags |= 0x10; + } + } + return; +} + +static void set_help_context(msft_typelib_t *typelib) +{ + const attr_t *attr; + for(attr = typelib->typelib->attrs; attr; attr = NEXT_LINK(attr)) { + if(attr->type == ATTR_HELPCONTEXT) { + const expr_t *expr = (expr_t *)attr->u.pval; + typelib->typelib_header.helpcontext = expr->cval; + } + } + return; +} + +static void set_help_string_dll(msft_typelib_t *typelib) +{ + int offset; + const attr_t *attr; + for(attr = typelib->typelib->attrs; attr; attr = NEXT_LINK(attr)) { + if(attr->type == ATTR_HELPSTRINGDLL) { + offset = ctl2_alloc_string(typelib, attr->u.pval); + if (offset == -1) return; + typelib->help_string_dll_offset = offset; + typelib->typelib_header.varflags |= 0x100; + } + } + return; +} + +static void set_help_string_context(msft_typelib_t *typelib) +{ + const attr_t *attr; + for(attr = typelib->typelib->attrs; attr; attr = NEXT_LINK(attr)) { + if(attr->type == ATTR_HELPSTRINGCONTEXT) { + const expr_t *expr = (expr_t *)attr->u.pval; + typelib->typelib_header.helpstringcontext = expr->cval; + } + } + return; +} + +static void set_lcid(msft_typelib_t *typelib) +{ + typelib->typelib_header.lcid2 = 0x0; + return; +} + +static void set_lib_flags(msft_typelib_t *typelib) +{ + const attr_t *attr; + + typelib->typelib_header.flags = 0; + for(attr = typelib->typelib->attrs; attr; attr = NEXT_LINK(attr)) { + switch(attr->type) { + case ATTR_CONTROL: + typelib->typelib_header.flags |= 0x02; /* LIBFLAG_FCONTROL */ + break; + case ATTR_HIDDEN: + typelib->typelib_header.flags |= 0x04; /* LIBFLAG_FHIDDEN */ + break; + case ATTR_RESTRICTED: + typelib->typelib_header.flags |= 0x01; /* LIBFLAG_FRESTRICTED */ + break; + default: + break; + } + } + return; +} + +static int ctl2_write_chunk(int fd, void *segment, int length) +{ + if (write(fd, segment, length) != length) { + close(fd); + return 0; + } + return -1; +} + +static int ctl2_write_segment(msft_typelib_t *typelib, int fd, int segment) +{ + if (write(fd, typelib->typelib_segment_data[segment], typelib->typelib_segdir[segment].length) + != typelib->typelib_segdir[segment].length) { + close(fd); + return 0; + } + + return -1; +} + +static void ctl2_finalize_typeinfos(msft_typelib_t *typelib, int filesize) +{ + msft_typeinfo_t *typeinfo; + + for (typeinfo = typelib->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) { + typeinfo->typeinfo->memoffset = filesize; + if (typeinfo->func_data) + filesize += typeinfo->func_data[0] + ((typeinfo->typeinfo->cElement & 0xffff) * 12); + if (typeinfo->var_data) + filesize += typeinfo->var_data[0] + (((typeinfo->typeinfo->cElement >> 16) & 0xffff) * 12); + if (typeinfo->func_data || typeinfo->var_data) + filesize += 4; + } +} + +static int ctl2_finalize_segment(msft_typelib_t *typelib, int filepos, int segment) +{ + if (typelib->typelib_segdir[segment].length) { + typelib->typelib_segdir[segment].offset = filepos; + } else { + typelib->typelib_segdir[segment].offset = -1; + } + + return typelib->typelib_segdir[segment].length; +} + + +static void ctl2_write_typeinfos(msft_typelib_t *typelib, int fd) +{ + msft_typeinfo_t *typeinfo; + int typedata_size; + + for (typeinfo = typelib->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) { + if (!typeinfo->func_data && !typeinfo->var_data) continue; + typedata_size = 0; + if (typeinfo->func_data) + typedata_size = typeinfo->func_data[0]; + if (typeinfo->var_data) + typedata_size += typeinfo->var_data[0]; + ctl2_write_chunk(fd, &typedata_size, sizeof(int)); + if (typeinfo->func_data) + ctl2_write_chunk(fd, typeinfo->func_data + 1, typeinfo->func_data[0]); + if (typeinfo->var_data) + ctl2_write_chunk(fd, typeinfo->var_data + 1, typeinfo->var_data[0]); + if (typeinfo->func_indices) + ctl2_write_chunk(fd, typeinfo->func_indices, (typeinfo->typeinfo->cElement & 0xffff) * 4); + if (typeinfo->var_indices) + ctl2_write_chunk(fd, typeinfo->var_indices, (typeinfo->typeinfo->cElement >> 16) * 4); + if (typeinfo->func_names) + ctl2_write_chunk(fd, typeinfo->func_names, (typeinfo->typeinfo->cElement & 0xffff) * 4); + if (typeinfo->var_names) + ctl2_write_chunk(fd, typeinfo->var_names, (typeinfo->typeinfo->cElement >> 16) * 4); + if (typeinfo->func_offsets) + ctl2_write_chunk(fd, typeinfo->func_offsets, (typeinfo->typeinfo->cElement & 0xffff) * 4); + if (typeinfo->var_offsets) { + int add = 0, i, offset; + if(typeinfo->func_data) + add = typeinfo->func_data[0]; + for(i = 0; i < (typeinfo->typeinfo->cElement >> 16); i++) { + offset = typeinfo->var_offsets[i]; + offset += add; + ctl2_write_chunk(fd, &offset, 4); + } + } + } +} + +static int save_all_changes(msft_typelib_t *typelib) +{ + int retval; + int filepos; + int fd; + + chat("save_all_changes(%p)\n", typelib); + + retval = TYPE_E_IOERROR; + + fd = creat(typelib->typelib->filename, 0666); + if (fd == -1) return retval; + + filepos = sizeof(MSFT_Header) + sizeof(MSFT_SegDir); + if(typelib->typelib_header.varflags & 0x100) filepos += 4; /* helpstringdll */ + filepos += typelib->typelib_header.nrtypeinfos * 4; + + filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_TYPEINFO); + filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_GUIDHASH); + filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_GUID); + filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_REFERENCES); + filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_IMPORTINFO); + filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_IMPORTFILES); + filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_NAMEHASH); + filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_NAME); + filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_STRING); + filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_TYPEDESC); + filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_ARRAYDESC); + filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_CUSTDATA); + filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_CUSTDATAGUID); + + ctl2_finalize_typeinfos(typelib, filepos); + + if (!ctl2_write_chunk(fd, &typelib->typelib_header, sizeof(typelib->typelib_header))) return retval; + if(typelib->typelib_header.varflags & 0x100) + if (!ctl2_write_chunk(fd, &typelib->help_string_dll_offset, sizeof(typelib->help_string_dll_offset))) + return retval; + + if (!ctl2_write_chunk(fd, typelib->typelib_typeinfo_offsets, typelib->typelib_header.nrtypeinfos * 4)) return retval; + if (!ctl2_write_chunk(fd, &typelib->typelib_segdir, sizeof(typelib->typelib_segdir))) return retval; + if (!ctl2_write_segment(typelib, fd, MSFT_SEG_TYPEINFO )) return retval; + if (!ctl2_write_segment(typelib, fd, MSFT_SEG_GUIDHASH )) return retval; + if (!ctl2_write_segment(typelib, fd, MSFT_SEG_GUID )) return retval; + if (!ctl2_write_segment(typelib, fd, MSFT_SEG_REFERENCES )) return retval; + if (!ctl2_write_segment(typelib, fd, MSFT_SEG_IMPORTINFO )) return retval; + if (!ctl2_write_segment(typelib, fd, MSFT_SEG_IMPORTFILES )) return retval; + if (!ctl2_write_segment(typelib, fd, MSFT_SEG_NAMEHASH )) return retval; + if (!ctl2_write_segment(typelib, fd, MSFT_SEG_NAME )) return retval; + if (!ctl2_write_segment(typelib, fd, MSFT_SEG_STRING )) return retval; + if (!ctl2_write_segment(typelib, fd, MSFT_SEG_TYPEDESC )) return retval; + if (!ctl2_write_segment(typelib, fd, MSFT_SEG_ARRAYDESC )) return retval; + if (!ctl2_write_segment(typelib, fd, MSFT_SEG_CUSTDATA )) return retval; + if (!ctl2_write_segment(typelib, fd, MSFT_SEG_CUSTDATAGUID)) return retval; + + ctl2_write_typeinfos(typelib, fd); + + if (close(fd) == -1) return retval; + + retval = S_OK; + return retval; +} + +int create_msft_typelib(typelib_t *typelib) +{ + msft_typelib_t *msft; + int failed = 0; + typelib_entry_t *entry; + time_t cur_time; + unsigned int version = 5 << 24 | 1 << 16 | 164; /* 5.01.0164 */ + GUID midl_time_guid = {0xde77ba63,0x517c,0x11d1,{0xa2,0xda,0x00,0x00,0xf8,0x77,0x3c,0xe9}}; + GUID midl_version_guid = {0xde77ba64,0x517c,0x11d1,{0xa2,0xda,0x00,0x00,0xf8,0x77,0x3c,0xe9}}; + + msft = malloc(sizeof(*msft)); + if (!msft) return 0; + memset(msft, 0, sizeof(*msft)); + msft->typelib = typelib; + + ctl2_init_header(msft); + ctl2_init_segdir(msft); + + msft->typelib_header.varflags |= SYS_WIN32; + + /* + * The following two calls return an offset or -1 if out of memory. We + * specifically need an offset of 0, however, so... + */ + if (ctl2_alloc_segment(msft, MSFT_SEG_GUIDHASH, 0x80, 0x80)) { failed = 1; } + if (ctl2_alloc_segment(msft, MSFT_SEG_NAMEHASH, 0x200, 0x200)) { failed = 1; } + + if(failed) return 0; + + msft->typelib_guidhash_segment = (int *)msft->typelib_segment_data[MSFT_SEG_GUIDHASH]; + msft->typelib_namehash_segment = (int *)msft->typelib_segment_data[MSFT_SEG_NAMEHASH]; + + memset(msft->typelib_guidhash_segment, 0xff, 0x80); + memset(msft->typelib_namehash_segment, 0xff, 0x200); + + set_lib_flags(msft); + set_lcid(msft); + set_help_file_name(msft); + set_doc_string(msft); + set_guid(msft); + set_version(msft); + set_name(msft); + set_help_context(msft); + set_help_string_dll(msft); + set_help_string_context(msft); + + /* midl adds two sets of custom data to the library: the current unix time + and midl's version number */ + cur_time = time(NULL); + set_custdata(msft, &midl_time_guid, VT_UI4, &cur_time, &msft->typelib_header.CustomDataOffset); + set_custdata(msft, &midl_version_guid, VT_UI4, &version, &msft->typelib_header.CustomDataOffset); + + for(entry = typelib->entry; entry && NEXT_LINK(entry); entry = NEXT_LINK(entry)) + ; + + for( ; entry; entry = PREV_LINK(entry)) + add_entry(msft, entry); + + save_all_changes(msft); + return 1; +}