From f215e02bf85f68d3a6106c2a1f4f7f063f819064 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Thu, 11 Apr 2024 10:17:27 +0200 Subject: Adding upstream version 7.0.14-dfsg. Signed-off-by: Daniel Baumann --- .../xpcom18a4/xpcom/typelib/xpt/tools/.cvsignore | 3 + .../xpcom18a4/xpcom/typelib/xpt/tools/Makefile.in | 90 ++ .../xpcom18a4/xpcom/typelib/xpt/tools/xpt_dump.c | 941 +++++++++++++++++++++ .../xpcom18a4/xpcom/typelib/xpt/tools/xpt_link.c | 883 +++++++++++++++++++ 4 files changed, 1917 insertions(+) create mode 100644 src/libs/xpcom18a4/xpcom/typelib/xpt/tools/.cvsignore create mode 100644 src/libs/xpcom18a4/xpcom/typelib/xpt/tools/Makefile.in create mode 100644 src/libs/xpcom18a4/xpcom/typelib/xpt/tools/xpt_dump.c create mode 100644 src/libs/xpcom18a4/xpcom/typelib/xpt/tools/xpt_link.c (limited to 'src/libs/xpcom18a4/xpcom/typelib/xpt/tools') diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpt/tools/.cvsignore b/src/libs/xpcom18a4/xpcom/typelib/xpt/tools/.cvsignore new file mode 100644 index 00000000..985cc7a7 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/typelib/xpt/tools/.cvsignore @@ -0,0 +1,3 @@ +Makefile +xpt_dump +xpt_link diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpt/tools/Makefile.in b/src/libs/xpcom18a4/xpcom/typelib/xpt/tools/Makefile.in new file mode 100644 index 00000000..bedece8e --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/typelib/xpt/tools/Makefile.in @@ -0,0 +1,90 @@ +# +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the terms of +# either of the GNU General Public License Version 2 or later (the "GPL"), +# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +DEPTH = ../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +MODULE = xpcom +INTERNAL_TOOLS = 1 + +SIMPLE_PROGRAMS = xpt_dump$(BIN_SUFFIX) xpt_link$(BIN_SUFFIX) + +CSRCS = xpt_dump.c xpt_link.c + +SDK_BINARY = \ + $(SIMPLE_PROGRAMS) \ + $(NULL) + +ifdef CROSS_COMPILE +HOST_SIMPLE_PROGRAMS = $(addprefix host_, $(SIMPLE_PROGRAMS:$(BIN_SUFFIX)=$(HOST_BIN_SUFFIX))) +HOST_CSRCS = $(CSRCS) +endif + +include $(topsrcdir)/config/rules.mk + +# Compile directly against the static lib, so we can use the tools +# during the build without the shared library path being set. +ifeq ($(OS_ARCH),WINNT) +DEFINES += -DEXPORT_XPT_API +endif + +LIBS = $(DIST)/lib/$(LIB_PREFIX)xpt.$(LIB_SUFFIX) + +# Tell the $(SIMPLE_PROGRAMS) target that we need to be recompiled +# when libxpt changes. +EXTRA_DEPS = $(wildcard $(DIST)/lib/$(LIB_PREFIX)xpt.*) + +ifdef CROSS_COMPILE +HOST_LIBS = $(DIST)/host/lib/libhostxpt.$(LIB_SUFFIX) +HOST_EXTRA_DEPS = $(wildcard $(DIST)/host/lib/libhostxpt.*) + +ifdef HOST_NSPR_MDCPUCFG +HOST_CFLAGS += -DMDCPUCFG=$(HOST_NSPR_MDCPUCFG) +endif +endif + + +# Build xpt_link and xpt_dump early. (libs creates .deps used by libs.) +export:: + @$(MAKE) libs + + + diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpt/tools/xpt_dump.c b/src/libs/xpcom18a4/xpcom/typelib/xpt/tools/xpt_dump.c new file mode 100644 index 00000000..8926b9c9 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/typelib/xpt/tools/xpt_dump.c @@ -0,0 +1,941 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * A utility for dumping the contents of a typelib file (.xpt) to screen + */ + +#include "xpt_xdr.h" +#include +#ifdef XP_MAC +#include +#include +#include "FullPath.h" +#else +#ifdef XP_OS2_EMX +#include +#endif +#include +#endif +#include +#include +#include "prprf.h" + +#define BASE_INDENT 3 + +static char *type_array[32] = + {"int8", "int16", "int32", "int64", + "uint8", "uint16", "uint32", "uint64", + "float", "double", "boolean", "char", + "wchar_t", "void", "reserved", "reserved", + "reserved", "reserved", "reserved", "reserved", + "reserved", "reserved", "reserved", "reserved", + "reserved", "reserved", "reserved", "reserved", + "reserved", "reserved", "reserved", "reserved"}; + +static char *ptype_array[32] = + {"int8 *", "int16 *", "int32 *", "int64 *", + "uint8 *", "uint16 *", "uint32 *", "uint64 *", + "float *", "double *", "boolean *", "char *", + "wchar_t *", "void *", "nsIID *", "DOMString *", + "string", "wstring", "Interface *", "InterfaceIs *", + "array", "string_s", "wstring_s", "UTF8String *", + "CString *", "AString *", "reserved", "reserved", + "reserved", "reserved", "reserved", "reserved"}; + +static char *rtype_array[32] = + {"int8 &", "int16 &", "int32 &", "int64 &", + "uint8 &", "uint16 &", "uint32 &", "uint64 &", + "float &", "double &", "boolean &", "char &", + "wchar_t &", "void &", "nsIID &", "DOMString &", + "string &", "wstring &", "Interface &", "InterfaceIs &", + "array &", "string_s &", "wstring_s &", "UTF8String &", + "CString &", "AString &", "reserved", "reserved", + "reserved", "reserved", "reserved", "reserved"}; + +PRBool param_problems = PR_FALSE; + +PRBool +XPT_DumpHeader(XPTCursor *cursor, XPTHeader *header, + const int indent, PRBool verbose_mode); + +PRBool +XPT_DumpAnnotations(XPTAnnotation *ann, const int indent, PRBool verbose_mode); + +PRBool +XPT_DumpInterfaceDirectoryEntry(XPTCursor *cursor, + XPTInterfaceDirectoryEntry *ide, + XPTHeader *header, const int indent, + PRBool verbose_mode); + +PRBool +XPT_DumpInterfaceDescriptor(XPTCursor *cursor, XPTInterfaceDescriptor *id, + XPTHeader *header, const int indent, + PRBool verbose_mode); + +PRBool +XPT_DumpMethodDescriptor(XPTHeader *header, XPTMethodDescriptor *md, + XPTInterfaceDescriptor *id, + const int indent, PRBool verbose_mode); +PRBool +XPT_GetStringForType(XPTHeader *header, XPTTypeDescriptor *td, + XPTInterfaceDescriptor *id, + char **type_string); + +PRBool +XPT_DumpXPTString(XPTString *str); + +PRBool +XPT_DumpParamDescriptor(XPTHeader *header, XPTParamDescriptor *pd, + XPTInterfaceDescriptor *id, + const int indent, PRBool verbose_mode, + PRBool is_result); + +PRBool +XPT_DumpTypeDescriptor(XPTTypeDescriptor *td, + XPTInterfaceDescriptor *id, + int indent, PRBool verbose_mode); + +PRBool +XPT_DumpConstDescriptor(XPTHeader *header, XPTConstDescriptor *cd, + XPTInterfaceDescriptor *id, + const int indent, PRBool verbose_mode); + +static void +xpt_dump_usage(char *argv[]) { + fprintf(stdout, "Usage: %s [-v] \n" + " -v verbose mode\n", argv[0]); +} + +#if defined(XP_MAC) && defined(XPIDL_PLUGIN) + +#define main xptdump_main +int xptdump_main(int argc, char *argv[]); + +#define get_file_length mac_get_file_length +extern size_t mac_get_file_length(const char* filename); + +#else /* !(XP_MAC && XPIDL_PLUGIN) */ + +static size_t get_file_length(const char* filename) +{ + struct stat file_stat; + if (stat(filename, &file_stat) != 0) { + perror("FAILED: get_file_length"); + exit(1); + } + return file_stat.st_size; +} + +#endif /* !(XP_MAC && XPIDL_PLUGIN) */ + +int +main(int argc, char **argv) +{ + PRBool verbose_mode = PR_FALSE; + XPTArena *arena; + XPTState *state; + XPTCursor curs, *cursor = &curs; + XPTHeader *header; + size_t flen; + char *name; + char *whole; + FILE *in; + int result = 1; + + switch (argc) { + case 2: + if (argv[1][0] == '-') { + xpt_dump_usage(argv); + return 1; + } + name = argv[1]; + flen = get_file_length(name); + in = fopen(name, "rb"); + break; + case 3: + verbose_mode = PR_TRUE; + if (argv[1][0] != '-' || argv[1][1] != 'v') { + xpt_dump_usage(argv); + return 1; + } + name = argv[2]; + flen = get_file_length(name); + in = fopen(name, "rb"); + break; + default: + xpt_dump_usage(argv); + return 1; + } + + if (!in) { + perror("FAILED: fopen"); + return 1; + } + + arena = XPT_NewArena(1024, sizeof(double), "main xpt_dump arena"); + if (!arena) { + perror("XPT_NewArena failed"); + return 1; + } + + /* after arena creation all exits via 'goto out' */ + + whole = XPT_MALLOC(arena, flen); + if (!whole) { + perror("FAILED: XPT_MALLOC for whole"); + goto out; + } + + if (flen > 0) { + size_t rv = fread(whole, 1, flen, in); + if (rv < flen) { + fprintf(stderr, "short read (%zd vs %zd)! ouch!\n", rv, flen); + goto out; + } + if (ferror(in) != 0 || fclose(in) != 0) + perror("FAILED: Unable to read typelib file.\n"); + + state = XPT_NewXDRState(XPT_DECODE, whole, flen); + if (!XPT_MakeCursor(state, XPT_HEADER, 0, cursor)) { + fprintf(stdout, "XPT_MakeCursor failed for %s\n", name); + goto out; + } + if (!XPT_DoHeader(arena, cursor, &header)) { + fprintf(stdout, + "DoHeader failed for %s. Is %s a valid .xpt file?\n", + name, name); + goto out; + } + + if (!XPT_DumpHeader(cursor, header, BASE_INDENT, verbose_mode)) { + perror("FAILED: XPT_DumpHeader"); + goto out; + } + + if (param_problems) { + fprintf(stdout, "\nWARNING: ParamDescriptors are present with " + "bad in/out/retval flag information.\n" + "These have been marked with 'XXX'.\n" + "Remember, retval params should always be marked as out!\n"); + } + + XPT_DestroyXDRState(state); + XPT_FREE(arena, whole); + + } else { + fclose(in); + perror("FAILED: file length <= 0"); + goto out; + } + + result = 0; + +out: + XPT_DestroyArena(arena); + return result; +} + +PRBool +XPT_DumpHeader(XPTCursor *cursor, XPTHeader *header, + const int indent, PRBool verbose_mode) +{ + int i; + + fprintf(stdout, "Header:\n"); + + if (verbose_mode) { + fprintf(stdout, "%*sMagic beans: ", indent, " "); + for (i=0; i<16; i++) { + fprintf(stdout, "%02x", header->magic[i]); + } + fprintf(stdout, "\n"); + if (strncmp((const char*)header->magic, XPT_MAGIC, 16) == 0) + fprintf(stdout, "%*s PASSED\n", indent, " "); + else + fprintf(stdout, "%*s FAILED\n", indent, " "); + } + fprintf(stdout, "%*sMajor version: %d\n", indent, " ", + header->major_version); + fprintf(stdout, "%*sMinor version: %d\n", indent, " ", + header->minor_version); + fprintf(stdout, "%*sNumber of interfaces: %d\n", indent, " ", + header->num_interfaces); + + if (verbose_mode) { + fprintf(stdout, "%*sFile length: %d\n", indent, " ", + header->file_length); + fprintf(stdout, "%*sData pool offset: %d\n\n", indent, " ", + header->data_pool); + } + + fprintf(stdout, "%*sAnnotations:\n", indent, " "); + if (!XPT_DumpAnnotations(header->annotations, indent*2, verbose_mode)) + return PR_FALSE; + + fprintf(stdout, "\nInterface Directory:\n"); + for (i=0; inum_interfaces; i++) { + if (verbose_mode) { + fprintf(stdout, "%*sInterface #%d:\n", indent, " ", i); + if (!XPT_DumpInterfaceDirectoryEntry(cursor, + &header->interface_directory[i], + header, indent*2, + verbose_mode)) { + return PR_FALSE; + } + } else { + if (!XPT_DumpInterfaceDirectoryEntry(cursor, + &header->interface_directory[i], + header, indent, + verbose_mode)) { + return PR_FALSE; + } + } + } + + return PR_TRUE; +} + +PRBool +XPT_DumpAnnotations(XPTAnnotation *ann, const int indent, PRBool verbose_mode) +{ + int i = -1; + XPTAnnotation *last; + int new_indent = indent + BASE_INDENT; + + do { + i++; + if (XPT_ANN_IS_PRIVATE(ann->flags)) { + if (verbose_mode) { + fprintf(stdout, "%*sAnnotation #%d is private.\n", + indent, " ", i); + } else { + fprintf(stdout, "%*sAnnotation #%d:\n", + indent, " ", i); + } + fprintf(stdout, "%*sCreator: ", new_indent, " "); + if (!XPT_DumpXPTString(ann->creator)) + return PR_FALSE; + fprintf(stdout, "\n"); + fprintf(stdout, "%*sPrivate Data: ", new_indent, " "); + if (!XPT_DumpXPTString(ann->private_data)) + return PR_FALSE; + fprintf(stdout, "\n"); + } else { + fprintf(stdout, "%*sAnnotation #%d is empty.\n", + indent, " ", i); + } + last = ann; + ann = ann->next; + } while (!XPT_ANN_IS_LAST(last->flags)); + + if (verbose_mode) { + fprintf(stdout, "%*sAnnotation #%d is the last annotation.\n", + indent, " ", i); + } + + return PR_TRUE; +} + +static void +print_IID(struct nsID *iid, FILE *file) +{ + fprintf(file, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", + (PRUint32) iid->m0, (PRUint32) iid->m1,(PRUint32) iid->m2, + (PRUint32) iid->m3[0], (PRUint32) iid->m3[1], + (PRUint32) iid->m3[2], (PRUint32) iid->m3[3], + (PRUint32) iid->m3[4], (PRUint32) iid->m3[5], + (PRUint32) iid->m3[6], (PRUint32) iid->m3[7]); + +} + +PRBool +XPT_DumpInterfaceDirectoryEntry(XPTCursor *cursor, + XPTInterfaceDirectoryEntry *ide, + XPTHeader *header, const int indent, + PRBool verbose_mode) +{ + int new_indent = indent + BASE_INDENT; + + if (verbose_mode) { + fprintf(stdout, "%*sIID: ", indent, " "); + print_IID(&ide->iid, stdout); + fprintf(stdout, "\n"); + + fprintf(stdout, "%*sName: %s\n", + indent, " ", ide->name); + fprintf(stdout, "%*sNamespace: %s\n", + indent, " ", ide->name_space ? ide->name_space : "none"); + fprintf(stdout, "%*sAddress of interface descriptor: %p\n", + indent, " ", ide->interface_descriptor); + + fprintf(stdout, "%*sDescriptor:\n", indent, " "); + + if (!XPT_DumpInterfaceDescriptor(cursor, ide->interface_descriptor, + header, new_indent, verbose_mode)) { + return PR_FALSE; + } + } else { + fprintf(stdout, "%*s- %s::%s (", indent, " ", + ide->name_space ? ide->name_space : "", ide->name); + print_IID(&ide->iid, stdout); + fprintf(stdout, "):\n"); + if (!XPT_DumpInterfaceDescriptor(cursor, ide->interface_descriptor, + header, new_indent, verbose_mode)) { + return PR_FALSE; + } + } + + return PR_TRUE; +} + +PRBool +XPT_DumpInterfaceDescriptor(XPTCursor *cursor, XPTInterfaceDescriptor *id, + XPTHeader *header, const int indent, + PRBool verbose_mode) +{ + XPTInterfaceDirectoryEntry *parent_ide; + int i; + int new_indent = indent + BASE_INDENT; + int more_indent = new_indent + BASE_INDENT; + + if (!id) { + fprintf(stdout, "%*s[Unresolved]\n", indent, " "); + return PR_TRUE; + } + + if (id->parent_interface) { + + parent_ide = &header->interface_directory[id->parent_interface - 1]; + + fprintf(stdout, "%*sParent: %s::%s\n", indent, " ", + parent_ide->name_space ? + parent_ide->name_space : "", + parent_ide->name); + } + + fprintf(stdout, "%*sFlags:\n", indent, " "); + + fprintf(stdout, "%*sScriptable: %s\n", new_indent, " ", + XPT_ID_IS_SCRIPTABLE(id->flags) ? "TRUE" : "FALSE"); + + fprintf(stdout, "%*sFunction: %s\n", new_indent, " ", + XPT_ID_IS_FUNCTION(id->flags) ? "TRUE" : "FALSE"); + + if (verbose_mode) { + if (id->parent_interface) { + fprintf(stdout, + "%*sIndex of parent interface (in data pool): %d\n", + indent, " ", id->parent_interface); + + } + } else { + } + + if (id->num_methods > 0) { + if (verbose_mode) { + fprintf(stdout, + "%*s# of Method Descriptors: %d\n", + indent, " ", id->num_methods); + } else { + fprintf(stdout, "%*sMethods:\n", indent, " "); + } + + for (i=0; inum_methods; i++) { + if (verbose_mode) { + fprintf(stdout, "%*sMethod #%d:\n", new_indent, " ", i); + if (!XPT_DumpMethodDescriptor(header, + &id->method_descriptors[i], id, + more_indent, verbose_mode)) { + return PR_FALSE; + } + } else { + if (!XPT_DumpMethodDescriptor(header, + &id->method_descriptors[i], id, + new_indent, verbose_mode)) { + return PR_FALSE; + } + } + } + } else { + fprintf(stdout, "%*sMethods:\n", indent, " "); + fprintf(stdout, "%*sNo Methods\n", new_indent, " "); + } + + if (id->num_constants > 0) { + if (verbose_mode) { + fprintf(stdout, + "%*s# of Constant Descriptors: %d\n", + indent, " ", id->num_constants); + } else { + fprintf(stdout, "%*sConstants:\n", indent, " "); + } + + for (i=0; inum_constants; i++) { + if (verbose_mode) { + fprintf(stdout, "%*sConstant #%d:\n", new_indent, " ", i); + if (!XPT_DumpConstDescriptor(header, + &id->const_descriptors[i], id, + more_indent, verbose_mode)) + return PR_FALSE; + } else { + if (!XPT_DumpConstDescriptor(header, + &id->const_descriptors[i], id, + new_indent, verbose_mode)) { + return PR_FALSE; + } + } + } + } else { + fprintf(stdout, "%*sConstants:\n", indent, " "); + fprintf(stdout, "%*sNo Constants\n", new_indent, " "); + } + + return PR_TRUE; +} + +PRBool +XPT_DumpMethodDescriptor(XPTHeader *header, XPTMethodDescriptor *md, + XPTInterfaceDescriptor *id, + const int indent, PRBool verbose_mode) +{ + int i; + int new_indent = indent + BASE_INDENT; + int more_indent = new_indent + BASE_INDENT; + + if (verbose_mode) { + fprintf(stdout, "%*sName: %s\n", indent, " ", md->name); + fprintf(stdout, "%*sIs Getter? ", indent, " "); + if (XPT_MD_IS_GETTER(md->flags)) + fprintf(stdout, "TRUE\n"); + else + fprintf(stdout, "FALSE\n"); + + fprintf(stdout, "%*sIs Setter? ", indent, " "); + if (XPT_MD_IS_SETTER(md->flags)) + fprintf(stdout, "TRUE\n"); + else + fprintf(stdout, "FALSE\n"); + + fprintf(stdout, "%*sIs NotXPCOM? ", indent, " "); + if (XPT_MD_IS_NOTXPCOM(md->flags)) + fprintf(stdout, "TRUE\n"); + else + fprintf(stdout, "FALSE\n"); + + fprintf(stdout, "%*sIs Constructor? ", indent, " "); + if (XPT_MD_IS_CTOR(md->flags)) + fprintf(stdout, "TRUE\n"); + else + fprintf(stdout, "FALSE\n"); + + fprintf(stdout, "%*sIs Hidden? ", indent, " "); + if (XPT_MD_IS_HIDDEN(md->flags)) + fprintf(stdout, "TRUE\n"); + else + fprintf(stdout, "FALSE\n"); + + fprintf(stdout, "%*s# of arguments: %d\n", indent, " ", md->num_args); + fprintf(stdout, "%*sParameter Descriptors:\n", indent, " "); + + for (i=0; inum_args; i++) { + fprintf(stdout, "%*sParameter #%d:\n", new_indent, " ", i); + + if (!XPT_DumpParamDescriptor(header, &md->params[i], id, + more_indent, verbose_mode, PR_FALSE)) + return PR_FALSE; + } + + fprintf(stdout, "%*sResult:\n", indent, " "); + if (!XPT_DumpParamDescriptor(header, md->result, id, new_indent, + verbose_mode, PR_TRUE)) { + return PR_FALSE; + } + } else { + char *param_type; + XPTParamDescriptor *pd; + + if (!XPT_GetStringForType(header, &md->result->type, id, ¶m_type)) { + return PR_FALSE; + } + fprintf(stdout, "%*s%c%c%c%c%c %s %s(", indent - 6, " ", + XPT_MD_IS_GETTER(md->flags) ? 'G' : ' ', + XPT_MD_IS_SETTER(md->flags) ? 'S' : ' ', + XPT_MD_IS_HIDDEN(md->flags) ? 'H' : ' ', + XPT_MD_IS_NOTXPCOM(md->flags) ? 'N' : ' ', + XPT_MD_IS_CTOR(md->flags) ? 'C' : ' ', + param_type, md->name); + for (i=0; inum_args; i++) { + if (i!=0) { + fprintf(stdout, ", "); + } + pd = &md->params[i]; + if (XPT_PD_IS_IN(pd->flags)) { + fprintf(stdout, "in"); + if (XPT_PD_IS_OUT(pd->flags)) { + fprintf(stdout, "out "); + if (XPT_PD_IS_RETVAL(pd->flags)) { + fprintf(stdout, "retval "); + } + if (XPT_PD_IS_SHARED(pd->flags)) { + fprintf(stdout, "shared "); + } + } else { + fprintf(stdout, " "); + if (XPT_PD_IS_DIPPER(pd->flags)) { + fprintf(stdout, "dipper "); + } + if (XPT_PD_IS_RETVAL(pd->flags)) { + fprintf(stdout, "retval "); + } + } + } else { + if (XPT_PD_IS_OUT(pd->flags)) { + fprintf(stdout, "out "); + if (XPT_PD_IS_RETVAL(pd->flags)) { + fprintf(stdout, "retval "); + } + if (XPT_PD_IS_SHARED(pd->flags)) { + fprintf(stdout, "shared "); + } + } else { + param_problems = PR_TRUE; + fprintf(stdout, "XXX "); + } + } + if (!XPT_GetStringForType(header, &pd->type, id, ¶m_type)) { + return PR_FALSE; + } + fprintf(stdout, "%s", param_type); + } + fprintf(stdout, ");\n"); + } + return PR_TRUE; +} + +PRBool +XPT_GetStringForType(XPTHeader *header, XPTTypeDescriptor *td, + XPTInterfaceDescriptor *id, + char **type_string) +{ + static char buf[128]; /* ugly non-reentrant use of static buffer! */ + PRBool isArray = PR_FALSE; + + int tag = XPT_TDP_TAG(td->prefix); + + if (tag == TD_ARRAY) { + isArray = PR_TRUE; + td = &id->additional_types[td->type.additional_type]; + tag = XPT_TDP_TAG(td->prefix); + } + + if (tag == TD_INTERFACE_TYPE) { + int idx = td->type.iface; + if (!idx || idx > header->num_interfaces) + *type_string = "UNKNOWN_INTERFACE"; + else + *type_string = header->interface_directory[idx-1].name; + } else if (XPT_TDP_IS_POINTER(td->prefix.flags)) { + if (XPT_TDP_IS_REFERENCE(td->prefix.flags)) + *type_string = rtype_array[tag]; + else + *type_string = ptype_array[tag]; + } else { + *type_string = type_array[tag]; + } + + if(isArray) { + sprintf(buf, "%s []", *type_string); + *type_string = buf; + } + + return PR_TRUE; +} + +PRBool +XPT_DumpXPTString(XPTString *str) +{ + int i; + for (i=0; ilength; i++) { + fprintf(stdout, "%c", str->bytes[i]); + } + return PR_TRUE; +} + +PRBool +XPT_DumpParamDescriptor(XPTHeader *header, XPTParamDescriptor *pd, + XPTInterfaceDescriptor *id, + const int indent, PRBool verbose_mode, + PRBool is_result) +{ + int new_indent = indent + BASE_INDENT; + + if (!XPT_PD_IS_IN(pd->flags) && + !XPT_PD_IS_OUT(pd->flags) && + (XPT_PD_IS_RETVAL(pd->flags) || + XPT_PD_IS_SHARED(pd->flags))) { + param_problems = PR_TRUE; + fprintf(stdout, "XXX\n"); + } else { + if (!XPT_PD_IS_IN(pd->flags) && !XPT_PD_IS_OUT(pd->flags)) { + if (is_result) { + if (XPT_TDP_TAG(pd->type.prefix) != TD_UINT32 && + XPT_TDP_TAG(pd->type.prefix) != TD_VOID) { + param_problems = PR_TRUE; + fprintf(stdout, "XXX\n"); + } + } else { + param_problems = PR_TRUE; + fprintf(stdout, "XXX\n"); + } + } + } + + fprintf(stdout, "%*sIn Param? ", indent, " "); + if (XPT_PD_IS_IN(pd->flags)) + fprintf(stdout, "TRUE\n"); + else + fprintf(stdout, "FALSE\n"); + + fprintf(stdout, "%*sOut Param? ", indent, " "); + if (XPT_PD_IS_OUT(pd->flags)) + fprintf(stdout, "TRUE\n"); + else + fprintf(stdout, "FALSE\n"); + + fprintf(stdout, "%*sRetval? ", indent, " "); + if (XPT_PD_IS_RETVAL(pd->flags)) + fprintf(stdout, "TRUE\n"); + else + fprintf(stdout, "FALSE\n"); + + fprintf(stdout, "%*sShared? ", indent, " "); + if (XPT_PD_IS_SHARED(pd->flags)) + fprintf(stdout, "TRUE\n"); + else + fprintf(stdout, "FALSE\n"); + + fprintf(stdout, "%*sDipper? ", indent, " "); + if (XPT_PD_IS_DIPPER(pd->flags)) + fprintf(stdout, "TRUE\n"); + else + fprintf(stdout, "FALSE\n"); + + + fprintf(stdout, "%*sType Descriptor:\n", indent, " "); + if (!XPT_DumpTypeDescriptor(&pd->type, id, new_indent, verbose_mode)) + return PR_FALSE; + + return PR_TRUE; +} + +PRBool +XPT_DumpTypeDescriptor(XPTTypeDescriptor *td, + XPTInterfaceDescriptor *id, + int indent, PRBool verbose_mode) +{ + int new_indent; + + if (XPT_TDP_TAG(td->prefix) == TD_ARRAY) { + fprintf(stdout, "%*sArray (size in arg %d and length in arg %d) of...\n", + indent, " ", td->argnum, td->argnum2); + td = &id->additional_types[td->type.additional_type]; + indent += BASE_INDENT; + } + + new_indent = indent + BASE_INDENT; + + fprintf(stdout, "%*sIs Pointer? ", indent, " "); + if (XPT_TDP_IS_POINTER(td->prefix.flags)) + fprintf(stdout, "TRUE\n"); + else + fprintf(stdout, "FALSE\n"); + + fprintf(stdout, "%*sIs Unique Pointer? ", indent, " "); + if (XPT_TDP_IS_UNIQUE_POINTER(td->prefix.flags)) + fprintf(stdout, "TRUE\n"); + else + fprintf(stdout, "FALSE\n"); + + fprintf(stdout, "%*sIs Reference? ", indent, " "); + if (XPT_TDP_IS_REFERENCE(td->prefix.flags)) + fprintf(stdout, "TRUE\n"); + else + fprintf(stdout, "FALSE\n"); + + fprintf(stdout, "%*sTag: %d\n", indent, " ", + XPT_TDP_TAG(td->prefix)); + + if (XPT_TDP_TAG(td->prefix) == TD_PSTRING_SIZE_IS || + XPT_TDP_TAG(td->prefix) == TD_PWSTRING_SIZE_IS) { + fprintf(stdout, "%*s - size in arg %d and length in arg %d\n", + indent, " ", td->argnum, td->argnum2); + } + + if (XPT_TDP_TAG(td->prefix) == TD_INTERFACE_TYPE) { + fprintf(stdout, "%*sInterfaceTypeDescriptor:\n", indent, " "); + fprintf(stdout, "%*sIndex of IDE: %d\n", new_indent, " ", + td->type.iface); + } + + if (XPT_TDP_TAG(td->prefix) == TD_INTERFACE_IS_TYPE) { + fprintf(stdout, "%*sInterfaceTypeDescriptor:\n", indent, " "); + fprintf(stdout, "%*sIndex of Method Argument: %d\n", new_indent, " ", + td->argnum); + } + + return PR_TRUE; +} + +PRBool +XPT_DumpConstDescriptor(XPTHeader *header, XPTConstDescriptor *cd, + XPTInterfaceDescriptor *id, + const int indent, PRBool verbose_mode) +{ + int new_indent = indent + BASE_INDENT; + char *const_type; +/* char *out; */ + PRUint32 uintout; + PRInt32 intout; + + if (verbose_mode) { + fprintf(stdout, "%*sName: %s\n", indent, " ", cd->name); + fprintf(stdout, "%*sType Descriptor: \n", indent, " "); + if (!XPT_DumpTypeDescriptor(&cd->type, id, new_indent, verbose_mode)) + return PR_FALSE; + fprintf(stdout, "%*sValue: ", indent, " "); + } else { + if (!XPT_GetStringForType(header, &cd->type, id, &const_type)) { + return PR_FALSE; + } + fprintf(stdout, "%*s%s %s = ", indent, " ", const_type, cd->name); + } + + switch(XPT_TDP_TAG(cd->type.prefix)) { + case TD_INT8: + fprintf(stdout, "%d", cd->value.i8); + break; + case TD_INT16: + fprintf(stdout, "%d", cd->value.i16); + break; + case TD_INT64: + /* XXX punt for now to remove NSPR linkage... + * borrow from mozilla/nsprpub/pr/src/io/prprf.c::cvt_ll? */ + +/* out = PR_smprintf("%lld", cd->value.i64); */ +/* fputs(out, stdout); */ +/* PR_smprintf_free(out); */ + LL_L2I(intout, cd->value.i64); + fprintf(stdout, "%d", intout); + break; + case TD_INT32: + fprintf(stdout, "%d", cd->value.i32); + break; + case TD_UINT8: + fprintf(stdout, "%u", cd->value.ui8); + break; + case TD_UINT16: + fprintf(stdout, "%u", cd->value.ui16); + break; + case TD_UINT64: +/* out = PR_smprintf("%lld", cd->value.ui64); */ +/* fputs(out, stdout); */ +/* PR_smprintf_free(out); */ + /* XXX punt for now to remove NSPR linkage. */ + LL_L2UI(uintout, cd->value.ui64); + fprintf(stdout, "%u", uintout); + break; + case TD_UINT32: + fprintf(stdout, "%u", cd->value.ui32); + break; + case TD_FLOAT: + fprintf(stdout, "%f", cd->value.flt); + break; + case TD_DOUBLE: + fprintf(stdout, "%g", cd->value.dbl); + break; + case TD_BOOL: + if (cd->value.bul) + fprintf(stdout, "TRUE"); + else + fprintf(stdout, "FALSE"); + break; + case TD_CHAR: + fprintf(stdout, "%c", cd->value.ch); + break; + case TD_WCHAR: + fprintf(stdout, "%c", cd->value.wch & 0xff); + break; + case TD_VOID: + fprintf(stdout, "VOID"); + break; + case TD_PNSIID: + if (XPT_TDP_IS_POINTER(cd->type.prefix.flags)) { + print_IID(cd->value.iid, stdout); + } else + return PR_FALSE; + break; + case TD_PSTRING: + if (XPT_TDP_IS_POINTER(cd->type.prefix.flags)) { + fprintf(stdout, "%s", cd->value.str); + } else + return PR_FALSE; + break; + case TD_PWSTRING: + if (XPT_TDP_IS_POINTER(cd->type.prefix.flags)) { + PRUint16 *ch = cd->value.wstr; + while (*ch) { + fprintf(stdout, "%c", *ch & 0xff); + ch++; + } + } else + return PR_FALSE; + break; + default: + perror("Unrecognized type"); + return PR_FALSE; + break; + } + + if (verbose_mode) { + fprintf(stdout, "\n"); + } else { + fprintf(stdout, ";\n"); + } + + return PR_TRUE; +} diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpt/tools/xpt_link.c b/src/libs/xpcom18a4/xpcom/typelib/xpt/tools/xpt_link.c new file mode 100644 index 00000000..872b96fd --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/typelib/xpt/tools/xpt_link.c @@ -0,0 +1,883 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * A utility for linking multiple typelib files. + */ + +#include "xpt_xdr.h" +#include +#ifdef XP_MAC +#include +#else +#include +#endif +#include +#include +#include "prlong.h" + +#ifndef NULL +#define NULL (void *) 0 +#endif + +/* Forward declarations. */ +typedef struct fixElement fixElement; +static int compare_IDEs_by_IID(const void *ap, const void *bp); +static int compare_IDE_with_zero(const void *ap); +static int compare_IDEs_by_name(const void *ap, const void *bp); +static int compare_IDEs_by_name_space(const void *ap, const void *bp); +static int compare_strings(const void *ap, const void *bp); +static int compare_pointers(const void *ap, const void *bp); +static int compare_fixElements_by_IID(const void *ap, const void *bp); +static int compare_fixElements_by_name(const void *ap, const void *bp); +static int compare_IIDs(const void *ap, const void *bp); +PRBool shrink_IDE_array(XPTInterfaceDirectoryEntry *ide, + int element_to_delete, int num_interfaces); +PRBool update_fix_array(XPTArena *arena, fixElement *fix, int element_to_delete, + int num_interfaces, int replacement); +static int get_new_index(const fixElement *fix, int num_elements, + int target_file, int target_interface); +PRBool copy_IDE(XPTInterfaceDirectoryEntry *from, + XPTInterfaceDirectoryEntry *to); +PRBool copy_fixElement(fixElement *from, fixElement *to); +static void print_IID(struct nsID *iid, FILE *file); +static void xpt_link_usage(char *argv[]); + +struct fixElement { + nsID iid; + char* name; + int file_num; + int interface_num; + PRBool is_deleted; + /* These next two variables will point you to the substitute interface + * if this one has been deleted. + */ + int maps_to_file_num; + int maps_to_interface_num; +}; + +/* Global variables. */ +PRUint16 trueNumberOfInterfaces = 0; +PRUint16 totalNumberOfInterfaces = 0; +PRUint16 oldTotalNumberOfInterfaces = 0; + +/* The following globals are explained in xpt_struct.h */ +PRUint8 major_version = XPT_MAJOR_VERSION; +PRUint8 minor_version = XPT_MINOR_VERSION; + +#if defined(XP_MAC) && defined(XPIDL_PLUGIN) + +#define main xptlink_main +int xptlink_main(int argc, char *argv[]); +extern size_t mac_get_file_length(const char* filename); +#define get_file_length mac_get_file_length + +#else + +static size_t get_file_length(const char* filename) +{ + struct stat file_stat; + if (stat(filename, &file_stat) != 0) { + perror("FAILED: get_file_length"); + exit(1); + } + return file_stat.st_size; +} + +#endif /* XP_MAC && XPIDL_PLUGIN */ + +int +main(int argc, char **argv) +{ + XPTArena *arena; + XPTState *state; + XPTCursor curs, *cursor = &curs; + XPTHeader *header; + XPTInterfaceDirectoryEntry *IDE_array = NULL; + XPTInterfaceDescriptor *id; + XPTTypeDescriptor *td; + XPTAnnotation *ann, *first_ann; + PRUint32 header_sz, len; + PRUint32 oldOffset; + PRUint32 newOffset; + size_t flen = 0; + char *head, *data, *whole; + const char *outFileName; + FILE *in, *out; + fixElement *fix_array = NULL; + int i,j; + int k = 0; + + if (argc < 3) { + xpt_link_usage(argv); + return 1; + } + + arena = XPT_NewArena(1024 * 10, sizeof(double), "main xpt_link arena"); + if (!arena) { + perror("FAILED: XPT_NewArena"); + return 1; + } + + first_ann = XPT_NewAnnotation(arena, XPT_ANN_LAST, NULL, NULL); + + /* Check if the "-t version numnber" cmd line arg is present */ + i = 1; + if (argv[i][0] == '-' && argv[i][1] == 't') { + /* Parse for "-t version number" */ + + /* If -t is the last argument on the command line, we have a problem */ + if (i + 1 == argc) { + fprintf(stderr, "ERROR: missing version number after -t\n"); + xpt_link_usage(argv); + return 1; + } + + /* + * Assume that the argument after "-t" is the version number string + * and search for it in our internal list of acceptable version + * numbers. + */ + + switch (XPT_ParseVersionString(argv[++i], &major_version, + &minor_version)) { + case XPT_VERSION_CURRENT: + case XPT_VERSION_OLD: + break; + case XPT_VERSION_UNSUPPORTED: + fprintf(stderr, "ERROR: version \"%s\" not supported.\n", + argv[i]); + xpt_link_usage(argv); + return 1; + case XPT_VERSION_UNKNOWN: + default: + fprintf(stderr, "ERROR: version \"%s\" not recognised.\n", + argv[i]); + xpt_link_usage(argv); + return 1; + } + + /* Hang onto the output file name. It's needed later. */ + outFileName = argv[++i]; + + /* Increment i to the cmd line arg after outFileName */ + i++; + } + else { + outFileName = argv[1]; + i = 2; + } + + for ( /* use i from earlier */ ; i < argc; i++) { + char *name = argv[i]; + + flen = get_file_length(name); + if (!flen) { + fprintf(stderr, "ERROR: file %s is zero length\n", name); + return 1; + } + + in = fopen(name, "rb"); + if (!in) { + perror("FAILED: fopen"); + return 1; + } + + whole = XPT_MALLOC(arena, flen); + if (!whole) { + perror("FAILED: XPT_MALLOC for whole"); + return 1; + } + + if (flen > 0) { + size_t rv = fread(whole, 1, flen, in); + if (rv < flen) { + fprintf(stderr, "short read (%zd vs %zd)! ouch!\n", rv, flen); + return 1; + } + if (ferror(in) != 0 || fclose(in) != 0) { + perror("FAILED: Unable to read typelib file.\n"); + return 1; + } + + state = XPT_NewXDRState(XPT_DECODE, whole, flen); + if (!XPT_MakeCursor(state, XPT_HEADER, 0, cursor)) { + fprintf(stdout, "XPT_MakeCursor failed for %s\n", name); + return 1; + } + if (!XPT_DoHeader(arena, cursor, &header)) { + fprintf(stdout, + "DoHeader failed for %s. Is %s a valid .xpt file?\n", + name, name); + return 1; + } + + /* + * Make sure that the version of the typelib file is less than or + * equal to the version specified in the -t cmd line arg. + */ + + if (header && + (header->major_version > major_version || + (header->major_version == major_version && + header->minor_version > minor_version))) { + fprintf(stderr, "FAILED: %s's version, %d.%d, is newer than " + "the version (%d.%d) specified in the -t " + "command line argument.\n", + name, header->major_version, header->minor_version, + major_version, minor_version); + return 1; + } + + oldTotalNumberOfInterfaces = totalNumberOfInterfaces; + totalNumberOfInterfaces += header->num_interfaces; + if (header->num_interfaces > 0) { + XPTInterfaceDirectoryEntry *newIDE; + fixElement *newFix; + + newIDE = (XPTInterfaceDirectoryEntry *) + XPT_MALLOC(arena, totalNumberOfInterfaces * + sizeof(XPTInterfaceDirectoryEntry)); + if (!newIDE) { + perror("FAILED: XPT_MALLOC of IDE_array"); + return 1; + } + + if (IDE_array) { + if (oldTotalNumberOfInterfaces) + memcpy(newIDE, IDE_array, + oldTotalNumberOfInterfaces * + sizeof(XPTInterfaceDirectoryEntry)); + XPT_FREE(arena, IDE_array); + } + IDE_array = newIDE; + + + newFix = (fixElement *) + XPT_MALLOC(arena, + totalNumberOfInterfaces * sizeof(fixElement)); + if (!newFix) { + perror("FAILED: XPT_MALLOC of fix_array"); + return 1; + } + + if (fix_array) { + if (oldTotalNumberOfInterfaces) + memcpy(newFix, fix_array, + oldTotalNumberOfInterfaces * + sizeof(fixElement)); + XPT_FREE(arena, fix_array); + } + fix_array = newFix; + + for (j=0; jnum_interfaces; j++) { + if (!copy_IDE(&header->interface_directory[j], + &IDE_array[k])) { + perror("FAILED: 1st copying of IDE"); + return 1; + } + fix_array[k].iid = IDE_array[k].iid; + fix_array[k].name = IDE_array[k].name; + fix_array[k].file_num = i-2; + fix_array[k].interface_num = j+1; + fix_array[k].is_deleted = PR_FALSE; + fix_array[k].maps_to_file_num = i-2; + fix_array[k].maps_to_interface_num = j+1; + + k++; + } + } + + /* Copy the annotations if they are not 'empty' + */ + if (header->annotations != NULL && + header->annotations->flags != XPT_ANN_LAST) { + ann = first_ann; + while (ann->next != NULL) { + ann = ann->next; + } + ann->next = header->annotations; + } + + XPT_FREEIF(arena, header); + if (state) + XPT_DestroyXDRState(state); + XPT_FREE(arena, whole); + flen = 0; + + } else { + fclose(in); + perror("FAILED: file length <= 0"); + return 1; + } + } + + /* Make sure the last annotation is the only one marked as XP_ANN_LAST. + */ + ann = first_ann; + while (ann->next != NULL) { + ann->flags &= ~XPT_ANN_LAST; + ann = ann->next; + } + ann->flags |= XPT_ANN_LAST; + + /* Sort both IDE_array and fix_array by name so we can check for + * name_space::name collisions. + */ + qsort(IDE_array, + totalNumberOfInterfaces, + sizeof(XPTInterfaceDirectoryEntry), + compare_IDEs_by_name); + + qsort(fix_array, + totalNumberOfInterfaces, + sizeof(fixElement), + compare_fixElements_by_name); + + /* trueNumberOfInterfaces == number of interfaces left after deletions + * are made. Initialize it here to be the same as the total number of + * interfaces we'ce encountered thus far. + */ + trueNumberOfInterfaces = totalNumberOfInterfaces; + + /* Iterate through the sorted interfaces. Start at one so we don't + * accidentally walk off the end of the array. + */ + i = 1; + while (i != trueNumberOfInterfaces) { + + /* Check for name_space::name collision. + */ + if (compare_strings(IDE_array[i-1].name, + IDE_array[i].name) == 0 && + compare_strings(IDE_array[i-1].name_space, + IDE_array[i].name_space) == 0) { + + /* If one of the interfaces is unresolved, delete that one + * preferentailly. + */ + if (!IDE_array[i-1].interface_descriptor) { + /* Shrink the IDE_array to delete the duplicate interface. + */ + if (!shrink_IDE_array(IDE_array, + i-1, + trueNumberOfInterfaces)) { + perror("FAILED: shrink_IDE_array"); + return 1; + } + /* Update the fix array. This involves moving the deleted + * entry to the end of the array (rather than deleting it) + * and mapping it to the "replacement" element so we can + * update interface indices appropriately later. + */ + update_fix_array(arena, fix_array, i-1, + totalNumberOfInterfaces, i); + /* Decrement the true number of interfaces since we just + * deleted one. There's more than one way to get out of + * this loop. + */ + trueNumberOfInterfaces--; + } else { + if (!IDE_array[i].interface_descriptor || + (compare_IIDs(&IDE_array[i-1].iid, &IDE_array[i].iid) == 0)) + { + /* Shrink the IDE_array to delete the duplicate interface. + */ + if (!shrink_IDE_array(IDE_array, + i, + trueNumberOfInterfaces)) { + perror("FAILED: shrink_IDE_array"); + return 1; + } + /* Update the fix array. This involves moving the deleted + * entry to the end of the array (rather than deleting it) + * and mapping it to the "replacement" element so we can + * update interface indices appropriately later. + */ + update_fix_array(arena, fix_array, i, + totalNumberOfInterfaces, i-1); + /* Decrement the true number of interfaces since we just + * deleted one. There's more than one way to get out of + * this loop. + */ + trueNumberOfInterfaces--; + } else { + /* Found interfaces with duplicate names but different + * iids! */ + char *ns = IDE_array[i].name_space; + fprintf(stderr, + "ERROR: found duplicate definitions of interface " + "%s%s%s with iids \n", + ns ? ns : "", ns ? "::" : "", IDE_array[i].name); + print_IID(&IDE_array[i].iid, stderr); + fprintf(stderr, " and "); + print_IID(&IDE_array[i-1].iid, stderr); + fprintf(stderr, "\n"); + return 1; + } + } + } else { + /* Only increment if there was no name_space::name collision. + */ + i++; + } + } + + /* Sort the IDE_array (put them in their final order) so that updating + * of indices will be meaningful. + */ + qsort(IDE_array, + trueNumberOfInterfaces, + sizeof(XPTInterfaceDirectoryEntry), + compare_IDEs_by_IID); + + /* Sort the fix_array to match the IDE_array. + */ + qsort(fix_array, + trueNumberOfInterfaces, + sizeof(fixElement), + compare_fixElements_by_IID); + + /* Iterate through the remaining interfaces (those not deleted) + * looking for references to interfaces (such as id->parent_interface) + * which need an updated index number. + */ + for (i=0; iparent_interface && id->parent_interface != 0) { + id->parent_interface = + get_new_index(fix_array, totalNumberOfInterfaces, + fix_array[i].file_num, id->parent_interface); + } + /* Iterate through the method descriptors looking for params of + * type TD_INTERFACE_TYPE. + */ + for (j=0; jnum_methods; j++) { + /* Cycle through the params first. + */ + for (k=0; kmethod_descriptors[j].num_args; k++) { + /* Define td to save some keystrokes. + */ + td = &id->method_descriptors[j].params[k].type; + + while (XPT_TDP_TAG(td->prefix) == TD_ARRAY) { + td = &id->additional_types[td->type.additional_type]; + } + + if (XPT_TDP_TAG(td->prefix) == TD_INTERFACE_TYPE) { + td->type.iface = + get_new_index(fix_array, + totalNumberOfInterfaces, + fix_array[i].file_num, + td->type.iface); + } + } + + /* Check the result param too. Define td again to save + * some keystrokes. + */ + td = &id->method_descriptors[j].result->type; + if (XPT_TDP_TAG(td->prefix) == TD_INTERFACE_TYPE) { + td->type.iface = + get_new_index(fix_array, totalNumberOfInterfaces, + fix_array[i].file_num, + td->type.iface); + } + } + } + } + + /* Iterate through the array quickly looking for duplicate IIDS. + * This shouldn't happen, i.e. is a failure condition, so bail + * if we find a duplicate. If we have more than one entry, start + * at one so we don't accidentally grep the ether. + */ + if (trueNumberOfInterfaces>1) { + for (i=1; iannotations = first_ann; + for (i=0; iinterface_directory[i])) { + perror("FAILED: 2nd copying of IDE"); + return 1; + } + } + + header_sz = XPT_SizeOfHeaderBlock(header); + + state = XPT_NewXDRState(XPT_ENCODE, NULL, 0); + if (!state) { + perror("FAILED: error creating XDRState"); + return 1; + } + + XPT_SetDataOffset(state, header_sz); + + if (!XPT_MakeCursor(state, XPT_HEADER, header_sz, cursor)) { + perror("FAILED: error making cursor"); + return 1; + } + oldOffset = cursor->offset; + if (!XPT_DoHeader(arena, cursor, &header)) { + perror("FAILED: error doing Header"); + return 1; + } + newOffset = cursor->offset; + XPT_GetXDRDataLength(state, XPT_HEADER, &len); + header->file_length = len; + XPT_GetXDRDataLength(state, XPT_DATA, &len); + header->file_length += len; + XPT_SeekTo(cursor, oldOffset); + if (!XPT_DoHeaderPrologue(arena, cursor, &header, NULL)) { + perror("FAILED: error doing Header"); + return 1; + } + XPT_SeekTo(cursor, newOffset); + out = fopen(outFileName, "wb"); + if (!out) { + perror("FAILED: fopen"); + return 1; + } + + XPT_GetXDRData(state, XPT_HEADER, &head, &len); + fwrite(head, len, 1, out); + + XPT_GetXDRData(state, XPT_DATA, &data, &len); + fwrite(data, len, 1, out); + + if (ferror(out) != 0 || fclose(out) != 0) { + fprintf(stderr, "Error writing file: %s\n", argv[1]); + } else { +/* fprintf(stderr, "File written: %s\n", argv[1]); */ + } + + if (state) + XPT_DestroyXDRState(state); + + XPT_DestroyArena(arena); + + return 0; +} + +static int +compare_IDEs_by_IID(const void *ap, + const void *bp) +{ + const XPTInterfaceDirectoryEntry *ide1 = ap, *ide2 = bp; + + int answer = compare_IIDs(&ide1->iid, &ide2->iid); + if(!answer) + answer = compare_strings(ide1->name, ide2->name); + + return answer; +} + +/* For detecting unresolved interfaces. */ +const nsID iid_zero = { 0x0, 0x0, 0x0, + { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } }; + +static int +compare_IDE_with_zero(const void *ap) +{ + const XPTInterfaceDirectoryEntry *ide1 = ap; + + return compare_IIDs(&ide1->iid, &iid_zero); +} + +static int +compare_fixElements_by_IID(const void *ap, + const void *bp) +{ + const fixElement *fix1 = ap, *fix2 = bp; + + int answer = compare_IIDs(&fix1->iid, &fix2->iid); + if(!answer) + answer = compare_strings(fix1->name, fix2->name); + + return answer; +} + +static int +compare_IDEs_by_name(const void *ap, + const void *bp) +{ + const XPTInterfaceDirectoryEntry *ide1 = ap, *ide2 = bp; + + int answer = compare_strings(ide1->name, ide2->name); + if(!answer) + answer = compare_pointers(ide1->name, ide2->name); + + return answer; +} + +static int +compare_IDEs_by_name_space(const void *ap, + const void *bp) +{ + const XPTInterfaceDirectoryEntry *ide1 = ap, *ide2 = bp; + + return compare_strings(ide1->name_space, ide2->name_space); +} + +static int +compare_strings(const void *ap, const void *bp) +{ + const char *string1 = ap, *string2 = bp; + + if (!string1 && !string2) + return 0; + if (!string1) + return -1; + if (!string2) + return 1; + + return strcmp(string1, string2); +} + +static int +compare_pointers(const void *ap, const void *bp) +{ + if (ap == bp) { +#ifdef DEBUG_jband + perror("name addresses were equal!"); +#endif + return 0; + } + if (ap > bp) + return 1; + return -1; +} + +static int +compare_fixElements_by_name(const void *ap, + const void *bp) +{ + const fixElement *fix1 = ap, *fix2 = bp; + + int answer= compare_strings(fix1->name, fix2->name); + if(!answer) + answer = compare_pointers(fix1->name, fix2->name); + + return answer; +} + +static int +compare_IIDs(const void *ap, const void *bp) +{ + const nsID *a = ap, *b = bp; + int i; +#define COMPARE(field) if (a->field > b->field) return 1; \ + if (b->field > a->field) return -1; + COMPARE(m0); + COMPARE(m1); + COMPARE(m2); + for (i = 0; i < 8; i++) { + COMPARE(m3[i]); + } + return 0; +#undef COMPARE +} + +PRBool +shrink_IDE_array(XPTInterfaceDirectoryEntry *ide, int element_to_delete, + int num_interfaces) +{ + int i; + + if (element_to_delete >= num_interfaces) { + return PR_FALSE; + } + + for (i=element_to_delete+1; i= num_interfaces) { + return PR_FALSE; + } + + deleted = XPT_CALLOC(arena, sizeof(fixElement)); + if (!copy_fixElement(&fix[element_to_delete], deleted)) { + return PR_FALSE; + } + deleted->is_deleted = PR_TRUE; + deleted->maps_to_file_num = fix[replacement].file_num; + deleted->maps_to_interface_num = fix[replacement].interface_num; + + for (i=element_to_delete+1; iiid = from->iid; + to->name = from->name; + to->name_space = from->name_space; + to->interface_descriptor = from->interface_descriptor; + return PR_TRUE; +} + +PRBool +copy_fixElement(fixElement *from, fixElement *to) +{ + if (!from || !to) { + return PR_FALSE; + } + + to->iid = from->iid; + to->name = from->name; + to->file_num = from->file_num; + to->interface_num = from->interface_num; + to->is_deleted = from->is_deleted; + to->maps_to_file_num = from->maps_to_file_num; + to->maps_to_interface_num = from->maps_to_interface_num; + + return PR_TRUE; +} + +static void +print_IID(struct nsID *iid, FILE *file) +{ + fprintf(file, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", + (PRUint32) iid->m0, (PRUint32) iid->m1,(PRUint32) iid->m2, + (PRUint32) iid->m3[0], (PRUint32) iid->m3[1], + (PRUint32) iid->m3[2], (PRUint32) iid->m3[3], + (PRUint32) iid->m3[4], (PRUint32) iid->m3[5], + (PRUint32) iid->m3[6], (PRUint32) iid->m3[7]); +} + +static void +xpt_link_usage(char *argv[]) +{ + fprintf(stdout, "Usage: %s [-t version number] outfile file1.xpt file2.xpt ...\n" + " Links multiple typelib files into one outfile\n" + " -t create a typelib of an older version number\n", argv[0]); +} + -- cgit v1.2.3