summaryrefslogtreecommitdiffstats
path: root/src/libs/xpcom18a4/xpcom/typelib
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/.cvsignore1
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/Makefile.in49
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpidl/.cvsignore2
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpidl/Makefile.in88
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpidl/README16
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/compiler.rsrcbin0 -> 915 bytes
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/linker.rsrcbin0 -> 984 bytes
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_console.c139
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_console.h49
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_memory.cpp146
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_stdlib.cpp58
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_strings.cpp38
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_strings.h47
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_xpidl.cpp417
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_xpidl.h25
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_xpidl_panel.cpp695
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_xpidl_panel.h106
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_xpt_linker.cpp546
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/panel.rsrcbin0 -> 16238 bytes
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/version.rsrcbin0 -> 755 bytes
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpidl/xpidl.c275
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpidl/xpidl.h278
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpidl/xpidl_doc.c312
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpidl/xpidl_header.c1196
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpidl/xpidl_idl.c836
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpidl/xpidl_java.c1053
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpidl/xpidl_typelib.c1237
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpidl/xpidl_util.c851
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpt/.cvsignore1
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpt/Makefile.in50
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpt/public/.cvsignore1
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpt/public/Makefile.in51
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpt/public/xpt_arena.h145
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpt/public/xpt_struct.h562
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpt/public/xpt_xdr.h240
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpt/src/.cvsignore1
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpt/src/Makefile.in76
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpt/src/xpt_arena.c358
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpt/src/xpt_struct.c956
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpt/src/xpt_xdr.c665
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpt/tests/.cvsignore3
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpt/tests/Makefile.in59
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpt/tests/PrimitiveTest.c157
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpt/tests/SimpleTypeLib.c192
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpt/tools/.cvsignore3
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpt/tools/Makefile.in90
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpt/tools/xpt_dump.c941
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpt/tools/xpt_link.c883
48 files changed, 13894 insertions, 0 deletions
diff --git a/src/libs/xpcom18a4/xpcom/typelib/.cvsignore b/src/libs/xpcom18a4/xpcom/typelib/.cvsignore
new file mode 100644
index 00000000..f3c7a7c5
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/src/libs/xpcom18a4/xpcom/typelib/Makefile.in b/src/libs/xpcom18a4/xpcom/typelib/Makefile.in
new file mode 100644
index 00000000..43d92023
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/Makefile.in
@@ -0,0 +1,49 @@
+#
+# ***** 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
+DIRS = xpt xpidl
+
+include $(topsrcdir)/config/rules.mk
+
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpidl/.cvsignore b/src/libs/xpcom18a4/xpcom/typelib/xpidl/.cvsignore
new file mode 100644
index 00000000..8e5eac0d
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpidl/.cvsignore
@@ -0,0 +1,2 @@
+xpidl
+Makefile
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpidl/Makefile.in b/src/libs/xpcom18a4/xpcom/typelib/xpidl/Makefile.in
new file mode 100644
index 00000000..ae228ef0
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpidl/Makefile.in
@@ -0,0 +1,88 @@
+#
+# The contents of this file are subject to the Netscape 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/NPL/
+#
+# 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 Netscape are
+# Copyright (C) 1998 Netscape Communications Corporation. All
+# Rights Reserved.
+#
+# Contributor(s):
+#
+
+DEPTH = ../../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE = xpcom
+PROGRAM = xpidl$(BIN_SUFFIX)
+INTERNAL_TOOLS = 1
+
+# glib and libIDL link against the non-debug msvcrt
+MOZ_NO_DEBUG_RTL=1
+
+CSRCS = \
+ xpidl.c \
+ xpidl_idl.c \
+ xpidl_util.c \
+ xpidl_header.c \
+ xpidl_typelib.c \
+ xpidl_doc.c \
+ xpidl_java.c \
+ $(NULL)
+
+SDK_BINARY = \
+ $(PROGRAM) \
+ $(NULL)
+
+ifdef CROSS_COMPILE
+HOST_PROGRAM = host_xpidl$(HOST_BIN_SUFFIX)
+HOST_CSRCS = $(CSRCS)
+endif
+
+include $(topsrcdir)/config/rules.mk
+
+CFLAGS += $(LIBIDL_CFLAGS)
+
+# Compile directly against the static lib, so we can use xpidl during the build
+# without the shared library path being set.
+ifeq (WINNT,$(OS_ARCH))
+DEFINES += -DEXPORT_XPT_API
+ifndef GNU_CC
+LDFLAGS += -SUBSYSTEM:CONSOLE -NODEFAULTLIB:MSVCRTD
+endif
+endif
+
+# Tell the $(PROGRAM) target that we need to be recompiled when libxpt changes.
+LIBS = $(DIST)/lib/$(LIB_PREFIX)xpt.$(LIB_SUFFIX) $(LIBIDL_LIBS)
+EXTRA_DEPS = $(wildcard $(DIST)/lib/$(LIB_PREFIX)xpt.*)
+
+ifdef CROSS_COMPILE
+HOST_CFLAGS += $(HOST_LIBIDL_CFLAGS)
+HOST_LIBS = $(DIST)/host/lib/libhostxpt.$(LIB_SUFFIX) $(HOST_LIBIDL_LIBS)
+HOST_EXTRA_DEPS = $(wildcard $(DIST)/host/lib/libhostxpt.*)
+
+ifdef HOST_NSPR_MDCPUCFG
+HOST_CFLAGS += -DMDCPUCFG=$(HOST_NSPR_MDCPUCFG)
+endif
+endif
+
+ifdef MACOS_SDK_DIR
+NEXT_ROOT=
+OS_LIBS := $(patsubst -L$(MACOS_SDK_DIR)/usr/lib%,,$(OS_LIBS))
+endif
+
+export::
+ @$(MAKE) libs
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpidl/README b/src/libs/xpcom18a4/xpcom/typelib/xpidl/README
new file mode 100644
index 00000000..b7a400e0
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpidl/README
@@ -0,0 +1,16 @@
+Wed Dec 2 14:35:41 EST 1998
+
+xpidl depends on Andrew Veliath and Elliot Lee's libIDL, a part of the
+GNOME ORBit C ORB. We currently require libIDL >= 0.6.3, which in turn
+requires glib >= 1.2.0.
+
+libIDL builds for Linux and Win32 can be found, along with source
+tarballs, at http://www.rpi.edu/~veliaa/libIDL/, and Win32 users will
+need glib 1.2 and glib 1.2-dev from
+http://user.sgic.fi/~tml/gimp/win32/. Source and Linux RPMs are also
+available from ftp://ftp.mozilla.org/pub/mozilla/libraries, and Win32
+binaries are included in the wintools.zip file at
+ftp://ftp.mozilla.org/pub/mozilla/source/wintools.zip. A Mac project
+is in progress, and should be appearing shortly.
+
+glib tarballs and RPMs for Linux can be found through http://www.gtk.org.
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/compiler.rsrc b/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/compiler.rsrc
new file mode 100644
index 00000000..fb06f6a3
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/compiler.rsrc
Binary files differ
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/linker.rsrc b/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/linker.rsrc
new file mode 100644
index 00000000..bec7c043
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/linker.rsrc
Binary files differ
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_console.c b/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_console.c
new file mode 100644
index 00000000..ecda11e0
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_console.c
@@ -0,0 +1,139 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: NPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Netscape 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/NPL/
+ *
+ * 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 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 NPL, 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 NPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "mac_console.h"
+
+#ifndef __CONSOLE__
+#include <console.h>
+#endif
+
+extern CWPluginContext gPluginContext;
+
+UInt32 mac_console_count = 0;
+CWMemHandle mac_console_handle = NULL;
+
+/*
+ * The following four functions provide the UI for the console package.
+ * Users wishing to replace SIOUX with their own console package need
+ * only provide the four functions below in a library.
+ */
+
+/*
+ * extern short InstallConsole(short fd);
+ *
+ * Installs the Console package, this function will be called right
+ * before any read or write to one of the standard streams.
+ *
+ * short fd: The stream which we are reading/writing to/from.
+ * returns short: 0 no error occurred, anything else error.
+ */
+
+short InstallConsole(short fd)
+{
+#pragma unused (fd)
+ mac_console_count = 0;
+ CWAllocMemHandle(gPluginContext, 8192, false, &mac_console_handle);
+ return 0;
+}
+
+/*
+ * extern void RemoveConsole(void);
+ *
+ * Removes the console package. It is called after all other streams
+ * are closed and exit functions (installed by either atexit or _atexit)
+ * have been called. Since there is no way to recover from an error,
+ * this function doesn't need to return any.
+ */
+
+void RemoveConsole(void)
+{
+ if (mac_console_handle != NULL) {
+ CWFreeMemHandle(gPluginContext, mac_console_handle);
+ mac_console_handle = NULL;
+ }
+}
+
+/*
+ * extern long WriteCharsToConsole(char *buffer, long n);
+ *
+ * Writes a stream of output to the Console window. This function is
+ * called by write.
+ *
+ * char *buffer: Pointer to the buffer to be written.
+ * long n: The length of the buffer to be written.
+ * returns short: Actual number of characters written to the stream,
+ * -1 if an error occurred.
+ */
+
+long WriteCharsToConsole(char *buffer, long n)
+{
+ long size = 0;
+ void* ptr = NULL;
+
+ if (CWGetMemHandleSize(gPluginContext, mac_console_handle, &size) == noErr) {
+ if (mac_console_count + n >= size) {
+ size += 8192;
+ if (CWResizeMemHandle(gPluginContext, mac_console_handle, size) != noErr)
+ return -1;
+ }
+ }
+
+ if (CWLockMemHandle(gPluginContext, mac_console_handle, false, &ptr) == noErr) {
+ BlockMoveData(buffer, (char *)ptr + mac_console_count, n);
+ mac_console_count += n;
+ CWUnlockMemHandle(gPluginContext, mac_console_handle);
+ }
+
+ return 0;
+}
+
+/*
+ * extern long ReadCharsFromConsole(char *buffer, long n);
+ *
+ * Reads from the Console into a buffer. This function is called by
+ * read.
+ *
+ * char *buffer: Pointer to the buffer which will recieve the input.
+ * long n: The maximum amount of characters to be read (size of
+ * buffer).
+ * returns short: Actual number of characters read from the stream,
+ * -1 if an error occurred.
+ */
+
+long ReadCharsFromConsole(char *buffer, long n)
+{
+ return 0;
+}
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_console.h b/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_console.h
new file mode 100644
index 00000000..88809f85
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_console.h
@@ -0,0 +1,49 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: NPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Netscape 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/NPL/
+ *
+ * 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 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 NPL, 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 NPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ mac_console.h
+ */
+
+#pragma once
+
+#include <Files.h>
+#include <Memory.h>
+
+#include "CWPlugins.h"
+
+extern UInt32 mac_console_count;
+extern CWMemHandle mac_console_handle;
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_memory.cpp b/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_memory.cpp
new file mode 100644
index 00000000..41d03d88
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_memory.cpp
@@ -0,0 +1,146 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: NPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Netscape 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/NPL/
+ *
+ * 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 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 NPL, 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 NPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ mac_memory.cpp
+ */
+
+#include <new.h>
+#include <stdlib.h>
+
+#include <Files.h>
+#include <Memory.h>
+
+#include "DropInCompilerLinker.h"
+#include "CompilerMapping.h"
+#include "CWPluginErrors.h"
+
+extern CWPluginContext gPluginContext;
+
+/**
+ * Note: memory allocated by these operators will automatically be freed after the
+ * current call into xpidl_compiler completes. This should be fine in most cases,
+ * as we are also having the compiler be reloaded for every request to reinitialize
+ * global data. Just be careful out there!
+ */
+
+const Boolean kTemporaryAllocation = false;
+
+void* operator new(size_t size)
+{
+ void* ptr = NULL;
+ if (CWAllocateMemory(gPluginContext, size, kTemporaryAllocation, &ptr) == cwNoErr)
+ return ptr;
+ return NULL;
+}
+
+void operator delete(void* ptr)
+{
+ if (ptr != NULL)
+ CWFreeMemory(gPluginContext, ptr, kTemporaryAllocation);
+}
+
+void* operator new[] (size_t size)
+{
+ void* ptr = NULL;
+ if (CWAllocateMemory(gPluginContext, size, kTemporaryAllocation, &ptr) == cwNoErr)
+ return ptr;
+ return NULL;
+}
+
+void operator delete[](void* ptr)
+{
+ if (ptr != NULL)
+ CWFreeMemory(gPluginContext, ptr, kTemporaryAllocation);
+}
+
+namespace std {
+
+#define TRACK_ALLOCATION
+#define kTrackedCookie 'TRKD'
+
+void* malloc(size_t size)
+{
+#if defined(TRACK_ALLOCATION)
+ OSType* ptr = (OSType*) new char[sizeof(OSType) + size];
+ if (ptr != NULL)
+ *ptr++ = kTrackedCookie;
+ return ptr;
+#else
+ return new char[size];
+#endif
+}
+
+void free(void *ptr)
+{
+#if defined(TRACK_ALLOCATION)
+ OSType* type = (OSType*)ptr;
+ if (*--type == kTrackedCookie)
+ delete[] (char*) type;
+ else
+ DebugStr("\pillegal block passed to free.");
+#else
+ delete[] (char*) ptr;
+#endif
+}
+
+void* calloc(size_t nmemb, size_t size)
+{
+ size *= nmemb;
+ void* ptr = malloc(size);
+ if (ptr != NULL) {
+ BlockZero(ptr, size);
+ }
+ return ptr;
+}
+
+void* realloc(void * ptr, size_t size)
+{
+ void* newptr = NULL;
+
+ if (size > 0)
+ newptr = malloc(size);
+
+ if (ptr != NULL && newptr != NULL)
+ BlockMoveData(ptr, newptr, size);
+
+ if (ptr != NULL)
+ free(ptr);
+
+ return newptr;
+}
+
+}
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_stdlib.cpp b/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_stdlib.cpp
new file mode 100644
index 00000000..881dcb0b
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_stdlib.cpp
@@ -0,0 +1,58 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: NPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Netscape 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/NPL/
+ *
+ * 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 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 NPL, 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 NPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ mac_stdlib.cpp
+
+ replacement functions for the CodeWarrior plugin.
+
+ by Patrick C. Beard.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <setjmp.h>
+
+// simply throw us out of here!
+
+jmp_buf exit_jump;
+int exit_status = 0;
+
+void std::exit(int status)
+{
+ exit_status = status;
+ longjmp(exit_jump, -1);
+}
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_strings.cpp b/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_strings.cpp
new file mode 100644
index 00000000..37e389e5
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_strings.cpp
@@ -0,0 +1,38 @@
+/*
+ mac_strings.cpp
+ */
+
+#include "mac_strings.h"
+
+#include <string.h>
+#include <Memory.h>
+#include <new>
+
+StringPtr c2p_strcpy(StringPtr pstr, const char* cstr)
+{
+ size_t len = ::strlen(cstr);
+ if (len > 255) len = 255;
+ BlockMoveData(cstr, pstr + 1, len);
+ pstr[0] = len;
+ return pstr;
+}
+
+char* p2c_strcpy(char* cstr, const StringPtr pstr)
+{
+ size_t len = pstr[0];
+ BlockMoveData(pstr + 1, cstr, len);
+ cstr[len] = '\0';
+ return cstr;
+}
+
+char* p2c_strdup(StringPtr pstr)
+{
+ size_t len = pstr[0];
+ char* cstr = new char[1 + len];
+ if (cstr != NULL) {
+ BlockMoveData(pstr + 1, cstr, len);
+ cstr[len] = '\0';
+ }
+ return cstr;
+}
+
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_strings.h b/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_strings.h
new file mode 100644
index 00000000..44f39312
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_strings.h
@@ -0,0 +1,47 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: NPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Netscape 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/NPL/
+ *
+ * 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 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 NPL, 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 NPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ mac_strings.h
+ */
+
+#pragma once
+
+#include <MacTypes.h>
+
+StringPtr c2p_strcpy(StringPtr pstr, const char* cstr);
+char* p2c_strcpy(char* cstr, const StringPtr pstr);
+char* p2c_strdup(StringPtr pstr);
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_xpidl.cpp b/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_xpidl.cpp
new file mode 100644
index 00000000..49f061d9
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_xpidl.cpp
@@ -0,0 +1,417 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: NPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Netscape 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/NPL/
+ *
+ * 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 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 NPL, 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 NPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ mac_xpidl.cpp
+
+ Metrowerks Codewarrior IDL plugin.
+
+ by Patrick C. Beard.
+ */
+
+/* standard headers */
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <new.h>
+#include <setjmp.h>
+
+/* system headers */
+#include <Files.h>
+#include <Errors.h>
+#include <Strings.h>
+
+#include "FullPath.h"
+#include "MoreFilesExtras.h"
+
+/* compiler headers */
+#include "DropInCompilerLinker.h"
+#include "CompilerMapping.h"
+#include "CWPluginErrors.h"
+
+/* local headers. */
+#include "mac_xpidl.h"
+#include "mac_console.h"
+#include "mac_strings.h"
+#include "mac_xpidl_panel.h"
+
+/* prototypes of local functions */
+static CWResult Compile(CWPluginContext context);
+static CWResult Disassemble(CWPluginContext context);
+static CWResult LocateFile(CWPluginContext context, const char* filename, FSSpec& file);
+
+/* external variables */
+extern jmp_buf exit_jump;
+extern int exit_status;
+
+/* global variables */
+CWPluginContext gPluginContext;
+
+/* local variables */
+static CWFileSpec gSourceFile;
+static char* gSourcePath = NULL;
+static CWFileSpec gOutputFile;
+
+extern "C" {
+pascal short xpidl_compiler(CWPluginContext context);
+int xpidl_main(int argc, char* argv[]);
+int xptdump_main(int argc, char* argv[]);
+
+FILE * FSp_fopen(ConstFSSpecPtr spec, const char * open_mode);
+}
+
+pascal short xpidl_compiler(CWPluginContext context)
+{
+ long request;
+ if (CWGetPluginRequest(context, &request) != cwNoErr)
+ return cwErrRequestFailed;
+
+ gPluginContext = context;
+ short result = cwNoErr;
+
+ /* dispatch on compiler request */
+ switch (request) {
+ case reqInitCompiler:
+ /* compiler has just been loaded into memory */
+ break;
+
+ case reqTermCompiler:
+ /* compiler is about to be unloaded from memory */
+ break;
+
+ case reqCompile:
+ /* compile a source file */
+ result = Compile(context);
+ break;
+
+ case reqCompDisassemble:
+ /* disassemble a source file */
+ result = Disassemble(context);
+ break;
+
+ default:
+ result = cwErrRequestFailed;
+ break;
+ }
+
+ /* is this necessary? */
+ CWDonePluginRequest(context, result);
+
+ /* return result code */
+ return (result);
+}
+
+static char* full_path_to(const FSSpec& file)
+{
+ short len = 0;
+ Handle fullPath = NULL;
+ if (FSpGetFullPath(&file, &len, &fullPath) == noErr && fullPath != NULL) {
+ char* path = new char[1 + len];
+ if (path != NULL) {
+ BlockMoveData(*fullPath, path, len);
+ path[len] = '\0';
+ }
+ DisposeHandle(fullPath);
+ return path;
+ }
+ return NULL;
+}
+
+static CWResult GetSettings(CWPluginContext context, XPIDLSettings& settings)
+{
+ CWMemHandle settingsHand;
+ CWResult err = CWGetNamedPreferences(context, kXPIDLPanelName, &settingsHand);
+ if (!CWSUCCESS(err))
+ return (err);
+
+ XPIDLSettings* settingsPtr = NULL;
+ err = CWLockMemHandle(context, settingsHand, false, (void**)&settingsPtr);
+ if (!CWSUCCESS(err))
+ return (err);
+
+ settings = *settingsPtr;
+
+ err = CWUnlockMemHandle(context, settingsHand);
+ if (!CWSUCCESS(err))
+ return (err);
+
+ return noErr;
+}
+
+static CWResult Compile(CWPluginContext context)
+{
+ CWResult err = CWGetMainFileSpec(context, &gSourceFile);
+ if (!CWSUCCESS(err))
+ return (err);
+
+ long fileNum;
+ err = CWGetMainFileNumber(context, &fileNum);
+ if (!CWSUCCESS(err))
+ return (err);
+
+ // get the name of the source file to compile.
+ gSourcePath = p2c_strdup(gSourceFile.name);
+ if (gSourcePath == NULL)
+ return cwErrOutOfMemory;
+
+ // build an argument list and call the compiler.
+ XPIDLSettings settings = { kXPIDLSettingsVersion, kXPIDLModeHeader, false, false };
+ GetSettings(context, settings);
+
+#if 0
+ // if generating .xpt files, let the IDE tell us where to put the output file.
+ // otherwise, put them in the project's output directory.
+ if (settings.mode == kXPIDLModeTypelib)
+ err = CWGetSuggestedObjectFileSpec(context, fileNum, &gOutputFile);
+ else
+ err = CWGetOutputFileDirectory(gPluginContext, &gOutputFile);
+#else
+ // always generate the output file into the project target's data directory.
+ err = CWGetSuggestedObjectFileSpec(context, fileNum, &gOutputFile);
+#endif
+ if (!CWSUCCESS(err))
+ return (err);
+
+ int argc = 3;
+ char* modes[] = { "header", "java", "typelib", "doc" };
+ char* argv[] = { "xpidl", "-m", modes[settings.mode - 1], NULL, NULL, NULL, NULL, };
+ if (settings.warnings) argv[argc++] = "-w";
+ if (settings.verbose) argv[argc++] = "-v";
+ argv[argc++] = gSourcePath;
+
+ if (setjmp(exit_jump) == 0) {
+ if (xpidl_main(argc, argv) != 0)
+ err = cwErrRequestFailed;
+ } else {
+ // evidently the good old exit function got called.
+ if (exit_status != 0)
+ err = cwErrRequestFailed;
+ }
+
+ // if the compilation succeeded, tell CodeWarrior about the output file.
+ // this ensures several things: 1. if the output file is deleted by the user,
+ // then the IDE will know to recompile it, which is good for dirty builds,
+ // where the output files may be hand deleted; 2. if the user elects to remove
+ // objects, the output files are deleted. Thanks to robv@metrowerks.com for
+ // pointing this new CWPro4 API out.
+ if (err == cwNoErr) {
+ CWObjectData objectData;
+ BlockZero(&objectData, sizeof(objectData));
+
+ // for fun, show how large the output file is in the data area.
+ long dataSize, rsrcSize;
+ if (FSpGetFileSize(&gOutputFile, &dataSize, &rsrcSize) == noErr)
+ objectData.idatasize = dataSize;
+
+ // tell the IDE that this file was generated by the compiler.
+ objectData.objectfile = &gOutputFile;
+
+ err = CWStoreObjectData(context, fileNum, &objectData);
+ } else {
+ // an error occured, delete the output file, which might be a partial file.
+ if (gOutputFile.name[0] != 0) {
+ ::FSpDelete(&gOutputFile);
+ }
+ }
+
+ delete[] gSourcePath;
+ gSourcePath = NULL;
+
+ return (err);
+}
+
+static CWResult Disassemble(CWPluginContext context)
+{
+ // the disassembly code has moved to the linker.
+ return noErr;
+}
+
+static CWResult LocateFile(CWPluginContext context, const char* filename, FSSpec& file)
+{
+ /* prefill the CWFileInfo struct */
+ CWFileInfo fileinfo;
+ BlockZero(&fileinfo, sizeof(fileinfo));
+ // memset(&fileinfo, 0, sizeof(fileinfo));
+ fileinfo.fullsearch = true;
+ fileinfo.suppressload = true;
+ fileinfo.dependencyType = cwNormalDependency;
+ fileinfo.isdependentoffile = kCurrentCompiledFile;
+
+ /* locate the file name using the project's access paths */
+ CWResult err = CWFindAndLoadFile(context, filename, &fileinfo);
+ if (err == cwNoErr) {
+ file = fileinfo.filespec;
+ } else if (err == cwErrFileNotFound) {
+ char errmsg[200];
+ sprintf(errmsg, "Can't locate file \"%s\".", filename);
+ CWResult callbackResult = CWReportMessage(context, 0, errmsg, 0, messagetypeError, 0);
+ }
+
+ return (err);
+}
+
+/**
+ * Substitute for standard fopen, treats certain filenames specially,
+ * and also considers the mode argument. If a file is being opened
+ * for reading, the file is assumed to be locateable using CodeWarrior's
+ * standard access paths. If it's for writing, the file is opened in
+ * the current project's output directory.
+ */
+FILE* std::fopen(const char* filename, const char *mode)
+{
+ FSSpec filespec;
+ CWResult err = noErr;
+ do {
+ if (filename == gSourcePath || strcmp(filename, gSourcePath) == 0) {
+ // opening the main source file.
+ filespec = gSourceFile;
+ } else if (mode[0] == 'w') {
+ // if an output file, open it in the current compilation's output directory.
+ c2p_strcpy(filespec.name, filename);
+ filespec.vRefNum = gOutputFile.vRefNum;
+ filespec.parID = gOutputFile.parID;
+ c2p_strcpy(gOutputFile.name, filename);
+ } else {
+ // an input file, use CodeWarrior's search paths to find the named source file.
+ err = LocateFile(gPluginContext, filename, filespec);
+ }
+ } while (0);
+ // if all went well, we have a file to open.
+ return (err == noErr ? FSp_fopen(&filespec, mode) : NULL);
+}
+
+/**
+ * Returns the length of a file, assuming it is always located in the
+ * project's output directory.
+ */
+size_t mac_get_file_length(const char* filename)
+{
+ long dataSize= 0, rsrcSize = 0;
+ FSSpec filespec;
+ if (CWGetOutputFileDirectory(gPluginContext, &filespec) != noErr)
+ return 0;
+ c2p_strcpy(filespec.name, filename);
+ if (FSpGetFileSize(&filespec, &dataSize, &rsrcSize) != noErr)
+ return 0;
+ return dataSize;
+}
+
+void mac_warning(const char* warning_message)
+{
+ CWReportMessage(gPluginContext, 0, warning_message, 0, messagetypeWarning, 0);
+}
+
+void mac_error(const char* error_message)
+{
+ CWReportMessage(gPluginContext, 0, error_message, 0, messagetypeError, 0);
+}
+
+// plugin compiler exports.
+
+#if CW_USE_PRAGMA_EXPORT
+#pragma export on
+#endif
+
+CWPLUGIN_ENTRY(CWPlugin_GetDropInFlags)(const DropInFlags** flags, long* flagsSize)
+{
+ static const DropInFlags sFlags = {
+ kCurrentDropInFlagsVersion,
+ CWDROPINCOMPILERTYPE,
+ DROPINCOMPILERLINKERAPIVERSION,
+ (kGeneratescode | /* kCandisassemble | */ kCompMultiTargAware | kCompAlwaysReload),
+ Lang_MISC,
+ DROPINCOMPILERLINKERAPIVERSION
+ };
+
+ *flags = &sFlags;
+ *flagsSize = sizeof(sFlags);
+
+ return cwNoErr;
+}
+
+CWPLUGIN_ENTRY(CWPlugin_GetDropInName)(const char** dropinName)
+{
+ static const char* sDropInName = "xpidl";
+
+ *dropinName = sDropInName;
+
+ return cwNoErr;
+}
+
+CWPLUGIN_ENTRY(CWPlugin_GetDisplayName)(const char** displayName)
+{
+ static const char* sDisplayName = "xpidl";
+
+ *displayName = sDisplayName;
+
+ return cwNoErr;
+}
+
+CWPLUGIN_ENTRY(CWPlugin_GetPanelList)(const CWPanelList** panelList)
+{
+ static const char* sPanelName = kXPIDLPanelName;
+ static CWPanelList sPanelList = { kCurrentCWPanelListVersion, 1, &sPanelName };
+
+ *panelList = &sPanelList;
+
+ return cwNoErr;
+}
+
+CWPLUGIN_ENTRY(CWPlugin_GetTargetList)(const CWTargetList** targetList)
+{
+ static CWDataType sCPU = '****';
+ static CWDataType sOS = '****';
+ static CWTargetList sTargetList = { kCurrentCWTargetListVersion, 1, &sCPU, 1, &sOS };
+
+ *targetList = &sTargetList;
+
+ return cwNoErr;
+}
+
+CWPLUGIN_ENTRY(CWPlugin_GetDefaultMappingList)(const CWExtMapList** defaultMappingList)
+{
+ static CWExtensionMapping sExtension = { 'TEXT', ".idl", 0 };
+ static CWExtMapList sExtensionMapList = { kCurrentCWExtMapListVersion, 1, &sExtension };
+
+ *defaultMappingList = &sExtensionMapList;
+
+ return cwNoErr;
+}
+
+#if CW_USE_PRAGMA_EXPORT
+#pragma export off
+#endif
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_xpidl.h b/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_xpidl.h
new file mode 100644
index 00000000..bb1c5048
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_xpidl.h
@@ -0,0 +1,25 @@
+/*
+ mac_xpidl.h
+
+ prototypes for the Mac CodeWarrior plugin version of xpidl.
+
+ by Patrick C. Beard.
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _STDIO_H
+#include <stdio.h>
+#endif
+
+size_t mac_get_file_length(const char* filename);
+void mac_warning(const char* warning_message);
+void mac_error(const char* error_message);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_xpidl_panel.cpp b/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_xpidl_panel.cpp
new file mode 100644
index 00000000..b046071d
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_xpidl_panel.cpp
@@ -0,0 +1,695 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: NPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Netscape 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/NPL/
+ *
+ * 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 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 NPL, 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 NPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ mac_xpidl_panel.cpp
+ */
+
+#define CW_STRICT_DIALOGS 1
+
+/* standard headers */
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+/* system headers */
+#include <AERegistry.h>
+#include <Drag.h>
+#include <Palettes.h>
+#include <Resources.h>
+#include <Scrap.h>
+#include <TextUtils.h>
+#include <Sound.h>
+
+/* compiler headers */
+#include <DropInPanel.h>
+
+/* project headers */
+#include "mac_xpidl_panel.h"
+
+enum {
+ kFactoryPrefsID = 128,
+ kCW7ItemListID = 128,
+ kCW8ItemListID = 129,
+
+ kXPIDLModeItem = 1,
+ kXPIDLWarningsItem,
+ kXPIDLVerboseItem,
+
+ kXPTLinkerOutputItem = 4
+};
+
+
+/* local variables */
+static RgnHandle sDragRgn;
+static Boolean sHighlightOn;
+
+
+/* prototypes of local functions */
+static short InitDialog(PanelParameterBlock *pb);
+static void TermDialog(PanelParameterBlock *pb);
+static void PutData(PanelParameterBlock *pb, Handle options);
+static short GetData(PanelParameterBlock *pb, Handle options, Boolean noisy);
+static void ByteSwapData(XPIDLSettingsHandle options);
+static short Filter(PanelParameterBlock *pb, EventRecord *event, short *itemHit);
+static void ItemHit(PanelParameterBlock *pb);
+static void Validate(Handle original, Handle current, Boolean *recompile, Boolean *relink, Boolean *reset);
+static short GetPref(AEKeyword keyword, AEDesc *prefsDesc, Handle settings);
+static short SetPref(AEKeyword keyword, const AEDesc *prefsDesc, Handle settings);
+static short GetFactory(Handle settings);
+static short UpdatePref(Handle settings);
+static Boolean ComparePrefs(Handle prefsHand1, Handle prefsHand2);
+static Boolean ComparePrefs(XPIDLSettings& prefs1, XPIDLSettings& prefs2);
+static void OutlineRect(const Rect* focusRect, Boolean outlineOn);
+static OSErr DragEnter(PanelParameterBlock *pb);
+static void DragWithin(PanelParameterBlock *pb);
+static void DragExit(PanelParameterBlock *pb);
+static void DragDrop(PanelParameterBlock *pb);
+
+extern "C" {
+
+pascal short xpidl_panel(PanelParameterBlock *pb);
+
+}
+
+/*
+ * main - entry-point for Drop-In Preferences Panel
+ *
+ */
+
+pascal short xpidl_panel(PanelParameterBlock *pb)
+{
+ short result;
+
+ result = noErr;
+
+ switch (pb->request)
+ {
+ case reqInitPanel:
+ /* panel has just been loaded into memory */
+ break;
+
+ case reqTermPanel:
+ /* panel is about to be unloaded from memory */
+ break;
+
+ case reqFirstLoad:
+ /* first time panel was loaded. */
+ break;
+
+ case reqInitDialog:
+ /* hook our dialog item list into the preferences dialog */
+ result = InitDialog(pb);
+ break;
+
+ case reqTermDialog:
+ /* unhook our dialog item list from the preferences dialog */
+ TermDialog(pb);
+ break;
+
+ case reqPutData:
+ /* put the data in the given handle into our dialog items */
+ PutData(pb, pb->currentPrefs);
+ break;
+
+ case reqGetData:
+ /* fill in the given handle with our dialog items */
+ result = GetData(pb, pb->currentPrefs, true);
+ break;
+
+ case reqByteSwapData:
+ /* byte swap the data in the handle */
+ ByteSwapData((XPIDLSettingsHandle)pb->currentPrefs);
+ break;
+
+ case reqFilter:
+ /* filter an event in the dialog */
+ result = Filter(pb, pb->event, &pb->itemHit);
+ break;
+
+ case reqItemHit:
+ /* handle a hit on one of our dialog items */
+ ItemHit(pb);
+ break;
+
+ case reqDrawCustomItem:
+ /* handle a request to draw one of our user items (CW/8 and later) */
+ break;
+
+ case reqActivateItem:
+ break;
+
+ case reqDeactivateItem:
+ break;
+
+ case reqHandleKey:
+ break;
+
+ case reqHandleClick:
+ break;
+
+ case reqFindStatus:
+ break;
+
+ case reqObeyCommand:
+ break;
+
+ case reqAEGetPref:
+ /* return one item in the given handle as an Apple Event descriptor */
+ result = GetPref(pb->prefsKeyword, &pb->prefsDesc, pb->currentPrefs);
+ break;
+
+ case reqAESetPref:
+ /* change one item in the given handle according to the given Apple Event descriptor */
+ result = SetPref(pb->prefsKeyword, &pb->prefsDesc, pb->currentPrefs);
+ break;
+
+ case reqValidate:
+ /* determine if we need to reset paths, recompile, or relink */
+ Validate(pb->originalPrefs, pb->currentPrefs, &pb->recompile, &pb->relink, &pb->reset);
+ break;
+
+ case reqGetFactory:
+ /* return our factory settings */
+ result = GetFactory(pb->factoryPrefs);
+ break;
+
+ case reqUpdatePref:
+ /* update the given handle to use the current format for our prefs data */
+ result = UpdatePref(pb->currentPrefs);
+ break;
+
+ case reqDragEnter:
+ /* determine if we can accept the drag and, if so, start tracking */
+ result = DragEnter(pb);
+ break;
+
+ case reqDragWithin:
+ /* continue tracking */
+ DragWithin(pb);
+ break;
+
+ case reqDragExit:
+ /* stop tracking */
+ DragExit(pb);
+ break;
+
+ case reqDragDrop:
+ /* the user has dropped in our panel */
+ DragDrop(pb);
+ break;
+
+ default:
+ result = paramErr;
+ break;
+ }
+
+ return (result);
+}
+
+/*
+ * InitDialog - initialize Dialog Box items for this panel
+ *
+ */
+
+static short InitDialog(PanelParameterBlock *pb)
+{
+ OSErr err;
+
+ // The library function will call the IDE to append the dialog items
+ // if possible; else it will call AppendDITL itself. This way, you
+ // don't have to worry about it.
+
+ err = CWPanlAppendItems(pb, kCW8ItemListID);
+ if (err != noErr)
+ return (err);
+
+ sDragRgn = NewRgn();
+
+ return (err);
+}
+
+/*
+ * TermDialog - destroy Dialog Box items for this panel
+ *
+ */
+
+static void TermDialog(PanelParameterBlock *pb)
+{
+ DisposeRgn(sDragRgn);
+}
+
+inline Boolean hasLinkerOutput(short mode)
+{
+ return (mode == kXPIDLModeHeader || mode == kXPIDLModeTypelib);
+}
+
+/*
+ * PutData - copy the options data from the handle to the screen
+ *
+ */
+
+static void PutData(PanelParameterBlock *pb, Handle options)
+{
+ // make sure the options are the right size.
+ UpdatePref(options);
+
+ XPIDLSettings prefsData = **(XPIDLSettingsHandle) options;
+
+ CWPanlSetItemValue(pb, kXPIDLModeItem, prefsData.mode);
+ CWPanlSetItemValue(pb, kXPIDLWarningsItem, prefsData.warnings);
+ CWPanlSetItemValue(pb, kXPIDLVerboseItem, prefsData.verbose);
+
+ CWPanlEnableItem(pb, kXPTLinkerOutputItem, hasLinkerOutput(prefsData.mode));
+ CWPanlSetItemText(pb, kXPTLinkerOutputItem, prefsData.output);
+}
+
+/*
+ * GetData - copy the options data from screen to the handle
+ *
+ */
+
+static short GetData(PanelParameterBlock *pb, Handle options, Boolean noisy)
+{
+ XPIDLSettings prefsData = **(XPIDLSettingsHandle) options;
+ long mode, warnings, verbose;
+
+ CWPanlGetItemValue(pb, kXPIDLModeItem, &mode);
+ CWPanlGetItemValue(pb, kXPIDLWarningsItem, &warnings);
+ CWPanlGetItemValue(pb, kXPIDLVerboseItem, &verbose);
+
+ prefsData.mode = (short) mode;
+ prefsData.warnings = (Boolean) warnings;
+ prefsData.verbose = (Boolean) verbose;
+
+ CWPanlGetItemText(pb, kXPTLinkerOutputItem, prefsData.output, sizeof(Str32));
+
+ ** (XPIDLSettingsHandle) options = prefsData;
+
+ return (noErr);
+}
+
+static void ByteSwapShort(short* x)
+{
+ union {
+ short s;
+ char c[2];
+ } from,to;
+
+ from.s=*x;
+ to.c[0]=from.c[1];
+ to.c[1]=from.c[0];
+ *x = to.s;
+}
+
+/*
+ * ByteSwapData - byte-swap the options data
+ *
+ */
+
+static void ByteSwapData(XPIDLSettingsHandle options)
+{
+ ByteSwapShort(&(**options).version);
+ ByteSwapShort(&(**options).mode);
+}
+
+/*
+ * Filter - filter an event for the Preferences panel
+ *
+ */
+static short Filter(PanelParameterBlock *pb, EventRecord *event, short *itemHit)
+{
+#pragma unused(pb, event, itemHit)
+
+ return (noErr);
+}
+
+/*
+ * ItemHit - handle an itemHit in a Preferences panel
+ *
+ */
+
+static void ItemHit(PanelParameterBlock *pb)
+{
+ short theItem = pb->itemHit - pb->baseItems;
+ long oldValue;
+
+ switch (theItem) {
+ case kXPIDLModeItem:
+ CWPanlGetItemValue(pb, theItem, &oldValue);
+ CWPanlEnableItem(pb, kXPTLinkerOutputItem, hasLinkerOutput(oldValue));
+ break;
+
+ case kXPIDLWarningsItem:
+ case kXPIDLVerboseItem:
+ CWPanlGetItemValue(pb, theItem, &oldValue);
+ break;
+ }
+
+ GetData(pb, pb->currentPrefs, false);
+
+ pb->canRevert = !ComparePrefs(pb->originalPrefs, pb->currentPrefs);
+ pb->canFactory = !ComparePrefs(pb->factoryPrefs, pb->currentPrefs);
+}
+
+/*
+ * Validate - check if panel's changes require a recompile or relink
+ *
+ */
+
+static void Validate(Handle original, Handle current, Boolean *recompile, Boolean *relink, Boolean *reset)
+{
+#pragma unused(original, current)
+ XPIDLSettings& origSettings = **(XPIDLSettingsHandle) original;
+ XPIDLSettings& currentSettings = **(XPIDLSettingsHandle) current;
+
+ *recompile = currentSettings.mode != origSettings.mode;
+ *relink = *recompile && hasLinkerOutput(currentSettings.mode);
+ *reset = false;
+}
+
+/*
+ * GetPref - get a specified Preference setting for an AppleEvent request
+ *
+ */
+static short GetPref(AEKeyword keyword, AEDesc *prefsDesc, Handle settings)
+{
+#if 0
+ XPIDLSettings prefsData = ** (XPIDLSettingsHandle) settings;
+ DescType anEnum;
+ OSErr err;
+
+ switch (keyword) {
+ case prefsLN_GenerateSymFile:
+ err = AECreateDesc(typeBoolean, &prefsData.linksym, sizeof(Boolean), prefsDesc);
+ break;
+
+ case prefsPR_ProjectType:
+ switch (prefsData.projtype)
+ {
+ case kProjTypeApplication: anEnum = enum_Project_Application; break;
+ case kProjTypeLibrary: anEnum = enum_Project_Library; break;
+ case kProjTypeSharedLib: anEnum = enum_Project_SharedLibrary; break;
+ case kProjTypeCodeResource: anEnum = enum_Project_CodeResource; break;
+ case kProjTypeMPWTool: anEnum = enum_Project_MPWTool; break;
+ default: return (paramErr);
+ }
+ err = AECreateDesc(typeEnumeration, &anEnum, sizeof(anEnum), prefsDesc);
+ break;
+
+ case prefsPR_FileName:
+ err = AECreateDesc(typeChar, prefsData.outfile+1, StrLength(prefsData.outfile), prefsDesc);
+ break;
+
+ default:
+ err = errAECantHandleClass;
+ break;
+ }
+
+ return (err);
+#else
+ return (errAECantHandleClass);
+#endif
+}
+
+/*
+ * SetPref - set a specified Preference setting from an AppleEvent request
+ *
+ */
+
+static short SetPref(AEKeyword keyword, const AEDesc *prefsDesc, Handle settings)
+{
+#if 0
+ XPIDLSettings prefsData = ** (XPIDLSettingsHandle) settings;
+ AEDesc toDesc = { typeNull, NULL };
+ OSErr err = noErr;
+ Handle dataHand;
+ Size textLength;
+ DescType anEnum;
+
+ switch (keyword)
+ {
+ case prefsLN_GenerateSymFile:
+ if (prefsDesc->descriptorType == typeBoolean)
+ {
+ dataHand = prefsDesc->dataHandle;
+ }
+ else
+ {
+ err = AECoerceDesc(prefsDesc, typeBoolean, &toDesc);
+ if (err == noErr)
+ dataHand = toDesc.dataHandle;
+ }
+ if (err == noErr)
+ {
+ prefsData.linksym = ** (Boolean **) dataHand;
+ }
+ break;
+
+ case prefsPR_ProjectType:
+ if (prefsDesc->descriptorType != typeEnumeration)
+ {
+ err = errAETypeError;
+ break;
+ }
+
+ anEnum = ** (DescType **) prefsDesc->dataHandle;
+
+ switch (anEnum)
+ {
+ case enum_Project_Application: prefsData.projtype = kProjTypeApplication; break;
+ case enum_Project_Library: prefsData.projtype = kProjTypeLibrary; break;
+ case enum_Project_SharedLibrary: prefsData.projtype = kProjTypeSharedLib; break;
+ case enum_Project_CodeResource: prefsData.projtype = kProjTypeCodeResource; break;
+ case enum_Project_MPWTool: prefsData.projtype = kProjTypeMPWTool; break;
+ default: return (errAECoercionFail);
+ }
+ break;
+
+ case prefsPR_FileName:
+ if (prefsDesc->descriptorType == typeChar)
+ {
+ dataHand = prefsDesc->dataHandle;
+ }
+ else
+ {
+ err = AECoerceDesc(prefsDesc, typeChar, &toDesc);
+ if (err == noErr)
+ dataHand = toDesc.dataHandle;
+ }
+ if (err == noErr)
+ {
+ textLength = GetHandleSize(dataHand);
+ if (textLength > sizeof(prefsData.outfile) - 1)
+ textLength = sizeof(prefsData.outfile) - 1;
+ BlockMoveData(*dataHand, prefsData.outfile+1, textLength);
+ prefsData.outfile[0] = textLength;
+ }
+ break;
+
+ default:
+ err = errAECantHandleClass;
+ break;
+ }
+
+ if (err == noErr)
+ {
+ ** (XPIDLSettingsHandle) settings = prefsData;
+ }
+
+ AEDisposeDesc(&toDesc);
+
+ return (err);
+#else
+ return (errAECantHandleClass);
+#endif
+}
+
+/*
+ * GetFactory - retrieve factory settings
+ *
+ */
+
+static short GetFactory(Handle settings)
+{
+ Handle factory;
+ Size size;
+ OSErr err;
+
+ factory = Get1Resource('pref', kFactoryPrefsID);
+ if (factory == NULL) {
+ err = ResError();
+ if (err == noErr)
+ err = resNotFound;
+ return (err);
+ }
+
+ size = GetHandleSize(factory);
+ SetHandleSize(settings, size);
+ err = MemError();
+
+ if (err == noErr) {
+ BlockMoveData(*factory, *settings, size);
+ }
+
+ return (err);
+}
+
+/*
+ * UpdatePref - "upgrade" a pref to the current version
+ */
+static short UpdatePref(Handle settings)
+{
+ if (GetHandleSize(settings) != sizeof(XPIDLSettings))
+ GetFactory(settings);
+
+ return (noErr);
+}
+
+/*
+ * ComparePrefs
+ *
+ */
+static Boolean ComparePrefs(Handle prefsHand1, Handle prefsHand2)
+{
+ XPIDLSettings& prefs1 = **(XPIDLSettingsHandle) prefsHand1;
+ XPIDLSettings& prefs2 = **(XPIDLSettingsHandle) prefsHand2;
+
+ return ((prefs1.mode == prefs2.mode) &&
+ (prefs1.warnings == prefs2.warnings) &&
+ (prefs1.verbose == prefs2.verbose) &&
+ (EqualString(prefs1.output, prefs2.output, true, true)));
+}
+
+static Boolean ComparePrefs(XPIDLSettings& prefs1, XPIDLSettings& prefs2)
+{
+ return ((prefs1.mode == prefs2.mode) &&
+ (prefs1.warnings == prefs2.warnings) &&
+ (prefs1.verbose == prefs2.verbose) &&
+ (EqualString(prefs1.output, prefs2.output, true, true)));
+}
+
+/*
+ * OutlineRect
+ *
+ */
+static void OutlineRect(const Rect* focusRect, Boolean outlineOn)
+{
+ ColorSpec savedForeColor, backColor;
+ PenState savedPen;
+
+ GetPenState(&savedPen);
+ PenNormal();
+
+ if (!outlineOn)
+ {
+ SaveFore(&savedForeColor);
+ SaveBack(&backColor);
+ RestoreFore(&backColor);
+ }
+
+ PenSize(2, 2);
+ FrameRect(focusRect);
+
+ SetPenState(&savedPen);
+
+ if (!outlineOn)
+ {
+ RestoreFore(&savedForeColor);
+ }
+}
+
+/*
+ * DragEnter
+ *
+ */
+static OSErr DragEnter(PanelParameterBlock *pb)
+{
+#if 0
+ short theItem = pb->itemHit - pb->baseItems;
+ unsigned short itemCount;
+ Rect itemRect;
+ OSErr err;
+#endif
+
+ /* Return paramErr if the user is on a item that can't be dropped on */
+ return (paramErr);
+}
+
+/*
+ * DragWithin
+ *
+ */
+static void DragWithin(PanelParameterBlock *pb)
+{
+#pragma unused(pb)
+
+ /* there's nothing to do */
+
+/// SysBreakStr("\preqDragWithin");
+}
+
+/*
+ * DragExit
+ *
+ */
+static void DragExit(PanelParameterBlock *pb)
+{
+ OSErr err;
+
+/// SysBreakStr("\preqDragExit");
+
+ if (sHighlightOn) {
+ err = HideDragHilite(pb->dragref);
+ if (err == noErr)
+ sHighlightOn = false;
+ }
+}
+
+/*
+ * DragDrop
+ *
+ */
+static void DragDrop(PanelParameterBlock *pb)
+{
+#if 0
+ Rect itemRect;
+#endif
+
+/// SysBreakStr("\preqDragDrop");
+
+ DragExit(pb);
+}
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_xpidl_panel.h b/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_xpidl_panel.h
new file mode 100644
index 00000000..582b1055
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_xpidl_panel.h
@@ -0,0 +1,106 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: NPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Netscape 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/NPL/
+ *
+ * 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 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 NPL, 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 NPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ mac_xpidl_panel.h
+ */
+
+#pragma once
+
+#ifndef __MAC_XPIDL_PANEL__
+#define __MAC_XPIDL_PANEL__
+
+#ifndef __TYPES__
+#include <Types.h>
+#endif
+
+#pragma options align=mac68k
+
+/* this is the name of the panel, as shown in the Finder */
+#define kXPIDLPanelName "xpidl Settings"
+
+/*
+ * AppleScript dictionary info. As a rule of thumb, dropin panels should use the
+ * same terminology and numeric code in their 'aete' that the IDE uses if there
+ * is already a similar item in the IDE's 'aete'. That is the case here, so we
+ * merely duplicate applicable 68K Project and 68K Linker user terms below.
+ */
+
+enum {
+/* Symbolic Name Code AETE Terminology */
+ class_XPIDL = 'XIDL',
+
+ prefsPR_ProjectType = 'PR01', /* Project Type */
+ prefsPR_FileName = 'PR02', /* File Name */
+ prefsLN_GenerateSymFile = 'LN02', /* Generate SYM File */
+
+ /* enumeration for project type */
+ enumeration_ProjectType = 'PRPT',
+ enum_Project_Application = 'PRPA', /* application */
+ enum_Project_Library = 'PRPL', /* library */
+ enum_Project_SharedLibrary = 'PRPS', /* shared library */
+ enum_Project_CodeResource = 'PRPC', /* code resource */
+ enum_Project_MPWTool = 'PRPM' /* MPW tool */
+};
+
+enum {
+ kXPIDLModeHeader = 1,
+ kXPIDLModeJava,
+ kXPIDLModeTypelib,
+ kXPIDLModeDoc
+};
+
+/* This is the structure that is manipulated by the panel. The sample
+ * compiler & linker both "know" about this structure.
+ */
+
+enum {
+ kXPIDLSettingsVersion = 0x0100
+};
+
+struct XPIDLSettings {
+ short version; /* version # of settings data */
+ short mode; /* one of kXPIDLModeHeader, ... */
+ Boolean warnings; /* generate warnings. */
+ Boolean verbose; /* verbose mode */
+ Str32Field output; /* name of the output file */
+};
+
+typedef struct XPIDLSettings XPIDLSettings, **XPIDLSettingsHandle;
+
+#pragma options align=reset
+
+#endif /* __MAC_XPIDL_PANEL__ */
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_xpt_linker.cpp b/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_xpt_linker.cpp
new file mode 100644
index 00000000..fe137959
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/mac_xpt_linker.cpp
@@ -0,0 +1,546 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: NPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Netscape 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/NPL/
+ *
+ * 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 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 NPL, 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 NPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ mac_xpt_linker.cpp
+
+ CodeWarrior plugin linker, links together multiple .xpt files.
+
+ by Patrick C. Beard.
+ */
+
+/* standard headers */
+#include <stdio.h>
+#include <string.h>
+#include <setjmp.h>
+
+/* system headers */
+#include <Files.h>
+#include <Strings.h>
+#include <Aliases.h>
+#include <Resources.h>
+
+/* compiler headers */
+#include "DropInCompilerLinker.h"
+#include "CompilerMapping.h"
+#include "CWPluginErrors.h"
+
+/* project headers */
+#include "mac_xpidl_panel.h"
+#include "mac_console.h"
+#include "mac_strings.h"
+#include "FullPath.h"
+#include "MoreFilesExtras.h"
+
+/* use standard CodeWarrior debugger */
+#define kDebuggerCreator 'MWDB'
+
+/* prototypes of local functions */
+static CWResult Link(CWPluginContext context);
+static CWResult Disassemble(CWPluginContext context);
+static CWResult GetTargetInfo(CWPluginContext context);
+
+extern "C" {
+pascal short xpt_linker(CWPluginContext context);
+int xptlink_main(int argc, char* argv[]);
+int xptdump_main(int argc, char* argv[]);
+
+FILE * FSp_fopen(ConstFSSpecPtr spec, const char * open_mode);
+size_t mac_get_file_length(const char* filename);
+}
+
+/* external variables */
+extern jmp_buf exit_jump;
+extern int exit_status;
+
+/* global variables */
+CWPluginContext gPluginContext;
+
+/* local variables */
+static CWFileSpec gOutputDirectory;
+static CWFileSpec gObjectCodeDirectory;
+
+/*
+ * xpt_linker - main entry-point for linker plugin
+ *
+ */
+pascal short xpt_linker(CWPluginContext context)
+{
+ long request;
+ if (CWGetPluginRequest(context, &request) != cwNoErr)
+ return cwErrRequestFailed;
+
+ gPluginContext = context;
+ short result = cwNoErr;
+
+ /* dispatch on linker request */
+ switch (request) {
+ case reqInitLinker:
+ /* linker has just been loaded into memory */
+ break;
+
+ case reqTermLinker:
+ /* linker is about to be unloaded from memory */
+ break;
+
+ case reqLink:
+ /* build the final executable */
+ result = Link(context);
+ break;
+
+ case reqDisassemble:
+ /* disassemble object code for a given project file */
+ result = Disassemble(context);
+ break;
+
+ case reqTargetInfo:
+ /* return info describing target characteristics */
+ result = GetTargetInfo(context);
+ break;
+
+ default:
+ result = cwErrRequestFailed;
+ break;
+ }
+
+ result = CWDonePluginRequest(context, result);
+
+ /* return result code */
+ return result;
+}
+
+static char* full_path_to(const FSSpec& file)
+{
+ short len = 0;
+ Handle fullPath = NULL;
+ if (FSpGetFullPath(&file, &len, &fullPath) == noErr && fullPath != NULL) {
+ char* path = new char[1 + len];
+ if (path != NULL) {
+ BlockMoveData(*fullPath, path, len);
+ path[len] = '\0';
+ }
+ DisposeHandle(fullPath);
+ return path;
+ }
+ return NULL;
+}
+
+/**
+ * Provides the full path name to a given directory.
+ */
+static char* full_path_to(short vRefNum, long dirID)
+{
+ long parID;
+ if (GetParentID(vRefNum, dirID, NULL, &parID) == noErr) {
+ FSSpec dirSpec = { vRefNum, parID };
+ if (GetDirName(vRefNum, dirID, dirSpec.name) == noErr) {
+ return full_path_to(dirSpec);
+ }
+ }
+ return NULL;
+}
+
+/**
+ * Returns the length of a file, assuming it is always located in the
+ * project's object code directory.
+ */
+size_t mac_get_file_length(const char* filename)
+{
+ FSSpec fileSpec = { gObjectCodeDirectory.vRefNum, gObjectCodeDirectory.parID };
+ c2p_strcpy(fileSpec.name, filename);
+ long dataSize, rsrcSize;
+ if (FSpGetFileSize(&fileSpec, &dataSize, &rsrcSize) != noErr)
+ dataSize = 0;
+ return dataSize;
+}
+
+/**
+ * replaces standard fopen -- opens files for writing in the project's output directory,
+ * and files for reading in the object code directory.
+ */
+FILE* std::fopen(const char* filename, const char *mode)
+{
+ CWFileSpec& fileDir = (mode[0] == 'r' ? gObjectCodeDirectory : gOutputDirectory);
+ FSSpec fileSpec = { fileDir.vRefNum, fileDir.parID };
+ c2p_strcpy(fileSpec.name, filename);
+ return FSp_fopen(&fileSpec, mode);
+}
+
+static CWResult GetSettings(CWPluginContext context, XPIDLSettings& settings)
+{
+ CWMemHandle settingsHand;
+ CWResult err = CWGetNamedPreferences(context, kXPIDLPanelName, &settingsHand);
+ if (!CWSUCCESS(err))
+ return err;
+
+ XPIDLSettings* settingsPtr = NULL;
+ err = CWLockMemHandle(context, settingsHand, false, (void**)&settingsPtr);
+ if (!CWSUCCESS(err))
+ return err;
+
+ settings = *settingsPtr;
+
+ err = CWUnlockMemHandle(context, settingsHand);
+ if (!CWSUCCESS(err))
+ return err;
+
+ return cwNoErr;
+}
+
+static CWResult LinkHeaders(CWPluginContext context, XPIDLSettings& settings)
+{
+ // find out how many files there are to link.
+ long fileCount = 0;
+ CWResult err = CWGetProjectFileCount(context, &fileCount);
+ if (err != cwNoErr || fileCount == 0)
+ return err;
+
+ // get the output directory.
+ FSSpec outputDir;
+ err = CWGetOutputFileDirectory(context, &outputDir);
+ if (!CWSUCCESS(err))
+ return err;
+
+ // enumerate all of the output header files, and make aliases to them in
+ // the output directory.
+ for (long index = 0; (err == cwNoErr) && (index < fileCount); index++) {
+ // get the name of each output file.
+ CWFileSpec outputFile;
+ err = CWGetStoredObjectFileSpec(context, index, &outputFile);
+ if (err == cwNoErr) {
+ FInfo info;
+ err = FSpGetFInfo(&outputFile, &info);
+
+ FSSpec aliasFile = { outputDir.vRefNum, outputDir.parID };
+ BlockMoveData(outputFile.name, aliasFile.name, 1 + outputFile.name[0]);
+
+ AliasHandle alias = NULL;
+ if (NewAliasMinimal(&outputFile, &alias) == noErr) {
+ // recreate the alias file from scratch.
+ FSpDelete(&aliasFile);
+ FSpCreateResFile(&aliasFile, info.fdCreator, info.fdType, smRoman);
+ short refNum = FSpOpenResFile(&aliasFile, fsRdWrPerm);
+ if (refNum != -1) {
+ UseResFile(refNum);
+ AddResource(Handle(alias), rAliasType, 0, aliasFile.name);
+ ReleaseResource(Handle(alias));
+ UpdateResFile(refNum);
+ CloseResFile(refNum);
+ }
+ // finally, mark the newly created file as an alias file.
+ FSpGetFInfo(&aliasFile, &info);
+ info.fdFlags |= kIsAlias;
+ FSpSetFInfo(&aliasFile, &info);
+ }
+ }
+ }
+
+ // create the target file in the output directory.
+ BlockMoveData(settings.output, outputDir.name, 1 + settings.output[0]);
+ FILE* outputFile = FSp_fopen(&outputDir, "w");
+ if (outputFile != NULL) fclose(outputFile);
+
+ return err;
+}
+
+static CWResult LinkTypeLib(CWPluginContext context, XPIDLSettings& settings)
+{
+ // find out how many files there are to link.
+ long fileCount = 0;
+ CWResult err = CWGetProjectFileCount(context, &fileCount);
+ if (err != cwNoErr || fileCount == 0)
+ return err;
+
+ // assemble the argument list.
+ // { "xpt_link", outputFile, inputFile1, ..., inputFileN, NULL }
+ char** argv = new char*[2 + fileCount + 1];
+ int argc = 0;
+ argv[argc++] = "xpt_link";
+
+ // get the output directory.
+ err = CWGetOutputFileDirectory(context, &gOutputDirectory);
+ if (!CWSUCCESS(err))
+ return err;
+
+ // get the object code directory.
+ err = CWGetStoredObjectFileSpec(context, 0, &gObjectCodeDirectory);
+ if (!CWSUCCESS(err))
+ return err;
+
+ // push the output file name.
+ if ((argv[argc++] = p2c_strdup(settings.output)) == NULL)
+ return cwErrOutOfMemory;
+
+ for (long index = 0; (err == cwNoErr) && (index < fileCount); index++) {
+ // get the name of each output file.
+ CWFileSpec outputFile;
+ err = CWGetStoredObjectFileSpec(context, index, &outputFile);
+ if (err == cwNoErr) {
+ if ((argv[argc++] = p2c_strdup(outputFile.name)) == NULL) {
+ err = cwErrOutOfMemory;
+ break;
+ }
+ }
+ }
+
+ if (err != cwNoErr)
+ return err;
+
+ // trap calls to exit, which longjmp back to here.
+ if (setjmp(exit_jump) == 0) {
+ if (xptlink_main(argc, argv) != 0)
+ err = cwErrRequestFailed;
+ } else {
+ // evidently the good old exit function got called.
+ if (exit_status != 0)
+ err = cwErrRequestFailed;
+ }
+
+ return err;
+}
+
+static CWResult Link(CWPluginContext context)
+{
+ // load the relevant prefs.
+ XPIDLSettings settings = { kXPIDLSettingsVersion, kXPIDLModeTypelib, false, false };
+ CWResult err = GetSettings(context, settings);
+ if (err != cwNoErr)
+ return err;
+
+ switch (settings.mode) {
+ case kXPIDLModeHeader:
+ return LinkHeaders(context, settings);
+ case kXPIDLModeTypelib:
+ return LinkTypeLib(context, settings);
+ default:
+ return cwNoErr;
+ }
+}
+
+static CWResult Disassemble(CWPluginContext context)
+{
+ CWResult err = noErr;
+
+ // cache the project's output directory.
+ err = CWGetOutputFileDirectory(gPluginContext, &gOutputDirectory);
+ if (!CWSUCCESS(err))
+ return err;
+
+ long fileNum;
+ err = CWGetMainFileNumber(context, &fileNum);
+ if (!CWSUCCESS(err))
+ return err;
+
+ // get the output file's location from the stored object data.
+ err = CWGetStoredObjectFileSpec(context, fileNum, &gObjectCodeDirectory);
+ if (!CWSUCCESS(err))
+ return err;
+
+ char* outputName = p2c_strdup(gObjectCodeDirectory.name);
+ if (outputName == NULL)
+ return cwErrOutOfMemory;
+
+ XPIDLSettings settings = { kXPIDLSettingsVersion, kXPIDLModeTypelib, false, false };
+ GetSettings(context, settings);
+
+ // build an argument list and call xpt_dump.
+ int argc = 1;
+ char* argv[] = { "xpt_dump", NULL, NULL, NULL };
+ if (settings.verbose) argv[argc++] = "-v";
+ argv[argc++] = outputName;
+
+ // trap calls to exit, which longjmp back to here.
+ if (setjmp(exit_jump) == 0) {
+ if (xptdump_main(argc, argv) != 0)
+ err = cwErrRequestFailed;
+ } else {
+ // evidently the good old exit function got called.
+ if (exit_status != 0)
+ err = cwErrRequestFailed;
+ }
+
+ delete[] outputName;
+
+ if (err == noErr) {
+ // display the disassembly in its own fresh text window.
+ CWNewTextDocumentInfo info = {
+ NULL,
+ mac_console_handle,
+ false
+ };
+ CWResizeMemHandle(context, mac_console_handle, mac_console_count);
+ err = CWCreateNewTextDocument(context, &info);
+ }
+
+ return err;
+}
+
+static CWResult GetTargetInfo(CWPluginContext context)
+{
+ CWTargetInfo targ;
+ memset(&targ, 0, sizeof(targ));
+
+ CWResult err = CWGetOutputFileDirectory(context, &targ.outfile);
+ targ.outputType = linkOutputFile;
+ targ.symfile = targ.outfile; /* location of SYM file */
+ targ.linkType = exelinkageFlat;
+ targ.targetCPU = '****';
+ targ.targetOS = '****';
+
+ // load the relevant settings.
+ XPIDLSettings settings = { kXPIDLSettingsVersion, kXPIDLModeTypelib, false, false };
+ err = GetSettings(context, settings);
+ if (err != cwNoErr)
+ return err;
+
+#if CWPLUGIN_HOST == CWPLUGIN_HOST_MACOS
+ // tell the IDE about the output file.
+ targ.outfileCreator = 'MMCH';
+ targ.outfileType = 'CWIE';
+ targ.debuggerCreator = kDebuggerCreator; /* so IDE can locate our debugger */
+
+ BlockMoveData(settings.output, targ.outfile.name, 1 + settings.output[0]);
+ targ.symfile.name[0] = 0;
+#endif
+
+#if CWPLUGIN_HOST == CWPLUGIN_HOST_WIN32
+ targ.debugHelperIsRegKey = true;
+ *(long*)targ.debugHelperName = kDebuggerCreator;
+ targ.debugHelperName[4] = 0;
+ strcat(targ.outfile.path, "\\");
+ strcat(targ.outfile.path, prefsData.outfile);
+ strcpy(targ.symfile.path, targ.outfile.path);
+ strcat(targ.symfile.path, ".SYM");
+#endif
+
+ targ.runfile = targ.outfile;
+ targ.linkAgainstFile = targ.outfile;
+
+ /* we can only run applications */
+ // targ.canRun = (prefsData.projtype == kProjTypeApplication);
+
+ /* we can only debug if we have a SYM file */
+ // targ.canDebug = prefsData.linksym;
+
+ err = CWSetTargetInfo(context, &targ);
+
+ return err;
+}
+
+#if 0
+
+#if CW_USE_PRAGMA_EXPORT
+#pragma export on
+#endif
+
+CWPLUGIN_ENTRY(CWPlugin_GetDropInFlags)(const DropInFlags** flags, long* flagsSize)
+{
+ static const DropInFlags sFlags = {
+ kCurrentDropInFlagsVersion,
+ CWDROPINLINKERTYPE,
+ DROPINCOMPILERLINKERAPIVERSION_7,
+ (linkMultiTargAware | linkAlwaysReload),
+ 0,
+ DROPINCOMPILERLINKERAPIVERSION
+ };
+
+ *flags = &sFlags;
+ *flagsSize = sizeof(sFlags);
+
+ return cwNoErr;
+}
+
+CWPLUGIN_ENTRY(CWPlugin_GetDropInName)(const char** dropinName)
+{
+ static const char* sDropInName = "xpt Linker";
+ *dropinName = sDropInName;
+ return cwNoErr;
+}
+
+CWPLUGIN_ENTRY(CWPlugin_GetDisplayName)(const char** displayName)
+{
+ static const char* sDisplayName = "xpt Linker";
+ *displayName = sDisplayName;
+ return cwNoErr;
+}
+
+CWPLUGIN_ENTRY(CWPlugin_GetPanelList)(const CWPanelList** panelList)
+{
+ // +++Turn this on when the sample panel has been converted!
+ static const char* sPanelName = kXPIDLPanelName;
+ static CWPanelList sPanelList = { kCurrentCWPanelListVersion, 1, &sPanelName };
+
+ *panelList = &sPanelList;
+
+ return cwNoErr;
+}
+
+CWPLUGIN_ENTRY(CWPlugin_GetTargetList)(const CWTargetList** targetList)
+{
+ static CWDataType sCPU = '****';
+ static CWDataType sOS = '****';
+ static CWTargetList sTargetList = { kCurrentCWTargetListVersion, 1, &sCPU, 1, &sOS };
+
+ *targetList = &sTargetList;
+
+ return cwNoErr;
+}
+
+CWPLUGIN_ENTRY(CWPlugin_GetDefaultMappingList)(const CWExtMapList** defaultMappingList)
+{
+ static CWExtensionMapping sExtension = { 'MMCH', ".xpt", 0 };
+ static CWExtMapList sExtensionMapList = { kCurrentCWExtMapListVersion, 1, &sExtension };
+
+ *defaultMappingList = &sExtensionMapList;
+
+ return cwNoErr;
+}
+
+CWPLUGIN_ENTRY (CWPlugin_GetFamilyList)(const CWFamilyList** familyList)
+{
+ static CWFamily sFamily = { 'XIDL', "xpidl Settings" };
+ static CWFamilyList sFamilyList = { kCurrentCWFamilyListVersion, 0, &sFamily };
+
+ *familyList = &sFamilyList;
+
+ return cwNoErr;
+}
+
+#if CW_USE_PRAGMA_EXPORT
+#pragma export off
+#endif
+
+#endif
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/panel.rsrc b/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/panel.rsrc
new file mode 100644
index 00000000..c5777088
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/panel.rsrc
Binary files differ
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/version.rsrc b/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/version.rsrc
new file mode 100644
index 00000000..6737d356
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpidl/macplugin/version.rsrc
Binary files differ
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpidl/xpidl.c b/src/libs/xpcom18a4/xpcom/typelib/xpidl/xpidl.c
new file mode 100644
index 00000000..e1a7c58d
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpidl/xpidl.c
@@ -0,0 +1,275 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: NPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Netscape 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/NPL/
+ *
+ * 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 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 NPL, 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 NPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * Main xpidl program entry point.
+ */
+
+#include "xpidl.h"
+
+static ModeData modes[] = {
+ {"header", "Generate C++ header", "h", xpidl_header_dispatch},
+ {"typelib", "Generate XPConnect typelib", "xpt", xpidl_typelib_dispatch},
+ {"doc", "Generate HTML documentation", "html", xpidl_doc_dispatch},
+ {"java", "Generate Java interface", "java", xpidl_java_dispatch},
+ {0, 0, 0, 0}
+};
+
+static ModeData *
+FindMode(char *mode)
+{
+ int i;
+ for (i = 0; modes[i].mode; i++) {
+ if (!strcmp(modes[i].mode, mode))
+ return &modes[i];
+ }
+ return NULL;
+}
+
+gboolean enable_debug = FALSE;
+gboolean enable_warnings = FALSE;
+gboolean verbose_mode = FALSE;
+gboolean emit_typelib_annotations = FALSE;
+gboolean explicit_output_filename = FALSE;
+
+/* The following globals are explained in xpt_struct.h */
+PRUint8 major_version = XPT_MAJOR_VERSION;
+PRUint8 minor_version = XPT_MINOR_VERSION;
+
+static char xpidl_usage_str[] =
+"Usage: %s -m mode [-w] [-v] [-t version number]\n"
+" [-I path] [-o basename | -e filename.ext] filename.idl\n"
+" -a emit annotations to typelib\n"
+" -w turn on warnings (recommended)\n"
+" -v verbose mode (NYI)\n"
+" -t create a typelib of a specific version number\n"
+" -I add entry to start of include path for ``#include \"nsIThing.idl\"''\n"
+" -o use basename (e.g. ``/tmp/nsIThing'') for output\n"
+" -e use explicit output filename\n"
+" -m specify output mode:\n";
+
+static void
+xpidl_usage(int argc, char *argv[])
+{
+ int i;
+ fprintf(stderr, xpidl_usage_str, argv[0]);
+ for (i = 0; modes[i].mode; i++) {
+ fprintf(stderr, " %-12s %-30s (.%s)\n", modes[i].mode,
+ modes[i].modeInfo, modes[i].suffix);
+ }
+}
+
+#if defined(XP_MAC) && defined(XPIDL_PLUGIN)
+#define main xpidl_main
+int xpidl_main(int argc, char *argv[]);
+#endif
+
+int main(int argc, char *argv[])
+{
+ int i;
+ IncludePathEntry *inc, *inc_head, **inc_tail;
+ char *file_basename = NULL;
+ ModeData *mode = NULL;
+ gboolean create_old_typelib = FALSE;
+
+ /* turn this on for extra checking of our code */
+/* IDL_check_cast_enable(TRUE); */
+
+ inc_head = xpidl_malloc(sizeof *inc);
+#ifndef XP_MAC
+ inc_head->directory = ".";
+#else
+ inc_head->directory = "";
+#endif
+ inc_head->next = NULL;
+ inc_tail = &inc_head->next;
+
+ for (i = 1; i < argc; i++) {
+ if (argv[i][0] != '-')
+ break;
+ switch (argv[i][1]) {
+ case '-':
+ argc++; /* pretend we didn't see this */
+ /* fall through */
+ case 0: /* - is a legal input filename (stdin) */
+ goto done_options;
+ case 'a':
+ emit_typelib_annotations = TRUE;
+ break;
+ case 'w':
+ enable_warnings = TRUE;
+ break;
+ case 'v':
+ verbose_mode = TRUE;
+ break;
+ case 't':
+ {
+ /* Parse for "-t version number" and store it into global boolean
+ * and string variables.
+ */
+ const gchar* typelib_version_string = NULL;
+
+ /*
+ * 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");
+ xpidl_usage(argc, argv);
+ return 1;
+ }
+
+ /* Do not allow more than one "-t" definition */
+ if (create_old_typelib) {
+ fprintf(stderr,
+ "ERROR: -t argument used twice. "
+ "Cannot specify more than one version\n");
+ xpidl_usage(argc, 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:
+ break;
+ case XPT_VERSION_OLD:
+ create_old_typelib = TRUE;
+ break;
+ case XPT_VERSION_UNSUPPORTED:
+ fprintf(stderr, "ERROR: version \"%s\" not supported.\n",
+ argv[i]);
+ xpidl_usage(argc, argv);
+ return 1;
+ case XPT_VERSION_UNKNOWN:
+ default:
+ fprintf(stderr, "ERROR: version \"%s\" not recognised.\n",
+ argv[i]);
+ xpidl_usage(argc, argv);
+ return 1;
+ }
+ break;
+ }
+ case 'I':
+ if (argv[i][2] == '\0' && i == argc) {
+ fputs("ERROR: missing path after -I\n", stderr);
+ xpidl_usage(argc, argv);
+ return 1;
+ }
+ inc = xpidl_malloc(sizeof *inc);
+ if (argv[i][2] == '\0') {
+ /* is it the -I foo form? */
+ inc->directory = argv[++i];
+ } else {
+ /* must be the -Ifoo form. Don't preincrement i. */
+ inc->directory = argv[i] + 2;
+ }
+#ifdef DEBUG_shaver_includes
+ fprintf(stderr, "adding %s to include path\n", inc->directory);
+#endif
+ inc->next = NULL;
+ *inc_tail = inc;
+ inc_tail = &inc->next;
+ break;
+ case 'o':
+ if (i == argc) {
+ fprintf(stderr, "ERROR: missing basename after -o\n");
+ xpidl_usage(argc, argv);
+ return 1;
+ }
+ file_basename = argv[++i];
+ explicit_output_filename = FALSE;
+ break;
+ case 'e':
+ if (i == argc) {
+ fprintf(stderr, "ERROR: missing basename after -e\n");
+ xpidl_usage(argc, argv);
+ return 1;
+ }
+ file_basename = argv[++i];
+ explicit_output_filename = TRUE;
+ break;
+ case 'm':
+ if (i + 1 == argc) {
+ fprintf(stderr, "ERROR: missing modename after -m\n");
+ xpidl_usage(argc, argv);
+ return 1;
+ }
+ if (mode) {
+ fprintf(stderr,
+ "ERROR: must specify exactly one mode "
+ "(first \"%s\", now \"%s\")\n", mode->mode,
+ argv[i + 1]);
+ xpidl_usage(argc, argv);
+ return 1;
+ }
+ mode = FindMode(argv[++i]);
+ if (!mode) {
+ fprintf(stderr, "ERROR: unknown mode \"%s\"\n", argv[i]);
+ xpidl_usage(argc, argv);
+ return 1;
+ }
+ break;
+ default:
+ fprintf(stderr, "unknown option %s\n", argv[i]);
+ xpidl_usage(argc, argv);
+ return 1;
+ }
+ }
+ done_options:
+ if (!mode) {
+ fprintf(stderr, "ERROR: must specify output mode\n");
+ xpidl_usage(argc, argv);
+ return 1;
+ }
+ if (argc != i + 1) {
+ fprintf(stderr, "ERROR: extra arguments after input file\n");
+ }
+
+ /*
+ * Don't try to process multiple files, given that we don't handle -o
+ * multiply.
+ */
+ if (xpidl_process_idl(argv[i], inc_head, file_basename, mode))
+ return 0;
+
+ return 1;
+}
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpidl/xpidl.h b/src/libs/xpcom18a4/xpcom/typelib/xpidl/xpidl.h
new file mode 100644
index 00000000..857bfdf8
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpidl/xpidl.h
@@ -0,0 +1,278 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: NPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Netscape 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/NPL/
+ *
+ * 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 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 NPL, 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 NPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * Intramodule declarations.
+ */
+
+#ifndef __xpidl_h
+#define __xpidl_h
+
+#include <errno.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <glib.h>
+#include <string.h> /* After glib.h to avoid warnings about shadowing 'index'. */
+
+#ifndef XP_MAC
+#include <libIDL/IDL.h>
+#else
+#include <IDL.h>
+#endif
+
+#include <xpt_struct.h>
+
+/*
+ * IDL_tree_warning bombs on libIDL version 6.5, and I don't want to not write
+ * warnings... so I define a versioned one here. Thanks to Mike Shaver for the
+ * this solution, which allows us to pass through varargs calls.
+ */
+#if !(LIBIDL_MAJOR_VERSION == 0 && LIBIDL_MINOR_VERSION == 6 && \
+ LIBIDL_MICRO_VERSION == 5) && !defined(DEBUG_shaver)
+/*
+ * This turns a varargs call to XPIDL_WARNING directly into a varargs
+ * call to IDL_tree_warning or xpidl_tree_warning as appropriate. The
+ * only tricky bit is that you must call XPIDL_WARNING with extra
+ * parens, e.g. XPIDL_WARNING((foo, bar, "sil"))
+ *
+ * Probably best removed when we leave 6.5. */
+#define XPIDL_WARNING(x) IDL_tree_warning x
+#else
+extern void xpidl_tree_warning(IDL_tree p, int level, const char *fmt, ...);
+#define XPIDL_WARNING(x) xpidl_tree_warning x
+#endif
+
+/*
+ * Internal operation flags.
+ */
+extern gboolean enable_debug;
+extern gboolean enable_warnings;
+extern gboolean verbose_mode;
+extern gboolean emit_typelib_annotations;
+extern gboolean explicit_output_filename;
+
+extern PRUint8 major_version;
+extern PRUint8 minor_version;
+
+typedef struct TreeState TreeState;
+
+/*
+ * A function to handle an IDL_tree type.
+ */
+typedef gboolean (*nodeHandler)(TreeState *);
+
+/*
+ * Struct containing functions to define the behavior of a given output mode.
+ */
+typedef struct backend {
+ nodeHandler *dispatch_table; /* nodeHandlers table, indexed by node type. */
+ nodeHandler emit_prolog; /* called at beginning of output generation. */
+ nodeHandler emit_epilog; /* called at end. */
+} backend;
+
+/* Function that produces a struct of output-generation functions */
+typedef backend *(*backendFactory)();
+
+extern backend *xpidl_header_dispatch(void);
+extern backend *xpidl_typelib_dispatch(void);
+extern backend *xpidl_doc_dispatch(void);
+extern backend *xpidl_java_dispatch(void);
+
+typedef struct ModeData {
+ char *mode;
+ char *modeInfo;
+ char *suffix;
+ backendFactory factory;
+} ModeData;
+
+typedef struct IncludePathEntry {
+ char *directory;
+ struct IncludePathEntry *next;
+} IncludePathEntry;
+
+struct TreeState {
+ FILE *file;
+ /* Maybe supplied by -o. Not related to (g_)basename from string.h or glib */
+ char *basename;
+ IDL_ns ns;
+ IDL_tree tree;
+ GSList *base_includes;
+ nodeHandler *dispatch;
+ void *priv; /* mode-private data */
+#ifdef VBOX_XPIDL_EMULATE_GENJIFACES
+ char *real_outname;
+#endif
+
+};
+
+/*
+ * Process an IDL file, generating InterfaceInfo, documentation and headers as
+ * appropriate.
+ */
+int
+xpidl_process_idl(char *filename, IncludePathEntry *include_path,
+ char *file_basename, ModeData *mode);
+
+/*
+ * Iterate over an IDLN_LIST -- why is this not part of libIDL?
+ */
+void
+xpidl_list_foreach(IDL_tree p, IDL_tree_func foreach, gpointer user_data);
+
+/*
+ * Wrapper whines to stderr then exits after null return from malloc or strdup.
+ */
+void *
+xpidl_malloc(size_t nbytes);
+
+char *
+xpidl_strdup(const char *s);
+
+/*
+ * Return a newly allocated string to the start of the base filename of path.
+ * Free with g_free().
+ */
+char *
+xpidl_basename(const char * path);
+
+/*
+ * Process an XPIDL node and its kids, if any.
+ */
+gboolean
+xpidl_process_node(TreeState *state);
+
+/*
+ * Write a newline folllowed by an indented, one-line comment containing IDL
+ * source decompiled from state->tree.
+ */
+void
+xpidl_write_comment(TreeState *state, int indent);
+
+
+
+/*
+ * Functions for parsing and printing UUIDs.
+ */
+
+/*
+ * How large should the buffer supplied to xpidl_sprint_IID be?
+ */
+#define UUID_LENGTH 37
+
+/*
+ * Print an iid to into a supplied buffer; the buffer should be at least
+ * UUID_LENGTH bytes.
+ */
+gboolean
+xpidl_sprint_iid(nsID *iid, char iidbuf[]);
+
+/*
+ * Parse a uuid string into an nsID struct. We cannot link against libxpcom,
+ * so we re-implement nsID::Parse here.
+ */
+gboolean
+xpidl_parse_iid(nsID *id, const char *str);
+
+
+/* Try to common a little node-handling stuff. */
+
+/* is this node from an aggregate type (interface)? */
+#define UP_IS_AGGREGATE(node) \
+ (IDL_NODE_UP(node) && \
+ (IDL_NODE_TYPE(IDL_NODE_UP(node)) == IDLN_INTERFACE || \
+ IDL_NODE_TYPE(IDL_NODE_UP(node)) == IDLN_FORWARD_DCL))
+
+#define UP_IS_NATIVE(node) \
+ (IDL_NODE_UP(node) && \
+ IDL_NODE_TYPE(IDL_NODE_UP(node)) == IDLN_NATIVE)
+
+/* is this type output in the form "<foo> *"? */
+#define STARRED_TYPE(node) (IDL_NODE_TYPE(node) == IDLN_TYPE_STRING || \
+ IDL_NODE_TYPE(node) == IDLN_TYPE_WIDE_STRING || \
+ (IDL_NODE_TYPE(node) == IDLN_IDENT && \
+ UP_IS_AGGREGATE(node)))
+
+#define DIPPER_TYPE(node) \
+ (NULL != IDL_tree_property_get(node, "domstring") || \
+ NULL != IDL_tree_property_get(node, "utf8string") || \
+ NULL != IDL_tree_property_get(node, "cstring") || \
+ NULL != IDL_tree_property_get(node, "astring"))
+
+/*
+ * Find the underlying type of an identifier typedef. Returns NULL
+ * (and doesn't complain) on failure.
+ */
+IDL_tree /* IDL_TYPE_DCL */
+find_underlying_type(IDL_tree typedef_ident);
+
+/*
+ * Check that const declarations match their stated sign and are of the
+ * appropriate types.
+ */
+gboolean
+verify_const_declaration(IDL_tree const_tree);
+
+/*
+ * Check that scriptable attributes in scriptable interfaces actually are.
+ */
+gboolean
+verify_attribute_declaration(IDL_tree method_tree);
+
+/*
+ * Perform various validation checks on methods.
+ */
+gboolean
+verify_method_declaration(IDL_tree method_tree);
+
+/*
+ * Verifies the interface declaration
+ */
+gboolean
+verify_interface_declaration(IDL_tree method_tree);
+
+/*
+ * Verify that a native declaration has an associated C++ expression, i.e. that
+ * it's of the form native <idl-name>(<c++-name>)
+ */
+gboolean
+check_native(TreeState *state);
+
+void
+printlist(FILE *outfile, GSList *slist);
+
+#endif /* __xpidl_h */
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpidl/xpidl_doc.c b/src/libs/xpcom18a4/xpcom/typelib/xpidl/xpidl_doc.c
new file mode 100644
index 00000000..d560e407
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpidl/xpidl_doc.c
@@ -0,0 +1,312 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: NPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Netscape 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/NPL/
+ *
+ * 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 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 NPL, 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 NPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "xpidl.h"
+
+/*
+ * Generates documentation from javadoc-style comments in XPIDL files.
+ */
+
+static gboolean
+doc_prolog(TreeState *state)
+{
+ fprintf(state->file, "<html>\n");
+ fprintf(state->file, "<head>\n");
+
+ fprintf(state->file,
+ "<!-- this file is generated from %s.idl -->\n",
+ state->basename);
+ fprintf(state->file, "<title>documentation for %s.idl interfaces</title>\n",
+ state->basename);
+ fprintf(state->file, "</head>\n\n");
+ fprintf(state->file, "<body>\n");
+
+ return TRUE;
+}
+
+static gboolean
+doc_epilog(TreeState *state)
+{
+ fprintf(state->file, "</body>\n");
+ fprintf(state->file, "</html>\n");
+
+ return TRUE;
+}
+
+
+static gboolean
+doc_list(TreeState *state)
+{
+ IDL_tree iter;
+ for (iter = state->tree; iter; iter = IDL_LIST(iter).next) {
+ state->tree = IDL_LIST(iter).data;
+ if (!xpidl_process_node(state))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static gboolean
+print_list(FILE *outfile, IDL_tree list)
+{
+ if (list == NULL)
+ return TRUE;
+
+ fprintf(outfile, "<ul>\n");
+ while (list != NULL) {
+ fprintf(outfile, " <li>%s\n",
+ IDL_IDENT(IDL_LIST(list).data).str);
+ list = IDL_LIST(list).next;
+ }
+ fprintf(outfile, "</ul>\n");
+ return TRUE;
+}
+
+static gboolean
+doc_interface(TreeState *state)
+{
+ IDL_tree iface = state->tree;
+ IDL_tree iter;
+ IDL_tree orig;
+ char *classname = IDL_IDENT(IDL_INTERFACE(iface).ident).str;
+ GSList *doc_comments = IDL_IDENT(IDL_INTERFACE(iface).ident).comments;
+
+ fprintf(state->file, "interface %s<br>\n", classname);
+
+ /* Much more could happen at this step. */
+ /*
+ * If parsing doc comments, you might need to take some care with line
+ * endings, as the xpidl frontend will return comments containing of /r,
+ * /n, /r/n depending on the platform. It's best to leave out platform
+ * #defines and just treat them all as equivalent.
+ */
+ if (doc_comments != NULL) {
+ fprintf(state->file, "doc comments:<br>\n");
+ fprintf(state->file, "<pre>\n");
+ printlist(state->file, doc_comments);
+ fprintf(state->file, "</pre>\n");
+ fprintf(state->file, "<br>\n");
+ }
+
+ /* inherits from */
+ /*
+ * Note that we accept multiple inheritance here (for e.g. gnome idl)
+ * even though the header backend (specific to mozilla idl) rejects it.
+ */
+ if ((iter = IDL_INTERFACE(iface).inheritance_spec)) {
+ fprintf(state->file, "%s inherits from:<br>\n", classname);
+ print_list(state->file, iter);
+ fprintf(state->file, "<br>\n");
+ }
+
+ /*
+ * Call xpidl_process_node to recur through list of declarations in
+ * interface body; another option would be to explicitly iterate through
+ * the list. xpidl_process_node currently requires twiddling the state to
+ * get the right node; I'll fix that soon to just take the node. Makes it
+ * easier to follow what's going on, I think...
+ */
+ orig = state->tree;
+ state->tree = IDL_INTERFACE(iface).body;
+ if (state->tree && !xpidl_process_node(state))
+ return FALSE;
+ state->tree = orig;
+
+ return TRUE;
+}
+
+/*
+ * Copied from xpidl_header.c. You'll probably want to change it; if you can
+ * use it verbatim or abstract it, we could move it to xpidl_util.c and share
+ * it from there.
+ */
+static gboolean
+write_type(IDL_tree type_tree, FILE *outfile)
+{
+ if (!type_tree) {
+ fputs("void", outfile);
+ return TRUE;
+ }
+
+ switch (IDL_NODE_TYPE(type_tree)) {
+ case IDLN_TYPE_INTEGER: {
+ gboolean sign = IDL_TYPE_INTEGER(type_tree).f_signed;
+ switch (IDL_TYPE_INTEGER(type_tree).f_type) {
+ case IDL_INTEGER_TYPE_SHORT:
+ fputs(sign ? "PRInt16" : "PRUint16", outfile);
+ break;
+ case IDL_INTEGER_TYPE_LONG:
+ fputs(sign ? "PRInt32" : "PRUint32", outfile);
+ break;
+ case IDL_INTEGER_TYPE_LONGLONG:
+ fputs(sign ? "PRInt64" : "PRUint64", outfile);
+ break;
+ default:
+ g_error("Unknown integer type %d\n",
+ IDL_TYPE_INTEGER(type_tree).f_type);
+ return FALSE;
+ }
+ break;
+ }
+ case IDLN_TYPE_CHAR:
+ fputs("char", outfile);
+ break;
+ case IDLN_TYPE_WIDE_CHAR:
+ fputs("PRUnichar", outfile); /* wchar_t? */
+ break;
+ case IDLN_TYPE_WIDE_STRING:
+ fputs("PRUnichar *", outfile);
+ break;
+ case IDLN_TYPE_STRING:
+ fputs("char *", outfile);
+ break;
+ case IDLN_TYPE_BOOLEAN:
+ fputs("PRBool", outfile);
+ break;
+ case IDLN_TYPE_OCTET:
+ fputs("PRUint8", outfile);
+ break;
+ case IDLN_TYPE_FLOAT:
+ switch (IDL_TYPE_FLOAT(type_tree).f_type) {
+ case IDL_FLOAT_TYPE_FLOAT:
+ fputs("float", outfile);
+ break;
+ case IDL_FLOAT_TYPE_DOUBLE:
+ fputs("double", outfile);
+ break;
+ /* XXX 'long double' just ignored, or what? */
+ default:
+ fprintf(outfile, "unknown_type_%d", IDL_NODE_TYPE(type_tree));
+ break;
+ }
+ break;
+ case IDLN_IDENT:
+ if (UP_IS_NATIVE(type_tree)) {
+ fputs(IDL_NATIVE(IDL_NODE_UP(type_tree)).user_type, outfile);
+ if (IDL_tree_property_get(type_tree, "ptr")) {
+ fputs(" *", outfile);
+ } else if (IDL_tree_property_get(type_tree, "ref")) {
+ fputs(" &", outfile);
+ }
+ } else {
+ fputs(IDL_IDENT(type_tree).str, outfile);
+ }
+ if (UP_IS_AGGREGATE(type_tree))
+ fputs(" *", outfile);
+ break;
+ default:
+ fprintf(outfile, "unknown_type_%d", IDL_NODE_TYPE(type_tree));
+ break;
+ }
+ return TRUE;
+}
+
+/* handle ATTR_DCL (attribute declaration) nodes */
+static gboolean
+doc_attribute_declaration(TreeState *state)
+{
+ IDL_tree attr = state->tree;
+
+ if (!verify_attribute_declaration(attr))
+ return FALSE;
+ /*
+ * Attribute idents can also take doc comments. They're ignored here;
+ * should they be?
+ */
+
+ if (IDL_ATTR_DCL(attr).f_readonly)
+ fprintf(state->file, "readonly ");
+
+ fprintf(state->file, "attribute ");
+
+ if (!write_type(IDL_ATTR_DCL(attr).param_type_spec, state->file))
+ return FALSE;
+
+ fprintf(state->file, "\n");
+ print_list(state->file, IDL_ATTR_DCL(attr).simple_declarations);
+ fprintf(state->file, "<br>\n");
+
+ return TRUE;
+}
+
+/* handle OP_DCL (method declaration) nodes */
+static gboolean
+doc_method_declaration(TreeState *state)
+{
+ /*
+ * Doc comment for attributes also applies here.
+ */
+
+ /*
+ * Look at 'write_method_signature' in xpidl_header.c for an example of how
+ * to navigate parse trees for methods. For here, I just print the method
+ * name.
+ */
+
+ fprintf(state->file,
+ "method %s<br>\n",
+ IDL_IDENT(IDL_OP_DCL(state->tree).ident).str);
+
+ return TRUE;
+}
+
+backend *
+xpidl_doc_dispatch(void)
+{
+ static backend result;
+ static nodeHandler table[IDLN_LAST];
+ static gboolean initialized = FALSE;
+
+ result.emit_prolog = doc_prolog;
+ result.emit_epilog = doc_epilog;
+
+ if (!initialized) {
+ /* Initialize non-NULL elements */
+
+ /* I just handle a few... many still to be filled in! */
+
+ table[IDLN_LIST] = doc_list;
+ table[IDLN_INTERFACE] = doc_interface;
+ table[IDLN_ATTR_DCL] = doc_attribute_declaration;
+ table[IDLN_OP_DCL] = doc_method_declaration;
+
+ initialized = TRUE;
+ }
+
+ result.dispatch_table = table;
+ return &result;
+}
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpidl/xpidl_header.c b/src/libs/xpcom18a4/xpcom/typelib/xpidl/xpidl_header.c
new file mode 100644
index 00000000..f4fe9d5b
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpidl/xpidl_header.c
@@ -0,0 +1,1196 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: NPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Netscape 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/NPL/
+ *
+ * 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 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 NPL, 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 NPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * Generate XPCOM headers from XPIDL.
+ */
+
+#include "xpidl.h"
+#include <ctype.h>
+
+#define AS_DECL 0
+#define AS_CALL 1
+#define AS_IMPL 2
+
+static gboolean write_method_signature(IDL_tree method_tree, FILE *outfile,
+ int mode, const char *className);
+static gboolean write_attr_accessor(IDL_tree attr_tree, FILE * outfile,
+ gboolean getter,
+ int mode, const char *className);
+
+static void
+write_indent(FILE *outfile) {
+ fputs(" ", outfile);
+}
+
+static gboolean
+header_prolog(TreeState *state)
+{
+ char *define = xpidl_basename(state->basename);
+ fprintf(state->file, "/*\n * DO NOT EDIT. THIS FILE IS GENERATED FROM"
+ " %s.idl\n */\n", state->basename);
+ fprintf(state->file,
+ "\n#ifndef __gen_%s_h__\n"
+ "#define __gen_%s_h__\n",
+ define, define);
+ g_free(define);
+ if (state->base_includes != NULL) {
+ guint len = g_slist_length(state->base_includes);
+ guint i;
+
+ fputc('\n', state->file);
+ for (i = 0; i < len; i++) {
+ char *ident, *dot;
+
+ ident = (char *)g_slist_nth_data(state->base_includes, i);
+
+ /* suppress any trailing .extension */
+
+ /* XXX use g_basename instead ? ? */
+
+ dot = strrchr(ident, '.');
+ if (dot != NULL)
+ *dot = '\0';
+
+
+ /* begin include guard */
+ fprintf(state->file,
+ "\n#ifndef __gen_%s_h__\n",
+ ident);
+
+ fprintf(state->file, "#include \"%s.h\"\n",
+ (char *)g_slist_nth_data(state->base_includes, i));
+
+ fprintf(state->file, "#endif\n");
+
+ }
+ if (i > 0)
+ fputc('\n', state->file);
+ }
+ /*
+ * Support IDL files that don't include a root IDL file that defines
+ * NS_NO_VTABLE.
+ */
+ fprintf(state->file,
+ "/* For IDL files that don't want to include root IDL files. */\n"
+ "#ifndef NS_NO_VTABLE\n"
+ "#define NS_NO_VTABLE\n"
+ "#endif\n");
+
+ return TRUE;
+}
+
+static gboolean
+header_epilog(TreeState *state)
+{
+ char *define = xpidl_basename(state->basename);
+ fprintf(state->file, "\n#endif /* __gen_%s_h__ */\n", define);
+ g_free(define);
+ return TRUE;
+}
+
+static void
+write_classname_iid_define(FILE *file, const char *className)
+{
+ const char *iidName;
+ if (className[0] == 'n' && className[1] == 's') {
+ /* backcompat naming styles */
+ fputs("NS_", file);
+ iidName = className + 2;
+ } else {
+ iidName = className;
+ }
+ while (*iidName)
+ fputc(toupper(*iidName++), file);
+ fputs("_IID", file);
+}
+
+static gboolean
+interface(TreeState *state)
+{
+ IDL_tree iface = state->tree, iter, orig;
+ char *className = IDL_IDENT(IDL_INTERFACE(iface).ident).str;
+ char *classNameUpper = NULL;
+ char *classNameImpl = NULL;
+ char *cp;
+ gboolean ok = TRUE;
+ gboolean keepvtable;
+ const char *iid;
+ const char *name_space;
+ struct nsID id;
+ char iid_parsed[UUID_LENGTH];
+ GSList *doc_comments = IDL_IDENT(IDL_INTERFACE(iface).ident).comments;
+
+ if (!verify_interface_declaration(iface))
+ return FALSE;
+
+#define FAIL do {ok = FALSE; goto out;} while(0)
+
+ fprintf(state->file, "\n/* starting interface: %s */\n",
+ className);
+
+ name_space = IDL_tree_property_get(IDL_INTERFACE(iface).ident, "namespace");
+ if (name_space) {
+ fprintf(state->file, "/* namespace: %s */\n",
+ name_space);
+ fprintf(state->file, "/* fully qualified name: %s.%s */\n",
+ name_space,className);
+ }
+
+ iid = IDL_tree_property_get(IDL_INTERFACE(iface).ident, "uuid");
+ if (iid) {
+ /* Redundant, but a better error than 'cannot parse.' */
+ if (strlen(iid) != 36) {
+ IDL_tree_error(state->tree, "IID %s is the wrong length\n", iid);
+ FAIL;
+ }
+
+ /*
+ * Parse uuid and then output resulting nsID to string, to validate
+ * uuid and normalize resulting .h files.
+ */
+ if (!xpidl_parse_iid(&id, iid)) {
+ IDL_tree_error(state->tree, "cannot parse IID %s\n", iid);
+ FAIL;
+ }
+ if (!xpidl_sprint_iid(&id, iid_parsed)) {
+ IDL_tree_error(state->tree, "error formatting IID %s\n", iid);
+ FAIL;
+ }
+
+ /* #define NS_ISUPPORTS_IID_STR "00000000-0000-0000-c000-000000000046" */
+ fputs("#define ", state->file);
+ write_classname_iid_define(state->file, className);
+ fprintf(state->file, "_STR \"%s\"\n", iid_parsed);
+ fputc('\n', state->file);
+
+ /* #define NS_ISUPPORTS_IID { {0x00000000 .... 0x46 }} */
+ fprintf(state->file, "#define ");
+ write_classname_iid_define(state->file, className);
+ fprintf(state->file, " \\\n"
+ " {0x%.8x, 0x%.4x, 0x%.4x, \\\n"
+ " { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, "
+ "0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }}\n",
+ id.m0, id.m1, id.m2,
+ id.m3[0], id.m3[1], id.m3[2], id.m3[3],
+ id.m3[4], id.m3[5], id.m3[6], id.m3[7]);
+ fputc('\n', state->file);
+ } else {
+ IDL_tree_error(state->tree, "interface %s lacks a uuid attribute\n",
+ className);
+ FAIL;
+ }
+
+ if (doc_comments != NULL)
+ printlist(state->file, doc_comments);
+
+ /*
+ * NS_NO_VTABLE is defined in nsISupportsUtils.h, and defined on windows
+ * to __declspec(novtable) on windows. This optimization is safe
+ * whenever the constructor calls no virtual methods. Writing in IDL
+ * almost guarantees this, except for the case when a %{C++ block occurs in
+ * the interface. We detect that case, and emit a macro call that disables
+ * the optimization.
+ */
+ keepvtable = FALSE;
+ for (iter = IDL_INTERFACE(state->tree).body;
+ iter != NULL;
+ iter = IDL_LIST(iter).next)
+ {
+ IDL_tree data = IDL_LIST(iter).data;
+ if (IDL_NODE_TYPE(data) == IDLN_CODEFRAG)
+ keepvtable = TRUE;
+ }
+
+ /* The interface declaration itself. */
+ fprintf(state->file,
+ "class %s%s",
+ (keepvtable ? "" : "NS_NO_VTABLE "), className);
+
+ if ((iter = IDL_INTERFACE(iface).inheritance_spec)) {
+ fputs(" : ", state->file);
+ if (IDL_LIST(iter).next != NULL) {
+ IDL_tree_error(iter,
+ "multiple inheritance is not supported by xpidl");
+ FAIL;
+ }
+ fprintf(state->file, "public %s", IDL_IDENT(IDL_LIST(iter).data).str);
+ }
+ fputs(" {\n"
+ " public: \n\n", state->file);
+ if (iid) {
+ fputs(" NS_DEFINE_STATIC_IID_ACCESSOR(", state->file);
+ write_classname_iid_define(state->file, className);
+ fputs(")\n\n", state->file);
+ }
+
+ orig = state->tree; /* It would be nice to remove this state-twiddling. */
+
+ state->tree = IDL_INTERFACE(iface).body;
+
+ if (state->tree && !xpidl_process_node(state))
+ FAIL;
+
+ fputs("};\n", state->file);
+ fputc('\n', state->file);
+
+ /*
+ * #define NS_DECL_NSIFOO - create method prototypes that can be used in
+ * class definitions that support this interface.
+ *
+ * Walk the tree explicitly to prototype a reworking of xpidl to get rid of
+ * the callback mechanism.
+ */
+ state->tree = orig;
+ fputs("/* Use this macro when declaring classes that implement this "
+ "interface. */\n", state->file);
+ fputs("#define NS_DECL_", state->file);
+ classNameUpper = xpidl_strdup(className);
+ for (cp = classNameUpper; *cp != '\0'; cp++)
+ *cp = toupper(*cp);
+ fprintf(state->file, "%s \\\n", classNameUpper);
+ if (IDL_INTERFACE(state->tree).body == NULL) {
+ write_indent(state->file);
+ fputs("/* no methods! */\n", state->file);
+ }
+
+ for (iter = IDL_INTERFACE(state->tree).body;
+ iter != NULL;
+ iter = IDL_LIST(iter).next)
+ {
+ IDL_tree data = IDL_LIST(iter).data;
+
+ switch(IDL_NODE_TYPE(data)) {
+ case IDLN_OP_DCL:
+ write_indent(state->file);
+ write_method_signature(data, state->file, AS_DECL, NULL);
+ break;
+
+ case IDLN_ATTR_DCL:
+ write_indent(state->file);
+ if (!write_attr_accessor(data, state->file, TRUE, AS_DECL, NULL))
+ FAIL;
+ if (!IDL_ATTR_DCL(data).f_readonly) {
+ fputs("; \\\n", state->file); /* Terminate the previous one. */
+ write_indent(state->file);
+ if (!write_attr_accessor(data, state->file,
+ FALSE, AS_DECL, NULL))
+ FAIL;
+ /* '; \n' at end will clean up. */
+ }
+ break;
+
+ case IDLN_CONST_DCL:
+ /* ignore it here; it doesn't contribute to the macro. */
+ continue;
+
+ case IDLN_CODEFRAG:
+ XPIDL_WARNING((iter, IDL_WARNING1,
+ "%%{ .. %%} code fragment within interface "
+ "ignored when generating NS_DECL_%s macro; "
+ "if the code fragment contains method "
+ "declarations, the macro probably isn't "
+ "complete.", classNameUpper));
+ continue;
+
+ default:
+ IDL_tree_error(iter,
+ "unexpected node type %d! "
+ "Please file a bug against the xpidl component.",
+ IDL_NODE_TYPE(data));
+ FAIL;
+ }
+
+ if (IDL_LIST(iter).next != NULL) {
+ fprintf(state->file, "; \\\n");
+ } else {
+ fprintf(state->file, "; \n");
+ }
+ }
+ fputc('\n', state->file);
+
+ /* XXX abstract above and below into one function? */
+ /*
+ * #define NS_FORWARD_NSIFOO - create forwarding methods that can delegate
+ * behavior from in implementation to another object. As generated by
+ * idlc.
+ */
+ fprintf(state->file,
+ "/* Use this macro to declare functions that forward the "
+ "behavior of this interface to another object. */\n"
+ "#define NS_FORWARD_%s(_to) \\\n",
+ classNameUpper);
+ if (IDL_INTERFACE(state->tree).body == NULL) {
+ write_indent(state->file);
+ fputs("/* no methods! */\n", state->file);
+ }
+
+ for (iter = IDL_INTERFACE(state->tree).body;
+ iter != NULL;
+ iter = IDL_LIST(iter).next)
+ {
+ IDL_tree data = IDL_LIST(iter).data;
+
+ switch(IDL_NODE_TYPE(data)) {
+ case IDLN_OP_DCL:
+ write_indent(state->file);
+ write_method_signature(data, state->file, AS_DECL, NULL);
+ fputs(" { return _to ", state->file);
+ write_method_signature(data, state->file, AS_CALL, NULL);
+ break;
+
+ case IDLN_ATTR_DCL:
+ write_indent(state->file);
+ if (!write_attr_accessor(data, state->file, TRUE, AS_DECL, NULL))
+ FAIL;
+ fputs(" { return _to ", state->file);
+ if (!write_attr_accessor(data, state->file, TRUE, AS_CALL, NULL))
+ FAIL;
+ if (!IDL_ATTR_DCL(data).f_readonly) {
+ fputs("; } \\\n", state->file); /* Terminate the previous one. */
+ write_indent(state->file);
+ if (!write_attr_accessor(data, state->file,
+ FALSE, AS_DECL, NULL))
+ FAIL;
+ fputs(" { return _to ", state->file);
+ if (!write_attr_accessor(data, state->file,
+ FALSE, AS_CALL, NULL))
+ FAIL;
+ /* '; } \n' at end will clean up. */
+ }
+ break;
+
+ case IDLN_CONST_DCL:
+ case IDLN_CODEFRAG:
+ continue;
+
+ default:
+ FAIL;
+ }
+
+ if (IDL_LIST(iter).next != NULL) {
+ fprintf(state->file, "; } \\\n");
+ } else {
+ fprintf(state->file, "; } \n");
+ }
+ }
+ fputc('\n', state->file);
+
+
+ /* XXX abstract above and below into one function? */
+ /*
+ * #define NS_FORWARD_SAFE_NSIFOO - create forwarding methods that can delegate
+ * behavior from in implementation to another object. As generated by
+ * idlc.
+ */
+ fprintf(state->file,
+ "/* Use this macro to declare functions that forward the "
+ "behavior of this interface to another object in a safe way. */\n"
+ "#define NS_FORWARD_SAFE_%s(_to) \\\n",
+ classNameUpper);
+ if (IDL_INTERFACE(state->tree).body == NULL) {
+ write_indent(state->file);
+ fputs("/* no methods! */\n", state->file);
+ }
+
+ for (iter = IDL_INTERFACE(state->tree).body;
+ iter != NULL;
+ iter = IDL_LIST(iter).next)
+ {
+ IDL_tree data = IDL_LIST(iter).data;
+
+ switch(IDL_NODE_TYPE(data)) {
+ case IDLN_OP_DCL:
+ write_indent(state->file);
+ write_method_signature(data, state->file, AS_DECL, NULL);
+ fputs(" { return !_to ? NS_ERROR_NULL_POINTER : _to->", state->file);
+ write_method_signature(data, state->file, AS_CALL, NULL);
+ break;
+
+ case IDLN_ATTR_DCL:
+ write_indent(state->file);
+ if (!write_attr_accessor(data, state->file, TRUE, AS_DECL, NULL))
+ FAIL;
+ fputs(" { return !_to ? NS_ERROR_NULL_POINTER : _to->", state->file);
+ if (!write_attr_accessor(data, state->file, TRUE, AS_CALL, NULL))
+ FAIL;
+ if (!IDL_ATTR_DCL(data).f_readonly) {
+ fputs("; } \\\n", state->file); /* Terminate the previous one. */
+ write_indent(state->file);
+ if (!write_attr_accessor(data, state->file,
+ FALSE, AS_DECL, NULL))
+ FAIL;
+ fputs(" { return !_to ? NS_ERROR_NULL_POINTER : _to->", state->file);
+ if (!write_attr_accessor(data, state->file,
+ FALSE, AS_CALL, NULL))
+ FAIL;
+ /* '; } \n' at end will clean up. */
+ }
+ break;
+
+ case IDLN_CONST_DCL:
+ case IDLN_CODEFRAG:
+ continue;
+
+ default:
+ FAIL;
+ }
+
+ if (IDL_LIST(iter).next != NULL) {
+ fprintf(state->file, "; } \\\n");
+ } else {
+ fprintf(state->file, "; } \n");
+ }
+ }
+ fputc('\n', state->file);
+
+ /*
+ * Build a sample implementation template.
+ */
+ if (strlen(className) >= 3 && className[2] == 'I') {
+ classNameImpl = xpidl_strdup(className);
+ if (!classNameImpl)
+ FAIL;
+ memmove(&classNameImpl[2], &classNameImpl[3], strlen(classNameImpl) - 2);
+ } else {
+ classNameImpl = xpidl_strdup("_MYCLASS_");
+ if (!classNameImpl)
+ FAIL;
+ }
+
+ fputs("#if 0\n"
+ "/* Use the code below as a template for the "
+ "implementation class for this interface. */\n"
+ "\n"
+ "/* Header file */"
+ "\n",
+ state->file);
+ fprintf(state->file, "class %s : public %s\n", classNameImpl, className);
+ fputs("{\n"
+ "public:\n", state->file);
+ write_indent(state->file);
+ fputs("NS_DECL_ISUPPORTS\n", state->file);
+ write_indent(state->file);
+ fprintf(state->file, "NS_DECL_%s\n", classNameUpper);
+ fputs("\n", state->file);
+ write_indent(state->file);
+ fprintf(state->file, "%s();\n", classNameImpl);
+ fputs("\n"
+ "private:\n", state->file);
+ write_indent(state->file);
+ fprintf(state->file, "~%s();\n", classNameImpl);
+ fputs("\n"
+ "protected:\n", state->file);
+ write_indent(state->file);
+ fputs("/* additional members */\n", state->file);
+ fputs("};\n\n", state->file);
+
+ fputs("/* Implementation file */\n", state->file);
+
+ fprintf(state->file,
+ "NS_IMPL_ISUPPORTS1(%s, %s)\n", classNameImpl, className);
+ fputs("\n", state->file);
+
+ fprintf(state->file, "%s::%s()\n", classNameImpl, classNameImpl);
+ fputs("{\n", state->file);
+ write_indent(state->file);
+ fputs("/* member initializers and constructor code */\n", state->file);
+ fputs("}\n\n", state->file);
+
+ fprintf(state->file, "%s::~%s()\n", classNameImpl, classNameImpl);
+ fputs("{\n", state->file);
+ write_indent(state->file);
+ fputs("/* destructor code */\n", state->file);
+ fputs("}\n\n", state->file);
+
+ for (iter = IDL_INTERFACE(state->tree).body;
+ iter != NULL;
+ iter = IDL_LIST(iter).next)
+ {
+ IDL_tree data = IDL_LIST(iter).data;
+
+ switch(IDL_NODE_TYPE(data)) {
+ case IDLN_OP_DCL:
+ /* It would be nice to remove this state-twiddling. */
+ orig = state->tree;
+ state->tree = data;
+ xpidl_write_comment(state, 0);
+ state->tree = orig;
+
+ write_method_signature(data, state->file, AS_IMPL, classNameImpl);
+ fputs("\n{\n", state->file);
+ write_indent(state->file);
+ write_indent(state->file);
+ fputs("return NS_ERROR_NOT_IMPLEMENTED;\n"
+ "}\n"
+ "\n", state->file);
+ break;
+
+ case IDLN_ATTR_DCL:
+ /* It would be nice to remove this state-twiddling. */
+ orig = state->tree;
+ state->tree = data;
+ xpidl_write_comment(state, 0);
+ state->tree = orig;
+
+ if (!write_attr_accessor(data, state->file, TRUE,
+ AS_IMPL, classNameImpl))
+ FAIL;
+ fputs("\n{\n", state->file);
+ write_indent(state->file);
+ write_indent(state->file);
+ fputs("return NS_ERROR_NOT_IMPLEMENTED;\n"
+ "}\n", state->file);
+
+ if (!IDL_ATTR_DCL(data).f_readonly) {
+ if (!write_attr_accessor(data, state->file, FALSE,
+ AS_IMPL, classNameImpl))
+ FAIL;
+ fputs("\n{\n", state->file);
+ write_indent(state->file);
+ write_indent(state->file);
+ fputs("return NS_ERROR_NOT_IMPLEMENTED;\n"
+ "}\n", state->file);
+ }
+ fputs("\n", state->file);
+ break;
+
+ case IDLN_CONST_DCL:
+ case IDLN_CODEFRAG:
+ continue;
+
+ default:
+ FAIL;
+ }
+ }
+
+ fputs("/* End of implementation class template. */\n"
+ "#endif\n"
+ "\n", state->file);
+
+#undef FAIL
+
+out:
+ if (classNameUpper)
+ free(classNameUpper);
+ if (classNameImpl)
+ free(classNameImpl);
+ return ok;
+}
+
+static gboolean
+list(TreeState *state)
+{
+ IDL_tree iter;
+ for (iter = state->tree; iter; iter = IDL_LIST(iter).next) {
+ state->tree = IDL_LIST(iter).data;
+ if (!xpidl_process_node(state))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static gboolean
+write_type(IDL_tree type_tree, gboolean is_out, FILE *outfile)
+{
+ if (!type_tree) {
+ fputs("void", outfile);
+ return TRUE;
+ }
+
+ switch (IDL_NODE_TYPE(type_tree)) {
+ case IDLN_TYPE_INTEGER: {
+ gboolean sign = IDL_TYPE_INTEGER(type_tree).f_signed;
+ switch (IDL_TYPE_INTEGER(type_tree).f_type) {
+ case IDL_INTEGER_TYPE_SHORT:
+ fputs(sign ? "PRInt16" : "PRUint16", outfile);
+ break;
+ case IDL_INTEGER_TYPE_LONG:
+ fputs(sign ? "PRInt32" : "PRUint32", outfile);
+ break;
+ case IDL_INTEGER_TYPE_LONGLONG:
+ fputs(sign ? "PRInt64" : "PRUint64", outfile);
+ break;
+ default:
+ g_error("Unknown integer type %d\n",
+ IDL_TYPE_INTEGER(type_tree).f_type);
+ return FALSE;
+ }
+ break;
+ }
+ case IDLN_TYPE_CHAR:
+ fputs("char", outfile);
+ break;
+ case IDLN_TYPE_WIDE_CHAR:
+ fputs("PRUnichar", outfile); /* wchar_t? */
+ break;
+ case IDLN_TYPE_WIDE_STRING:
+ fputs("PRUnichar *", outfile);
+ break;
+ case IDLN_TYPE_STRING:
+ fputs("char *", outfile);
+ break;
+ case IDLN_TYPE_BOOLEAN:
+ fputs("PRBool", outfile);
+ break;
+ case IDLN_TYPE_OCTET:
+ fputs("PRUint8", outfile);
+ break;
+ case IDLN_TYPE_FLOAT:
+ switch (IDL_TYPE_FLOAT(type_tree).f_type) {
+ case IDL_FLOAT_TYPE_FLOAT:
+ fputs("float", outfile);
+ break;
+ case IDL_FLOAT_TYPE_DOUBLE:
+ fputs("double", outfile);
+ break;
+ /* XXX 'long double' just ignored, or what? */
+ default:
+ fprintf(outfile, "unknown_type_%d", IDL_NODE_TYPE(type_tree));
+ break;
+ }
+ break;
+ case IDLN_IDENT:
+ if (UP_IS_NATIVE(type_tree)) {
+ if (IDL_tree_property_get(type_tree, "domstring") ||
+ IDL_tree_property_get(type_tree, "astring")) {
+ fputs("nsAString", outfile);
+ } else if (IDL_tree_property_get(type_tree, "utf8string")) {
+ fputs("nsACString", outfile);
+ } else if (IDL_tree_property_get(type_tree, "cstring")) {
+ fputs("nsACString", outfile);
+ } else {
+ fputs(IDL_NATIVE(IDL_NODE_UP(type_tree)).user_type, outfile);
+ }
+ if (IDL_tree_property_get(type_tree, "ptr")) {
+ fputs(" *", outfile);
+ } else if (IDL_tree_property_get(type_tree, "ref")) {
+ fputs(" &", outfile);
+ }
+ } else {
+ fputs(IDL_IDENT(type_tree).str, outfile);
+ }
+ if (UP_IS_AGGREGATE(type_tree))
+ fputs(" *", outfile);
+ break;
+ default:
+ fprintf(outfile, "unknown_type_%d", IDL_NODE_TYPE(type_tree));
+ break;
+ }
+ return TRUE;
+}
+
+/*
+ * An attribute declaration looks like:
+ *
+ * [ IDL_ATTR_DCL]
+ * - param_type_spec [IDL_TYPE_* or NULL for void]
+ * - simple_declarations [IDL_LIST]
+ * - data [IDL_IDENT]
+ * - next [IDL_LIST or NULL if no more idents]
+ * - data [IDL_IDENT]
+ */
+
+#define ATTR_IDENT(tree) (IDL_IDENT(IDL_LIST(IDL_ATTR_DCL(tree).simple_declarations).data))
+#define ATTR_TYPE_DECL(tree) (IDL_ATTR_DCL(tree).param_type_spec)
+#define ATTR_TYPE(tree) (IDL_NODE_TYPE(ATTR_TYPE_DECL(tree)))
+
+/*
+ * AS_DECL writes 'NS_IMETHOD foo(string bar, long sil)'
+ * AS_IMPL writes 'NS_IMETHODIMP className::foo(string bar, long sil)'
+ * AS_CALL writes 'foo(bar, sil)'
+ */
+static gboolean
+write_attr_accessor(IDL_tree attr_tree, FILE * outfile,
+ gboolean getter, int mode, const char *className)
+{
+ char *attrname = ATTR_IDENT(attr_tree).str;
+
+ if (mode == AS_DECL) {
+ fputs("NS_IMETHOD ", outfile);
+ } else if (mode == AS_IMPL) {
+ fprintf(outfile, "NS_IMETHODIMP %s::", className);
+ }
+ fprintf(outfile, "%cet%c%s(",
+ getter ? 'G' : 'S',
+ toupper(*attrname), attrname + 1);
+ if (mode == AS_DECL || mode == AS_IMPL) {
+ /* Setters for string, wstring, nsid, domstring, utf8string,
+ * cstring and astring get const.
+ */
+ if (!getter &&
+ (IDL_NODE_TYPE(ATTR_TYPE_DECL(attr_tree)) == IDLN_TYPE_STRING ||
+ IDL_NODE_TYPE(ATTR_TYPE_DECL(attr_tree)) == IDLN_TYPE_WIDE_STRING ||
+ IDL_tree_property_get(ATTR_TYPE_DECL(attr_tree), "nsid") ||
+ IDL_tree_property_get(ATTR_TYPE_DECL(attr_tree), "domstring") ||
+ IDL_tree_property_get(ATTR_TYPE_DECL(attr_tree), "utf8string") ||
+ IDL_tree_property_get(ATTR_TYPE_DECL(attr_tree), "cstring") ||
+ IDL_tree_property_get(ATTR_TYPE_DECL(attr_tree), "astring")))
+ {
+ fputs("const ", outfile);
+ }
+
+ if (!write_type(ATTR_TYPE_DECL(attr_tree), getter, outfile))
+ return FALSE;
+ fprintf(outfile, "%s%s",
+ (STARRED_TYPE(attr_tree) ? "" : " "),
+ (getter && !DIPPER_TYPE(ATTR_TYPE_DECL(attr_tree)))? "*" : "");
+ }
+ fprintf(outfile, "a%c%s)", toupper(attrname[0]), attrname + 1);
+ return TRUE;
+}
+
+static gboolean
+attr_dcl(TreeState *state)
+{
+ GSList *doc_comments;
+
+ if (!verify_attribute_declaration(state->tree))
+ return FALSE;
+
+ doc_comments =
+ IDL_IDENT(IDL_LIST(IDL_ATTR_DCL
+ (state->tree).simple_declarations).data).comments;
+
+ if (doc_comments != NULL) {
+ write_indent(state->file);
+ printlist(state->file, doc_comments);
+ }
+
+ /*
+ * XXX lists of attributes with the same type, e.g.
+ * attribute string foo, bar sil;
+ * are legal IDL... but we don't do anything with 'em.
+ */
+ if (IDL_LIST(IDL_ATTR_DCL(state->tree).simple_declarations).next != NULL) {
+ XPIDL_WARNING((state->tree, IDL_WARNING1,
+ "multiple attributes in a single declaration aren't "
+ "currently supported by xpidl"));
+ }
+
+ xpidl_write_comment(state, 2);
+
+ write_indent(state->file);
+ if (!write_attr_accessor(state->tree, state->file, TRUE, AS_DECL, NULL))
+ return FALSE;
+ fputs(" = 0;\n", state->file);
+
+ if (!IDL_ATTR_DCL(state->tree).f_readonly) {
+ write_indent(state->file);
+ if (!write_attr_accessor(state->tree, state->file, FALSE, AS_DECL, NULL))
+ return FALSE;
+ fputs(" = 0;\n", state->file);
+ }
+ fputc('\n', state->file);
+
+ return TRUE;
+}
+
+static gboolean
+do_enum(TreeState *state)
+{
+ IDL_tree_error(state->tree, "enums not supported, "
+ "see http://bugzilla.mozilla.org/show_bug.cgi?id=8781");
+ return FALSE;
+}
+
+static gboolean
+do_const_dcl(TreeState *state)
+{
+ struct _IDL_CONST_DCL *dcl = &IDL_CONST_DCL(state->tree);
+ const char *name = IDL_IDENT(dcl->ident).str;
+ gboolean is_signed;
+ GSList *doc_comments = IDL_IDENT(dcl->ident).comments;
+ IDL_tree real_type;
+ const char *const_format;
+
+ if (!verify_const_declaration(state->tree))
+ return FALSE;
+
+ if (doc_comments != NULL) {
+ write_indent(state->file);
+ printlist(state->file, doc_comments);
+ }
+
+ /* Could be a typedef; try to map it to the real type. */
+ real_type = find_underlying_type(dcl->const_type);
+ real_type = real_type ? real_type : dcl->const_type;
+ is_signed = IDL_TYPE_INTEGER(real_type).f_signed;
+
+ const_format = is_signed ? "%" IDL_LL "d" : "%" IDL_LL "uU";
+ write_indent(state->file);
+ fprintf(state->file, "enum { %s = ", name);
+ fprintf(state->file, const_format, IDL_INTEGER(dcl->const_exp).value);
+ fprintf(state->file, " };\n\n");
+
+ return TRUE;
+}
+
+static gboolean
+do_typedef(TreeState *state)
+{
+ IDL_tree type = IDL_TYPE_DCL(state->tree).type_spec;
+ IDL_tree dcls = IDL_TYPE_DCL(state->tree).dcls;
+ IDL_tree complex;
+ GSList *doc_comments;
+
+ if (IDL_NODE_TYPE(type) == IDLN_TYPE_SEQUENCE) {
+ XPIDL_WARNING((state->tree, IDL_WARNING1,
+ "sequences not supported, ignored"));
+ } else {
+ if (IDL_NODE_TYPE(complex = IDL_LIST(dcls).data) == IDLN_TYPE_ARRAY) {
+ IDL_tree dim = IDL_TYPE_ARRAY(complex).size_list;
+ doc_comments = IDL_IDENT(IDL_TYPE_ARRAY(complex).ident).comments;
+
+ if (doc_comments != NULL)
+ printlist(state->file, doc_comments);
+
+ fputs("typedef ", state->file);
+ if (!write_type(type, FALSE, state->file))
+ return FALSE;
+ fputs(" ", state->file);
+
+ fprintf(state->file, "%s",
+ IDL_IDENT(IDL_TYPE_ARRAY(complex).ident).str);
+ do {
+ fputc('[', state->file);
+ if (IDL_LIST(dim).data) {
+ fprintf(state->file, "%ld",
+ (long)IDL_INTEGER(IDL_LIST(dim).data).value);
+ }
+ fputc(']', state->file);
+ } while ((dim = IDL_LIST(dim).next) != NULL);
+ } else {
+ doc_comments = IDL_IDENT(IDL_LIST(dcls).data).comments;
+
+ if (doc_comments != NULL)
+ printlist(state->file, doc_comments);
+
+ fputs("typedef ", state->file);
+ if (!write_type(type, FALSE, state->file))
+ return FALSE;
+ fputs(" ", state->file);
+ fputs(IDL_IDENT(IDL_LIST(dcls).data).str, state->file);
+ }
+ fputs(";\n\n", state->file);
+ }
+ return TRUE;
+}
+
+/*
+ * param generation:
+ * in string foo --> nsString *foo
+ * out string foo --> nsString **foo;
+ * inout string foo --> nsString **foo;
+ */
+
+/* If notype is true, just write the param name. */
+static gboolean
+write_param(IDL_tree param_tree, FILE *outfile)
+{
+ IDL_tree param_type_spec = IDL_PARAM_DCL(param_tree).param_type_spec;
+ gboolean is_in = IDL_PARAM_DCL(param_tree).attr == IDL_PARAM_IN;
+ /* in string, wstring, nsid, domstring, utf8string, cstring and
+ * astring any explicitly marked [const] are const
+ */
+
+ if (is_in &&
+ (IDL_NODE_TYPE(param_type_spec) == IDLN_TYPE_STRING ||
+ IDL_NODE_TYPE(param_type_spec) == IDLN_TYPE_WIDE_STRING ||
+ IDL_tree_property_get(IDL_PARAM_DCL(param_tree).simple_declarator,
+ "const") ||
+ IDL_tree_property_get(param_type_spec, "nsid") ||
+ IDL_tree_property_get(param_type_spec, "domstring") ||
+ IDL_tree_property_get(param_type_spec, "utf8string") ||
+ IDL_tree_property_get(param_type_spec, "cstring") ||
+ IDL_tree_property_get(param_type_spec, "astring"))) {
+ fputs("const ", outfile);
+ }
+ else if (IDL_PARAM_DCL(param_tree).attr == IDL_PARAM_OUT &&
+ IDL_tree_property_get(IDL_PARAM_DCL(param_tree).simple_declarator,
+ "shared")) {
+ fputs("const ", outfile);
+ }
+
+ if (!write_type(param_type_spec, !is_in, outfile))
+ return FALSE;
+
+ /* unless the type ended in a *, add a space */
+ if (!STARRED_TYPE(param_type_spec))
+ fputc(' ', outfile);
+
+ /* out and inout params get a bonus '*' (unless this is type that has a
+ * 'dipper' class that is passed in to receive 'out' data)
+ */
+ if (IDL_PARAM_DCL(param_tree).attr != IDL_PARAM_IN &&
+ !DIPPER_TYPE(param_type_spec)) {
+ fputc('*', outfile);
+ }
+ /* arrays get a bonus * too */
+ /* XXX Should this be a leading '*' or a trailing "[]" ?*/
+ if (IDL_tree_property_get(IDL_PARAM_DCL(param_tree).simple_declarator,
+ "array"))
+ fputc('*', outfile);
+
+ fputs(IDL_IDENT(IDL_PARAM_DCL(param_tree).simple_declarator).str, outfile);
+
+ return TRUE;
+}
+
+/*
+ * A forward declaration, usually an interface.
+ */
+static gboolean
+forward_dcl(TreeState *state)
+{
+ IDL_tree iface = state->tree;
+ const char *className = IDL_IDENT(IDL_FORWARD_DCL(iface).ident).str;
+
+ if (!className)
+ return FALSE;
+
+ fprintf(state->file, "class %s; /* forward declaration */\n\n", className);
+ return TRUE;
+}
+
+/*
+ * Shared between the interface class declaration and the NS_DECL_IFOO macro
+ * provided to aid declaration of implementation classes.
+ * mode...
+ * AS_DECL writes 'NS_IMETHOD foo(string bar, long sil)'
+ * AS_IMPL writes 'NS_IMETHODIMP className::foo(string bar, long sil)'
+ * AS_CALL writes 'foo(bar, sil)'
+ */
+static gboolean
+write_method_signature(IDL_tree method_tree, FILE *outfile, int mode,
+ const char *className)
+{
+ struct _IDL_OP_DCL *op = &IDL_OP_DCL(method_tree);
+ gboolean no_generated_args = TRUE;
+ gboolean op_notxpcom =
+ (IDL_tree_property_get(op->ident, "notxpcom") != NULL);
+ const char *name;
+ IDL_tree iter;
+
+ if (mode == AS_DECL) {
+ if (op_notxpcom) {
+ fputs("NS_IMETHOD_(", outfile);
+ if (!write_type(op->op_type_spec, FALSE, outfile))
+ return FALSE;
+ fputc(')', outfile);
+ } else {
+ fputs("NS_IMETHOD", outfile);
+ }
+ fputc(' ', outfile);
+ }
+ else if (mode == AS_IMPL) {
+ if (op_notxpcom) {
+ fputs("NS_IMETHODIMP_(", outfile);
+ if (!write_type(op->op_type_spec, FALSE, outfile))
+ return FALSE;
+ fputc(')', outfile);
+ } else {
+ fputs("NS_IMETHODIMP", outfile);
+ }
+ fputc(' ', outfile);
+ }
+ name = IDL_IDENT(op->ident).str;
+ if (mode == AS_IMPL) {
+ fprintf(outfile, "%s::%c%s(", className, toupper(*name), name + 1);
+ } else {
+ fprintf(outfile, "%c%s(", toupper(*name), name + 1);
+ }
+ for (iter = op->parameter_dcls; iter; iter = IDL_LIST(iter).next) {
+ if (mode == AS_DECL || mode == AS_IMPL) {
+ if (!write_param(IDL_LIST(iter).data, outfile))
+ return FALSE;
+ } else {
+ fputs(IDL_IDENT(IDL_PARAM_DCL(IDL_LIST(iter).data)
+ .simple_declarator).str,
+ outfile);
+ }
+ if ((IDL_LIST(iter).next ||
+ (!op_notxpcom && op->op_type_spec) || op->f_varargs))
+ fputs(", ", outfile);
+ no_generated_args = FALSE;
+ }
+
+ /* make IDL return value into trailing out argument */
+ if (op->op_type_spec && !op_notxpcom) {
+ IDL_tree fake_param = IDL_param_dcl_new(IDL_PARAM_OUT,
+ op->op_type_spec,
+ IDL_ident_new("_retval"));
+ if (!fake_param)
+ return FALSE;
+ if (mode == AS_DECL || mode == AS_IMPL) {
+ if (!write_param(fake_param, outfile))
+ return FALSE;
+ } else {
+ fputs("_retval", outfile);
+ }
+ if (op->f_varargs)
+ fputs(", ", outfile);
+ no_generated_args = FALSE;
+ }
+
+ /* varargs go last */
+ if (op->f_varargs) {
+ if (mode == AS_DECL || mode == AS_IMPL) {
+ fputs("nsVarArgs *", outfile);
+ }
+ fputs("_varargs", outfile);
+ no_generated_args = FALSE;
+ }
+
+ /*
+ * If generated method has no arguments, output 'void' to avoid C legacy
+ * behavior of disabling type checking.
+ */
+ if (no_generated_args && mode == AS_DECL) {
+ fputs("void", outfile);
+ }
+
+ fputc(')', outfile);
+
+ return TRUE;
+}
+
+/*
+ * A method is an `operation', therefore a method decl is an `op dcl'.
+ * I blame Elliot.
+ */
+static gboolean
+op_dcl(TreeState *state)
+{
+ GSList *doc_comments = IDL_IDENT(IDL_OP_DCL(state->tree).ident).comments;
+
+ /*
+ * Verify that e.g. non-scriptable methods in [scriptable] interfaces
+ * are declared so. Do this in a separate verification pass?
+ */
+ if (!verify_method_declaration(state->tree))
+ return FALSE;
+
+ if (doc_comments != NULL) {
+ write_indent(state->file);
+ printlist(state->file, doc_comments);
+ }
+ xpidl_write_comment(state, 2);
+
+ write_indent(state->file);
+ if (!write_method_signature(state->tree, state->file, AS_DECL, NULL))
+ return FALSE;
+ fputs(" = 0;\n\n", state->file);
+
+ return TRUE;
+}
+
+static void
+write_codefrag_line(gpointer data, gpointer user_data)
+{
+ TreeState *state = (TreeState *)user_data;
+ const char *line = (const char *)data;
+ fputs(line, state->file);
+ fputc('\n', state->file);
+}
+
+static gboolean
+codefrag(TreeState *state)
+{
+ const char *desc = IDL_CODEFRAG(state->tree).desc;
+ GSList *lines = IDL_CODEFRAG(state->tree).lines;
+ guint fragment_length;
+
+ if (strcmp(desc, "C++") && /* libIDL bug? */ strcmp(desc, "C++\r")) {
+ XPIDL_WARNING((state->tree, IDL_WARNING1,
+ "ignoring '%%{%s' escape. "
+ "(Use '%%{C++' to escape verbatim C++ code.)", desc));
+
+ return TRUE;
+ }
+
+ /*
+ * Emit #file directive to point debuggers back to the original .idl file
+ * for the duration of the code fragment. We look at internal IDL node
+ * properties _file, _line to do this; hopefully they won't change.
+ *
+ * _line seems to refer to the line immediately after the closing %}, so
+ * we backtrack to get the proper line for the beginning of the block.
+ */
+ /*
+ * Looks like getting this right means maintaining an accurate line
+ * count of everything generated, so we can set the file back to the
+ * correct line in the generated file afterwards. Skipping for now...
+ */
+
+ fragment_length = g_slist_length(lines);
+/* fprintf(state->file, "#line %d \"%s\"\n", */
+/* state->tree->_line - fragment_length - 1, */
+/* state->tree->_file); */
+
+ g_slist_foreach(lines, write_codefrag_line, (gpointer)state);
+
+ return TRUE;
+}
+
+backend *
+xpidl_header_dispatch(void)
+{
+ static backend result;
+ static nodeHandler table[IDLN_LAST];
+ static gboolean initialized = FALSE;
+
+ result.emit_prolog = header_prolog;
+ result.emit_epilog = header_epilog;
+
+ if (!initialized) {
+ table[IDLN_LIST] = list;
+ table[IDLN_ATTR_DCL] = attr_dcl;
+ table[IDLN_OP_DCL] = op_dcl;
+ table[IDLN_FORWARD_DCL] = forward_dcl;
+ table[IDLN_TYPE_ENUM] = do_enum;
+ table[IDLN_INTERFACE] = interface;
+ table[IDLN_CODEFRAG] = codefrag;
+ table[IDLN_TYPE_DCL] = do_typedef;
+ table[IDLN_CONST_DCL] = do_const_dcl;
+ table[IDLN_NATIVE] = check_native;
+ initialized = TRUE;
+ }
+
+ result.dispatch_table = table;
+ return &result;
+}
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpidl/xpidl_idl.c b/src/libs/xpcom18a4/xpcom/typelib/xpidl/xpidl_idl.c
new file mode 100644
index 00000000..175f379a
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpidl/xpidl_idl.c
@@ -0,0 +1,836 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: NPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Netscape 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/NPL/
+ *
+ * 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):
+ * Michael Ang <mang@subcarrier.org>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either 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 NPL, 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 NPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * Common IDL-processing code.
+ */
+
+#include "xpidl.h"
+
+#ifdef XP_MAC
+#include <stat.h>
+#endif
+
+static gboolean parsed_empty_file;
+
+/*
+ * The bulk of the generation happens here.
+ */
+gboolean
+xpidl_process_node(TreeState *state)
+{
+ gint type;
+ nodeHandler *dispatch, handler;
+
+ XPT_ASSERT(state->tree);
+ type = IDL_NODE_TYPE(state->tree);
+
+ if ((dispatch = state->dispatch) && (handler = dispatch[type]))
+ return handler(state);
+ return TRUE;
+}
+
+#if defined(XP_MAC) && defined(XPIDL_PLUGIN)
+extern void mac_warning(const char* warning_message);
+#endif
+
+static int
+msg_callback(int level, int num, int line, const char *file,
+ const char *message)
+{
+ char *warning_message;
+
+ /*
+ * Egregious hack to permit empty files.
+ * XXX libIDL needs an API to detect this case robustly.
+ */
+ if (0 == strcmp(message, "File empty after optimization")) {
+ parsed_empty_file = TRUE;
+ return 1;
+ }
+
+ if (!file)
+ file = "<unknown file>";
+ warning_message = g_strdup_printf("%s:%d: %s\n", file, line, message);
+
+#if defined(XP_MAC) && defined(XPIDL_PLUGIN)
+ mac_warning(warning_message);
+#else
+ fputs(warning_message, stderr);
+#endif
+
+ g_free(warning_message);
+ return 1;
+}
+
+/*
+ * To keep track of the state associated with a given input file. The 'next'
+ * field lets us maintain a stack of input files.
+ */
+typedef struct input_data {
+ char *filename; /* where did I come from? */
+ unsigned int lineno; /* last lineno processed */
+ char *buf; /* contents of file */
+ char *point; /* next char to feed to libIDL */
+ char *max; /* 1 past last char in buf */
+ struct input_data *next; /* file from which we were included */
+} input_data;
+
+/*
+ * Passed to us by libIDL. Holds global information and the current stack of
+ * include files.
+ */
+typedef struct input_callback_state {
+ struct input_data *input_stack; /* linked list of input_data */
+ GHashTable *already_included; /* to prevent redundant includes */
+ IncludePathEntry *include_path; /* search path for included files */
+ GSList *base_includes; /* to accumulate #includes from *first* file;
+ * for passing thru TreeState to
+ * xpidl_header backend. */
+} input_callback_state;
+
+static FILE *
+fopen_from_includes(const char *filename, const char *mode,
+ IncludePathEntry *include_path)
+{
+ IncludePathEntry *current_path = include_path;
+ char *pathname;
+ FILE *inputfile;
+ if (!strcmp(filename, "-"))
+ return stdin;
+
+ if (filename[0] != '/') {
+ while (current_path) {
+ pathname = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s",
+ current_path->directory, filename);
+ if (!pathname)
+ return NULL;
+ inputfile = fopen(pathname, mode);
+ g_free(pathname);
+ if (inputfile)
+ return inputfile;
+ current_path = current_path->next;
+ }
+ } else {
+ inputfile = fopen(filename, mode);
+ if (inputfile)
+ return inputfile;
+ }
+ return NULL;
+}
+
+#if defined(XP_MAC) && defined(XPIDL_PLUGIN)
+extern FILE* mac_fopen(const char* filename, const char *mode);
+#endif
+
+static input_data *
+new_input_data(const char *filename, IncludePathEntry *include_path)
+{
+ input_data *new_data;
+ FILE *inputfile;
+ char *buffer = NULL;
+ size_t offset = 0;
+ size_t buffer_size;
+#ifdef XP_MAC
+ size_t i;
+#endif
+
+#if defined(XP_MAC) && defined(XPIDL_PLUGIN)
+ /* on Mac, fopen knows how to find files. */
+ inputfile = fopen(filename, "r");
+#elif defined(XP_OS2) || defined(XP_WIN32)
+ /*
+ * if filename is fully qualified (starts with driver letter), then
+ * just call fopen(); else, go with fopen_from_includes()
+ */
+ if( filename[1] == ':' )
+ inputfile = fopen(filename, "r");
+ else
+ inputfile = fopen_from_includes(filename, "r", include_path);
+#else
+ inputfile = fopen_from_includes(filename, "r", include_path);
+#endif
+
+ if (!inputfile)
+ return NULL;
+
+#ifdef XP_MAC
+ {
+ struct stat input_stat;
+ if (fstat(fileno(inputfile), &input_stat))
+ return NULL;
+ buffer = malloc(input_stat.st_size + 1);
+ if (!buffer)
+ return NULL;
+ offset = fread(buffer, 1, input_stat.st_size, inputfile);
+ if (ferror(inputfile))
+ return NULL;
+ }
+#else
+ /*
+ * Rather than try to keep track of many different varieties of state
+ * around the boundaries of a circular buffer, we just read in the entire
+ * file.
+ *
+ * We iteratively grow the buffer here; an alternative would be to use
+ * stat to find the exact buffer size we need, as xpt_dump does.
+ */
+ for (buffer_size = 8191; ; buffer_size *= 2) {
+ size_t just_read;
+ buffer = realloc(buffer, buffer_size + 1); /* +1 for trailing nul */
+ just_read = fread(buffer + offset, 1, buffer_size - offset, inputfile);
+ if (ferror(inputfile))
+ return NULL;
+
+ if (just_read < buffer_size - offset || just_read == 0) {
+ /* Done reading. */
+ offset += just_read;
+ break;
+ }
+ offset += just_read;
+ }
+#endif
+
+ fclose(inputfile);
+
+#ifdef XP_MAC
+ /*
+ * libIDL doesn't speak '\r' properly - always make sure lines end with
+ * '\n'.
+ */
+ for (i = 0; i < offset; i++) {
+ if (buffer[i] == '\r')
+ buffer[i] = '\n';
+ }
+#endif
+
+ new_data = xpidl_malloc(sizeof (struct input_data));
+ new_data->point = new_data->buf = buffer;
+ new_data->max = buffer + offset;
+ *new_data->max = '\0';
+ new_data->filename = xpidl_strdup(filename);
+ /* libIDL expects the line number to be that of the *next* line */
+ new_data->lineno = 2;
+ new_data->next = NULL;
+
+ return new_data;
+}
+
+/* process pending raw section */
+static int
+NextIsRaw(input_data *data, char **startp, int *lenp)
+{
+ char *end, *start;
+
+ /*
+ * XXXmccabe still needed: an in_raw flag to handle the case where we're in
+ * a raw block, but haven't managed to copy it all to xpidl. This will
+ * happen when we have a raw block larger than
+ * IDL_input_data->fill.max_size (currently 8192.)
+ */
+ if (!(data->point[0] == '%' && data->point[1] == '{'))
+ return 0;
+
+ start = *startp = data->point;
+
+ end = NULL;
+ while (start < data->max && (end = strstr(start, "%}"))) {
+ if (end[-1] == '\r' ||
+ end[-1] == '\n')
+ break;
+ start = end + 1;
+ }
+
+ if (end && start < data->max) {
+ *lenp = end - data->point + 2;
+ return 1;
+ } else {
+ const char *filename;
+ int lineno;
+
+ IDL_file_get(&filename, &lineno);
+ msg_callback(IDL_ERROR, 0, lineno, filename,
+ "unterminated %{ block");
+ return -1;
+ }
+}
+
+/* process pending comment */
+static int
+NextIsComment(input_data *data, char **startp, int *lenp)
+{
+ char *end;
+
+ if (!(data->point[0] == '/' && data->point[1] == '*'))
+ return 0;
+
+ end = strstr(data->point, "*/");
+ *lenp = 0;
+ if (end) {
+ int skippedLines = 0;
+ char *tempPoint;
+
+ /* get current lineno */
+ IDL_file_get(NULL,(int *)&data->lineno);
+
+ /* get line count */
+ for (tempPoint = data->point; tempPoint < end; tempPoint++) {
+ if (*tempPoint == '\n')
+ skippedLines++;
+ }
+
+ data->lineno += skippedLines;
+ IDL_file_set(data->filename, (int)data->lineno);
+
+ *startp = end + 2;
+
+ /* If it's a ** comment, tell libIDL about it. */
+ if (data->point[2] == '*') {
+ /* hack termination. +2 to get past '*' '/' */
+ char t = *(end + 2);
+ *(end + 2) = '\0';
+ IDL_queue_new_ident_comment(data->point);
+ *(end + 2) = t;
+ }
+
+ data->point = *startp; /* XXXmccabe move this out of function? */
+ return 1;
+ } else {
+ const char *filename;
+ int lineno;
+
+ IDL_file_get(&filename, &lineno);
+ msg_callback(IDL_ERROR, 0, lineno, filename,
+ "unterminated comment");
+ return -1;
+ }
+}
+
+static int
+NextIsInclude(input_callback_state *callback_state, char **startp,
+ int *lenp)
+{
+ input_data *data = callback_state->input_stack;
+ input_data *new_data;
+ char *filename, *end;
+ const char *scratch;
+
+ /* process the #include that we're in now */
+ if (strncmp(data->point, "#include \"", 10)) {
+ return 0;
+ }
+
+ filename = data->point + 10; /* skip #include " */
+ XPT_ASSERT(filename < data->max);
+ end = filename;
+ while (end < data->max) {
+ if (*end == '\"' || *end == '\n' || *end == '\r')
+ break;
+ end++;
+ }
+
+ if (*end != '\"') {
+ /*
+ * Didn't find end of include file. Scan 'til next whitespace to find
+ * some reasonable approximation of the filename, and use it to report
+ * an error.
+ */
+
+ end = filename;
+ while (end < data->max) {
+ if (*end == ' ' || *end == '\n' || *end == '\r' || *end == '\t')
+ break;
+ end++;
+ }
+ *end = '\0';
+
+ /* make sure we have accurate line info */
+ IDL_file_get(&scratch, (int *)&data->lineno);
+ fprintf(stderr,
+ "%s:%u: didn't find end of quoted include name \"%s\n",
+ scratch, data->lineno, filename);
+ return -1;
+ }
+
+ *end = '\0';
+ *startp = end + 1;
+
+ if (data->next == NULL) {
+ /*
+ * If we're in the initial file, add this filename to the list
+ * of filenames to be turned into #include "filename.h"
+ * directives in xpidl_header.c. We do it here rather than in the
+ * block below so it still gets added to the list even if it's
+ * already been recursively included from some other file.
+ */
+ char *filename_cp = xpidl_strdup(filename);
+
+ /* note that g_slist_append accepts and likes null as list-start. */
+ callback_state->base_includes =
+ g_slist_append(callback_state->base_includes, filename_cp);
+ }
+
+ /* store offset for when we pop, or if we skip this one */
+ data->point = *startp;
+
+ if (!g_hash_table_lookup(callback_state->already_included, filename)) {
+ filename = xpidl_strdup(filename);
+ g_hash_table_insert(callback_state->already_included,
+ filename, (void *)TRUE);
+ new_data = new_input_data(filename, callback_state->include_path);
+ if (!new_data) {
+ char *error_message;
+ IDL_file_get(&scratch, (int *)&data->lineno);
+ error_message =
+ g_strdup_printf("can't open included file %s for reading\n",
+ filename);
+ msg_callback(IDL_ERROR, 0,
+ data->lineno, scratch, error_message);
+ g_free(error_message);
+ return -1;
+ }
+
+ new_data->next = data;
+ /* tell libIDL to exclude this IDL from the toplevel tree */
+ IDL_inhibit_push();
+ IDL_file_get(&scratch, (int *)&data->lineno);
+ callback_state->input_stack = new_data;
+ IDL_file_set(new_data->filename, (int)new_data->lineno);
+ }
+
+ *lenp = 0; /* this is magic, see the comment below */
+ return 1;
+}
+
+static void
+FindSpecial(input_data *data, char **startp, int *lenp)
+{
+ char *point = data->point;
+
+ /* magic sequences are:
+ * "%{" raw block
+ * "/\*" comment
+ * "#include \"" include
+ * The first and last want a newline [\r\n] before, or the start of the
+ * file.
+ */
+
+#define LINE_START(data, point) (point == data->buf || \
+ (point > data->point && \
+ (point[-1] == '\r' || point[-1] == '\n')))
+
+ while (point < data->max) {
+ if (point[0] == '/' && point[1] == '*')
+ break;
+ if (LINE_START(data, point)) {
+ if (point[0] == '%' && point[1] == '{')
+ break;
+ if (point[0] == '#' && !strncmp(point + 1, "include \"", 9))
+ break;
+ }
+ point++;
+ }
+
+#undef LINE_START
+
+ *startp = data->point;
+ *lenp = point - data->point;
+}
+
+/* set this with a debugger to see exactly what libIDL sees */
+static FILE *tracefile;
+
+static int
+input_callback(IDL_input_reason reason, union IDL_input_data *cb_data,
+ gpointer user_data)
+{
+ input_callback_state *callback_state = user_data;
+ input_data *data = callback_state->input_stack;
+ input_data *new_data = NULL;
+ unsigned int len, copy;
+ int rv;
+ char *start;
+
+ switch(reason) {
+ case IDL_INPUT_REASON_INIT:
+ if (data == NULL || data->next == NULL) {
+ /*
+ * This is the first file being processed. As it's the target
+ * file, we only look for it in the first entry in the include
+ * path, which we assume to be the current directory.
+ */
+
+ /* XXXmccabe proper assumption? Do we handle files in other
+ directories? */
+
+ IncludePathEntry first_entry;
+
+ first_entry.directory = callback_state->include_path->directory;
+ first_entry.next = NULL;
+
+ new_data = new_input_data(cb_data->init.filename,
+ &first_entry);
+ } else {
+ new_data = new_input_data(cb_data->init.filename,
+ callback_state->include_path);
+ }
+
+ if (!new_data)
+ return -1;
+
+ IDL_file_set(new_data->filename, (int)new_data->lineno);
+ callback_state->input_stack = new_data;
+ return 0;
+
+ case IDL_INPUT_REASON_FILL:
+ start = NULL;
+ len = 0;
+
+ while (data->point >= data->max) {
+ if (!data->next)
+ return 0;
+
+ /* Current file is done; revert to including file */
+ callback_state->input_stack = data->next;
+ free(data->filename);
+ free(data->buf);
+ free(data);
+ data = callback_state->input_stack;
+
+ IDL_file_set(data->filename, (int)data->lineno);
+ IDL_inhibit_pop();
+ }
+
+ /*
+ * Now we scan for sequences which require special attention:
+ * \n#include begins an include statement
+ * \n%{ begins a raw-source block
+ * /\* begins a comment
+ *
+ * We used to be fancier here, so make sure that we sent the most
+ * data possible at any given time. To that end, we skipped over
+ * \n%{ raw \n%} blocks and then _continued_ the search for special
+ * sequences like \n#include or /\* comments .
+ *
+ * It was really ugly, though -- liberal use of goto! lots of implicit
+ * state! what fun! -- so now we just do this:
+ *
+ * if (special at start) {
+ * process that special -
+ * - raw: send it to libIDL, and don't look inside for specials
+ * - comments: adjust point and start over
+ * - includes: push new input_data struct for included file, and
+ * start over
+ * } else {
+ * scan for next special
+ * send data up to that special to libIDL
+ * }
+ *
+ * If len is set to zero, it is a sentinel value indicating we a comment
+ * or include was found, and parsing should start over.
+ *
+ * XXX const string foo = "/\*" will just screw us horribly.
+ * Hm but. We could treat strings as we treat raw blocks, eh?
+ */
+
+ /*
+ * Order is important, so that you can have /\* comments and
+ * #includes within raw sections, and so that you can comment out
+ * #includes.
+ */
+ rv = NextIsRaw(data, &start, (int *)&len);
+ if (rv == -1) return -1;
+ if (!rv) {
+ /*
+ * When NextIsComment succeeds, it returns a 0 len (requesting a
+ * restart) and adjusts data->point to pick up after the comment.
+ */
+ rv = NextIsComment(data, &start, (int *)&len);
+ if (rv == -1) return -1;
+ if (!rv) {
+ /*
+ * NextIsInclude might push a new input_data struct; if so, it
+ * will return a 0 len, letting the callback pick up the new
+ * file the next time around.
+ */
+ rv = NextIsInclude(callback_state, &start, (int *)&len);
+ if (rv == -1) return -1;
+ if (!rv)
+ FindSpecial(data, &start, (int *)&len);
+ }
+ }
+
+ if (len == 0) {
+ /*
+ * len == 0 is a sentinel value that means we found a comment or
+ * include. If we found a comment, point has been adjusted to
+ * point past the comment. If we found an include, a new input_data
+ * has been pushed. In both cases, calling the input_callback again
+ * will pick up the new state.
+ */
+ return input_callback(reason, cb_data, user_data);
+ }
+
+ copy = MIN(len, (unsigned int) cb_data->fill.max_size);
+ memcpy(cb_data->fill.buffer, start, copy);
+ data->point = start + copy;
+
+ if (tracefile)
+ fwrite(cb_data->fill.buffer, copy, 1, tracefile);
+
+ return copy;
+
+ case IDL_INPUT_REASON_ABORT:
+ case IDL_INPUT_REASON_FINISH:
+ while (data != NULL) {
+ input_data *next;
+
+ next = data->next;
+ free(data->filename);
+ free(data->buf);
+ free(data);
+ data = next;
+ }
+ return 0;
+
+ default:
+ g_error("unknown input reason %d!", reason);
+ return -1;
+ }
+}
+
+static void
+free_ghash_key(gpointer key, gpointer value, gpointer user_data)
+{
+ /* We're only storing TRUE in the value... */
+ free(key);
+}
+
+static void
+free_gslist_data(gpointer data, gpointer user_data)
+{
+ free(data);
+}
+
+/* Pick up unlink. */
+#ifdef XP_UNIX
+#include <unistd.h>
+#elif XP_WIN
+/* We get it from stdio.h. */
+#endif
+
+int
+xpidl_process_idl(char *filename, IncludePathEntry *include_path,
+ char *file_basename, ModeData *mode)
+{
+ char *tmp, *outname, *real_outname = NULL;
+ IDL_tree top;
+ TreeState state;
+ int rv;
+ input_callback_state callback_state;
+ gboolean ok = TRUE;
+ backend *emitter;
+
+ callback_state.input_stack = NULL;
+ callback_state.base_includes = NULL;
+ callback_state.include_path = include_path;
+ callback_state.already_included = g_hash_table_new(g_str_hash, g_str_equal);
+
+ if (!callback_state.already_included) {
+ fprintf(stderr, "failed to create hashtable. out of memory?\n");
+ return 0;
+ }
+
+ state.basename = xpidl_strdup(filename);
+
+ /* if basename has an .extension, truncate it. */
+ tmp = strrchr(state.basename, '.');
+ if (tmp)
+ *tmp = '\0';
+
+ if (!file_basename)
+ outname = xpidl_strdup(state.basename);
+ else
+ outname = xpidl_strdup(file_basename);
+
+ /* so we don't include it again! */
+ g_hash_table_insert(callback_state.already_included,
+ xpidl_strdup(filename), (void *)TRUE);
+
+ parsed_empty_file = FALSE;
+
+ rv = IDL_parse_filename_with_input(filename, input_callback, &callback_state,
+ msg_callback, &top,
+ &state.ns,
+ IDLF_IGNORE_FORWARDS |
+ IDLF_XPIDL,
+ enable_warnings ? IDL_WARNING1 :
+ IDL_ERROR);
+ if (parsed_empty_file) {
+ /*
+ * If we've detected (via hack in msg_callback) that libIDL returned
+ * failure because it found a file with no IDL, set the parse tree to
+ * null and proceed. Allowing this is useful to permit .idl files that
+ * collect #includes.
+ */
+ top = NULL;
+ state.ns = NULL;
+ } else if (rv != IDL_SUCCESS) {
+ if (rv == -1) {
+ g_warning("Parse of %s failed: %s", filename, g_strerror(errno));
+ } else {
+ g_warning("Parse of %s failed", filename);
+ }
+ return 0;
+ }
+
+ state.basename = xpidl_strdup(filename);
+ tmp = strrchr(state.basename, '.');
+ if (tmp)
+ *tmp = '\0';
+
+ /* so xpidl_header.c can use it to generate a list of #include directives */
+ state.base_includes = callback_state.base_includes;
+
+ emitter = mode->factory();
+ state.dispatch = emitter->dispatch_table;
+
+ if (strcmp(outname, "-")) {
+ const char *fopen_mode;
+ char *out_basename;
+
+ /* explicit_output_filename can't be true without a filename */
+ if (explicit_output_filename) {
+ real_outname = g_strdup(outname);
+ } else {
+/*
+ *This combination seems a little strange, what about OS/2?
+ * Assume it's some build issue
+ */
+#if defined(XP_UNIX) || defined(XP_WIN)
+ if (!file_basename) {
+ out_basename = xpidl_basename(outname);
+ } else {
+ out_basename = outname;
+ }
+#else
+ out_basename = outname;
+#endif
+ real_outname = g_strdup_printf("%s.%s", out_basename, mode->suffix);
+ if (out_basename != outname)
+ g_free(out_basename);
+ }
+
+ /* Use binary write for typelib mode */
+ fopen_mode = (strcmp(mode->mode, "typelib")) ? "w" : "wb";
+ state.file = fopen(real_outname, fopen_mode);
+ if (!state.file) {
+ perror("error opening output file");
+ return 0;
+ }
+ } else {
+ state.file = stdout;
+ }
+ state.tree = top;
+#ifdef VBOX_XPIDL_EMULATE_GENJIFACES
+ state.real_outname = real_outname;
+#endif
+
+ if (emitter->emit_prolog)
+ emitter->emit_prolog(&state);
+ if (state.tree) /* Only if we have a tree to process. */
+ ok = xpidl_process_node(&state);
+ if (emitter->emit_epilog)
+ emitter->emit_epilog(&state);
+
+ if (state.file != stdout)
+ fclose(state.file);
+ free(state.basename);
+ free(outname);
+ g_hash_table_foreach(callback_state.already_included, free_ghash_key, NULL);
+ g_hash_table_destroy(callback_state.already_included);
+ g_slist_foreach(callback_state.base_includes, free_gslist_data, NULL);
+
+ if (state.ns)
+ IDL_ns_free(state.ns);
+ if (top)
+ IDL_tree_free(top);
+
+ if (real_outname != NULL) {
+ /*
+ * Delete partial output file on failure. (Mac does this in the plugin
+ * driver code, if the compiler returns failure.)
+ */
+#if defined(XP_UNIX) || defined(XP_WIN)
+ if (!ok)
+ unlink(real_outname);
+#endif
+ g_free(real_outname);
+ }
+
+ return ok;
+}
+
+/*
+ * Our own version of IDL_tree_warning, which we use when IDL_tree_warning
+ * would crash on us.
+ */
+void
+xpidl_tree_warning(IDL_tree p, int level, const char *fmt, ...)
+{
+ va_list ap;
+ char *msg, *file;
+ int lineno;
+
+ /* XXX need to check against __IDL_max_msg_level, no accessor */
+ va_start(ap, fmt);
+ msg = g_strdup_vprintf(fmt, ap);
+
+ if (p) {
+ file = p->_file;
+ lineno = p->_line;
+ } else {
+ file = NULL;
+ lineno = 0;
+ }
+
+ /* call our message callback, like IDL_tree_warning would */
+ msg_callback(level, 0, lineno, file, msg);
+ g_free(msg);
+ va_end(ap);
+}
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpidl/xpidl_java.c b/src/libs/xpcom18a4/xpcom/typelib/xpidl/xpidl_java.c
new file mode 100644
index 00000000..4f708027
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpidl/xpidl_java.c
@@ -0,0 +1,1053 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 Sun Microsystems,
+ * Inc. Portions created by Sun are
+ * Copyright (C) 1999 Sun Microsystems, Inc. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ * Michael Allen (michael.allen@sun.com)
+ * Frank Mitchell (frank.mitchell@sun.com)
+ */
+
+/*
+ * Generate Java interfaces from XPIDL.
+ */
+
+#include "xpidl.h"
+#include <ctype.h>
+#include <glib.h>
+
+
+struct java_priv_data {
+ GHashTable *typedefTable;
+};
+
+#define TYPEDEFS(state) (((struct java_priv_data *)state->priv)->typedefTable)
+
+static gboolean
+write_classname_iid_define(FILE *file, const char *className)
+{
+ const char *iidName;
+ if (className[0] == 'n' && className[1] == 's') {
+ /* backcompat naming styles */
+ fputs("NS_", file);
+ iidName = className + 2;
+ } else {
+ iidName = className;
+ }
+
+ while (*iidName) {
+ fputc(toupper(*iidName++), file);
+ }
+
+ fputs("_IID", file);
+ return TRUE;
+}
+
+static gboolean
+java_prolog(TreeState *state)
+{
+#ifdef VBOX_XPIDL_EMULATE_GENJIFACES_DIFF
+ const char *basename;
+ const char *ext;
+#endif
+
+ state->priv = calloc(1, sizeof(struct java_priv_data));
+ if (!state->priv)
+ return FALSE;
+ TYPEDEFS(state) = 0;
+ TYPEDEFS(state) = g_hash_table_new(g_str_hash, g_str_equal);
+ if (!TYPEDEFS(state)) {
+ /* XXX report error */
+ free(state->priv);
+ return FALSE;
+ }
+
+ /*
+ * First pass
+ */
+
+#ifdef VBOX_XPIDL_EMULATE_GENJIFACES_DIFF
+ basename = xpidl_basename(state->real_outname ? state->real_outname : state->basename);
+ ext = strrchr(basename, '.');
+ if (!ext)
+ ext = strchr(basename, '\0');
+ fprintf(state->file,
+ "/**\n"
+ " * NOTE: THIS IS A GENERATED FILE. PLEASE CONSULT THE ORIGINAL IDL FILE\n"
+ " * FOR THE FULL DOCUMENTATION AND LICENSE.\n"
+ " *\n"
+ " * @see <a href=\"http://lxr.mozilla.org/mozilla/search?string=interface+%.*s\">\n"
+ " **/\n"
+ "\n"
+ "package org.mozilla.interfaces;\n\n"
+ "import java.math.BigInteger;\n\n"
+ "\n"
+ , ext - basename >= 19 ? 19 : (int)(ext - basename), basename);
+ g_free(basename);
+#else
+ fputs("/*\n * ************* DO NOT EDIT THIS FILE ***********\n",
+ state->file);
+
+ fprintf(state->file,
+ " *\n * This file was automatically generated from %s.idl.\n",
+ state->basename);
+
+ fputs(" */\n\n", state->file);
+#endif
+
+ return TRUE;
+}
+
+static gboolean
+java_epilog(TreeState *state)
+{
+ /* points to other elements of the tree, so just destroy the table */
+ g_hash_table_destroy(TYPEDEFS(state));
+ free(state->priv);
+ state->priv = NULL;
+
+#ifndef VBOX_XPIDL_EMULATE_GENJIFACES_DIFF
+ /*
+ * Last pass
+ */
+
+ fprintf(state->file, "\n/*\n * end\n */\n");
+#endif
+
+ return TRUE;
+}
+
+static gboolean
+forward_declaration(TreeState *state)
+{
+ /*
+ * Java doesn't need forward declarations unless the declared
+ * class resides in a different package.
+ */
+#if 0
+ IDL_tree iface = state->tree;
+ const char *className = IDL_IDENT(IDL_FORWARD_DCL(iface).ident).str;
+ const char *pkgName = "org.mozilla.xpcom";
+ if (!className)
+ return FALSE;
+ /* XXX: Get package name and compare */
+ fprintf(state->file, "import %s.%s;\n", pkgName, className);
+#endif
+ return TRUE;
+}
+
+
+static gboolean
+interface_declaration(TreeState *state)
+{
+ IDL_tree interface = state->tree;
+ IDL_tree iterator = NULL;
+ char *interface_name = IDL_IDENT(IDL_INTERFACE(interface).ident).str;
+ const char *iid = NULL;
+
+ if (!verify_interface_declaration(interface))
+ return FALSE;
+#ifndef VBOX_XPIDL_EMULATE_GENJIFACES_DIFF
+ /*
+ * Write out JavaDoc comment
+ */
+
+ fprintf(state->file, "\n/**\n * Interface %s\n", interface_name);
+#endif
+
+#ifndef LIBIDL_MAJOR_VERSION
+ iid = IDL_tree_property_get(interface, "uuid");
+#else
+ iid = IDL_tree_property_get(IDL_INTERFACE(interface).ident, "uuid");
+#endif
+
+#ifndef VBOX_XPIDL_EMULATE_GENJIFACES_DIFF
+ if (iid != NULL) {
+ fprintf(state->file, " *\n * IID: 0x%s\n */\n\n", iid);
+ } else {
+ fputs(" */\n\n", state->file);
+ }
+#endif
+
+ /*
+ * Write "public interface <foo>"
+ */
+
+ fprintf(state->file, "public interface %s ", interface_name);
+
+ /*
+ * Check for inheritence, and iterator over the inherited names,
+ * if any.
+ */
+
+ if ((iterator = IDL_INTERFACE(interface).inheritance_spec)) {
+ fputs("extends ", state->file);
+
+ do {
+
+ fprintf(state->file, "%s",
+ IDL_IDENT(IDL_LIST(iterator).data).str);
+
+ if (IDL_LIST(iterator).next) {
+ fputs(", ", state->file);
+ }
+ } while ((iterator = IDL_LIST(iterator).next));
+
+ }
+
+ fputs("\n{\n", state->file);
+
+ if (iid) {
+ /*
+ * Write interface constants for IID
+ */
+
+#ifdef VBOX_XPIDL_EMULATE_GENJIFACES_DIFF
+ fputs(" public static final String ", state->file);
+#else
+ fputs(" public static final String ", state->file);
+#endif
+
+ /* XXX s.b just "IID" ? */
+ if (!write_classname_iid_define(state->file, interface_name)) {
+ return FALSE;
+ }
+
+#ifdef VBOX_XPIDL_EMULATE_GENJIFACES
+ fputs(" =\n \"{", state->file);
+ while (*iid) {
+ fputc(tolower(*iid++), state->file);
+ }
+ fputs("}\";\n", state->file);
+
+#else
+ fprintf(state->file, "_STRING =\n \"%s\";\n\n", iid);
+
+ fputs(" public static final nsID ", state->file);
+
+ /* XXX s.b just "IID" ? */
+ if (!write_classname_iid_define(state->file, interface_name)) {
+ return FALSE;
+ }
+
+ fprintf(state->file, " =\n new nsID(\"%s\");\n\n", iid);
+#endif
+ }
+
+ /*
+ * Advance the state of the tree, go on to process more
+ */
+
+ state->tree = IDL_INTERFACE(interface).body;
+
+ if (state->tree && !xpidl_process_node(state)) {
+ return FALSE;
+ }
+
+
+ fputs("\n}\n", state->file);
+
+ return TRUE;
+}
+
+static gboolean
+process_list(TreeState *state)
+{
+#ifdef VBOX_XPIDL_EMULATE_GENJIFACES_DIFF
+ /* To make the diffing simple, group the constants, methods and attributes. */
+ IDL_tree list = state->tree;
+ IDL_tree iter;
+ for (iter = list; iter; iter = IDL_LIST(iter).next) {
+ if (IDL_NODE_TYPE(IDL_LIST(iter).data) == IDLN_CONST_DCL) {
+ state->tree = IDL_LIST(iter).data;
+ if (!xpidl_process_node(state))
+ return FALSE;
+ }
+ }
+ for (iter = list; iter; iter = IDL_LIST(iter).next) {
+ if (IDL_NODE_TYPE(IDL_LIST(iter).data) == IDLN_ATTR_DCL) {
+ state->tree = IDL_LIST(iter).data;
+ if (!xpidl_process_node(state))
+ return FALSE;
+ }
+ }
+ for (iter = list; iter; iter = IDL_LIST(iter).next) {
+ if (IDL_NODE_TYPE(IDL_LIST(iter).data) == IDLN_OP_DCL) {
+ state->tree = IDL_LIST(iter).data;
+ if (!xpidl_process_node(state))
+ return FALSE;
+ }
+ }
+ for (iter = list; iter; iter = IDL_LIST(iter).next) {
+ if ( IDL_NODE_TYPE(IDL_LIST(iter).data) != IDLN_CONST_DCL
+ && IDL_NODE_TYPE(IDL_LIST(iter).data) != IDLN_OP_DCL
+ && IDL_NODE_TYPE(IDL_LIST(iter).data) != IDLN_ATTR_DCL ) {
+ state->tree = IDL_LIST(iter).data;
+ if (!xpidl_process_node(state))
+ return FALSE;
+ }
+ }
+
+#else
+ IDL_tree iter;
+ for (iter = state->tree; iter; iter = IDL_LIST(iter).next) {
+ state->tree = IDL_LIST(iter).data;
+ if (!xpidl_process_node(state))
+ return FALSE;
+ }
+#endif
+ return TRUE;
+}
+
+#ifdef VBOX_XPIDL_EMULATE_GENJIFACES
+static gboolean
+interface_declaration_wrapper(TreeState *state)
+{
+ IDL_tree interface = state->tree;
+ char *interface_name = IDL_IDENT(IDL_INTERFACE(interface).ident).str;
+ FILE *org_file = state->file;
+ char *org_name = state->real_outname;
+ void *org_priv = state->priv;
+ gboolean rc;
+
+ /*
+ * Skip non-scriptable interfaces.
+ */
+ if ( !IDL_tree_property_get(IDL_INTERFACE(interface).ident, "scriptable")
+ && strcmp(interface_name, "nsIAppShell") )
+ return TRUE;
+
+ /*
+ * GROSS HACK: If the interface isn't the same as the file name,
+ * temporarily switch output file.
+ */
+ if (state->real_outname) {
+ const char *basename = xpidl_basename(state->real_outname);
+ const char *ext = strrchr(basename, '.');
+ if ( ext
+ && !strcmp(ext, ".java")
+ && ( strncmp(interface_name, basename, ext - basename)
+ || interface_name[ext - basename] != '.') ) {
+ size_t needed = strlen(state->real_outname) + strlen(interface_name) + strlen(".java") + 4;
+ char *tmp = malloc(needed);
+ if (basename != state->real_outname)
+ sprintf(tmp,"%.*s/%s.java", (int)(basename - state->real_outname - 1), state->real_outname, interface_name);
+ else
+ sprintf(tmp,"%s.java", interface_name);
+ state->file = fopen(tmp, "w");
+ if (!state->file) {
+ perror("error opening output file");
+ state->file = org_file;
+ free(tmp);
+ return FALSE;
+ }
+ state->real_outname = tmp;
+ java_prolog(state);
+ }
+ g_free(basename);
+ }
+
+ rc = interface_declaration(state);
+
+ if (state->file != org_file) {
+ java_epilog(state);
+ fclose(state->file);
+ free(state->real_outname);
+ state->file = org_file;
+ state->real_outname = org_name;
+ state->priv = org_priv;
+ }
+ return rc;
+}
+#endif /* VBOX_XPIDL_EMULATE_GENJIFACES */
+
+static gboolean
+xpcom_to_java_type (TreeState *state)
+{
+ if (!state->tree) {
+ fputs("Object", state->file);
+ return TRUE;
+ }
+
+ switch(IDL_NODE_TYPE(state->tree)) {
+
+ case IDLN_TYPE_INTEGER: {
+
+ switch(IDL_TYPE_INTEGER(state->tree).f_type) {
+
+ case IDL_INTEGER_TYPE_SHORT:
+#ifdef VBOX_XPIDL_EMULATE_GENJIFACES
+ if (IDL_TYPE_INTEGER(state->tree).f_signed)
+ fputs("short", state->file);
+ else
+ fputs("int", state->file);
+#else
+ fputs("short", state->file);
+#endif
+ break;
+
+ case IDL_INTEGER_TYPE_LONG:
+#ifdef VBOX_XPIDL_EMULATE_GENJIFACES
+ if (IDL_TYPE_INTEGER(state->tree).f_signed)
+ fputs("int", state->file);
+ else
+ fputs("long", state->file);
+#else
+ fputs("int", state->file);
+#endif
+ break;
+
+ case IDL_INTEGER_TYPE_LONGLONG:
+#ifdef VBOX_XPIDL_EMULATE_GENJIFACES
+ if (IDL_TYPE_INTEGER(state->tree).f_signed)
+ fputs("long", state->file);
+ else
+ fputs("double", state->file);
+#else
+ fputs("long", state->file);
+#endif
+ break;
+
+ default:
+ g_error(" Unknown integer type: %d\n",
+ IDL_TYPE_INTEGER(state->tree).f_type);
+ return FALSE;
+
+ }
+
+ break;
+ }
+
+ case IDLN_TYPE_CHAR:
+ case IDLN_TYPE_WIDE_CHAR:
+ fputs("char", state->file);
+ break;
+
+ case IDLN_TYPE_WIDE_STRING:
+ case IDLN_TYPE_STRING:
+ fputs("String", state->file);
+ break;
+
+ case IDLN_TYPE_BOOLEAN:
+ fputs("boolean", state->file);
+ break;
+
+ case IDLN_TYPE_OCTET:
+#ifdef VBOX_XPIDL_EMULATE_GENJIFACES
+ fputs("short", state->file);
+#else
+ fputs("byte", state->file);
+#endif
+ break;
+
+ case IDLN_TYPE_FLOAT:
+ switch(IDL_TYPE_FLOAT(state->tree).f_type) {
+
+ case IDL_FLOAT_TYPE_FLOAT:
+ fputs("float", state->file);
+ break;
+
+ case IDL_FLOAT_TYPE_DOUBLE:
+ fputs("double", state->file);
+ break;
+
+ default:
+ g_error(" Unknown floating point typ: %d\n",
+ IDL_NODE_TYPE(state->tree));
+ break;
+ }
+ break;
+
+
+ case IDLN_IDENT:
+ if (IDL_NODE_UP(state->tree) &&
+ IDL_NODE_TYPE(IDL_NODE_UP(state->tree)) == IDLN_NATIVE) {
+ const char *user_type = IDL_NATIVE(IDL_NODE_UP(state->tree)).user_type;
+ if (strcmp(user_type, "void") == 0) {
+#ifdef VBOX_XPIDL_EMULATE_GENJIFACES
+ fputs("nsISupports", state->file);
+#else
+ fputs("Object", state->file);
+#endif
+ }
+ else if (strcmp(user_type, "nsID") == 0 ||
+ strcmp(user_type, "nsIID") == 0 ||
+ strcmp(user_type, "nsCID") == 0) {
+ /* XXX: s.b test for "iid" attribute */
+ /* XXX: special class for nsIDs */
+#ifdef VBOX_XPIDL_EMULATE_GENJIFACES
+ fputs("String", state->file);
+#else
+ fputs("nsID", state->file);
+#endif
+ }
+ else {
+ /* XXX: special class for opaque types */
+#ifdef VBOX_XPIDL_EMULATE_GENJIFACES
+ fputs("String", state->file);
+#else
+ fputs("OpaqueValue", state->file);
+#endif
+ }
+ } else {
+ const char *ident_str = IDL_IDENT(state->tree).str;
+
+ /* XXX: big kludge; s.b. way to match to typedefs */
+#ifdef VBOX_XPIDL_EMULATE_GENJIFACES
+ if (strcmp(ident_str, "PRInt8") == 0) {
+ fputs("byte", state->file);
+ }
+ else if (strcmp(ident_str, "PRInt16") == 0 ||
+ strcmp(ident_str, "PRUint8") == 0) {
+ fputs("short", state->file);
+ }
+ else if (strcmp(ident_str, "PRInt32") == 0 ||
+ strcmp(ident_str, "PRUint16") == 0) {
+ fputs("int", state->file);
+ }
+ else if (strcmp(ident_str, "PRInt64") == 0 ||
+ strcmp(ident_str, "PRUint32") == 0 ||
+ strcmp(ident_str, "PRThreadPriority") == 0 ||
+ strcmp(ident_str, "PRThreadScope") == 0 ||
+ strcmp(ident_str, "PRThreadState") == 0) {
+ fputs("long", state->file);
+ }
+ else if (strcmp(ident_str, "PRUint64") == 0) {
+ fputs("double", state->file);
+ }
+#else
+ if (strcmp(ident_str, "PRInt8") == 0 ||
+ strcmp(ident_str, "PRUint8") == 0) {
+ fputs("byte", state->file);
+ }
+ else if (strcmp(ident_str, "PRInt16") == 0 ||
+ strcmp(ident_str, "PRUint16") == 0) {
+ fputs("short", state->file);
+ }
+ else if (strcmp(ident_str, "PRInt32") == 0 ||
+ strcmp(ident_str, "PRUint32") == 0) {
+ fputs("int", state->file);
+ }
+ else if (strcmp(ident_str, "PRInt64") == 0 ||
+ strcmp(ident_str, "PRUint64") == 0) {
+ fputs("long", state->file);
+ }
+#endif
+ else if (strcmp(ident_str, "PRBool") == 0) {
+ fputs("boolean", state->file);
+ }
+ else if (strcmp(ident_str, "nsrefcnt") == 0) {
+ fputs("int", state->file);
+ }
+#ifdef VBOX_XPIDL_EMULATE_GENJIFACES
+ /* XXX: Use find_underlying_type instead? */
+ else if ( strcmp(ident_str, "nsresult") == 0
+ || strcmp(ident_str, "size_t") == 0) {
+ fputs("long", state->file);
+ }
+ else if ( strcmp(ident_str, "PRTime") == 0) {
+ fputs("double", state->file);
+ }
+ /* In Javaconnect, we handle weak references internally; no need for the
+ |nsIWeakReference| interface. So just return |nsISupports|. */
+ else if (strcmp(ident_str, "nsIWeakReference") == 0) {
+ fputs("nsISupports", state->file);
+ }
+#endif
+ else {
+ IDL_tree real_type =
+ g_hash_table_lookup(TYPEDEFS(state), ident_str);
+
+ if (real_type) {
+ IDL_tree orig_tree = state->tree;
+
+ state->tree = real_type;
+ xpcom_to_java_type(state);
+
+ state->tree = orig_tree;
+ }
+ else {
+ fputs(ident_str, state->file);
+ }
+ }
+ }
+
+ break;
+
+ case IDLN_TYPE_ENUM:
+ case IDLN_TYPE_OBJECT:
+ default:
+ g_error(" Unknown type: %d\n",
+ IDL_TYPE_FLOAT(state->tree).f_type);
+ break;
+ }
+
+ return TRUE;
+
+}
+
+static gboolean
+#ifdef VBOX_XPIDL_EMULATE_GENJIFACES_DIFF
+xpcom_to_java_param(TreeState *state, unsigned nparam)
+#else
+xpcom_to_java_param(TreeState *state)
+#endif
+{
+ IDL_tree param = state->tree;
+ state->tree = IDL_PARAM_DCL(param).param_type_spec;
+
+ /*
+ * Put in type of parameter
+ */
+
+ if (!xpcom_to_java_type(state)) {
+ return FALSE;
+ }
+
+ /*
+ * If the parameter is out or inout, make it a Java array of the
+ * appropriate type
+ */
+
+#ifdef VBOX_XPIDL_EMULATE_GENJIFACES
+ /* XXX: Causes nsILineInputStream::readLine(String[] arg1) where genjifaces drops the []. */
+#endif
+ if (IDL_PARAM_DCL(param).attr != IDL_PARAM_IN) {
+ fputs("[]", state->file);
+ }
+#ifdef VBOX_XPIDL_EMULATE_GENJIFACES
+ /*XXX: nsIConsoleService::getMessageArray ends up with [][] arg1... */
+ /*else*/ if (IDL_tree_property_get(IDL_PARAM_DCL(param).simple_declarator, "array")) {
+ fputs("[]", state->file);
+ }
+#endif
+
+ /*
+ * Put in name of parameter
+ */
+
+ fputc(' ', state->file);
+
+#ifdef VBOX_XPIDL_EMULATE_GENJIFACES_DIFF
+ fprintf(state->file, "arg%u", nparam+1);
+#else
+ fputs(IDL_IDENT(IDL_PARAM_DCL(param).simple_declarator).str, state->file);
+#endif
+
+ return TRUE;
+}
+
+#ifdef VBOX_XPIDL_EMULATE_GENJIFACES
+static gboolean is_java_keyword(char ch0, const char *name)
+{
+ static const char * const kJavaKeywords[] = {
+ "abstract", "default", "if" , "private" , "this" ,
+ "boolean" , "do" , "implements", "protected" , "throw" ,
+ "break" , "double" , "import", "public" , "throws" ,
+ "byte" , "else" , "instanceof", "return" , "transient",
+ "case" , "extends", "int" , "short" , "try" ,
+ "catch" , "final" , "interface" , "static" , "void" ,
+ "char" , "finally", "long" , "strictfp" , "volatile" ,
+ "class" , "float" , "native" , "super" , "while" ,
+ "const" , "for" , "new" , "switch" ,
+ "continue", "goto" , "package" , "synchronized",
+ "assert" , /* added in Java 1.4 */
+ "enum" , /* added in Java 5.0 */
+ "clone" , /* clone is a member function of java.lang.Object */
+ "finalize" /* finalize is a member function of java.lang.Object */
+ };
+ unsigned i;
+ for (i = 0; i < sizeof(kJavaKeywords) / sizeof(kJavaKeywords[0]); i++) {
+ if (kJavaKeywords[i][0] == ch0 && !strcmp(&kJavaKeywords[i][1], &name[1])) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+#endif
+
+static gboolean
+type_declaration(TreeState *state)
+{
+ /*
+ * Unlike C, Java has no type declaration directive.
+ * Instead, we record the mapping, and look up the actual type
+ * when needed.
+ */
+ IDL_tree type = IDL_TYPE_DCL(state->tree).type_spec;
+ IDL_tree dcls = IDL_TYPE_DCL(state->tree).dcls;
+
+ /* XXX: check for illegal types */
+
+ g_hash_table_insert(TYPEDEFS(state),
+ IDL_IDENT(IDL_LIST(dcls).data).str,
+ type);
+
+ return TRUE;
+}
+
+static gboolean
+method_declaration(TreeState *state)
+{
+ /* IDL_tree method_tree = state->tree; */
+ struct _IDL_OP_DCL *method = &IDL_OP_DCL(state->tree);
+ gboolean method_notxpcom =
+ (IDL_tree_property_get(method->ident, "notxpcom") != NULL);
+ gboolean method_noscript =
+ (IDL_tree_property_get(method->ident, "noscript") != NULL);
+ IDL_tree iterator = NULL;
+ IDL_tree retval_param = NULL;
+ const char *method_name = IDL_IDENT(method->ident).str;
+#ifdef VBOX_XPIDL_EMULATE_GENJIFACES_DIFF
+ unsigned nparam = 0;
+#endif
+
+ if (!verify_method_declaration(state->tree))
+ return FALSE;
+
+#ifdef VBOX_XPIDL_EMULATE_GENJIFACES
+ /*
+ * Skip most (todo) non-scriptable and not-xpcom methods.
+ */
+ if (method_noscript || method_notxpcom) {
+ return TRUE;
+ }
+#endif
+
+ fputc('\n', state->file);
+#ifndef VBOX_XPIDL_EMULATE_GENJIFACES_DIFF
+ xpidl_write_comment(state, 4);
+#endif
+
+ /*
+ * Write beginning of method declaration
+ */
+#ifdef VBOX_XPIDL_EMULATE_GENJIFACES_DIFF
+ fputs(" ", state->file);
+#else
+ fputs(" ", state->file);
+#endif
+ if (!method_noscript) {
+ /* Nonscriptable methods become package-protected */
+ fputs("public ", state->file);
+ }
+
+ /*
+ * Write return type
+ * Unlike C++ headers, Java interfaces return the declared
+ * return value; an exception indicates XPCOM method failure.
+ */
+ if (method_notxpcom || method->op_type_spec) {
+ state->tree = method->op_type_spec;
+ if (!xpcom_to_java_type(state)) {
+ return FALSE;
+ }
+ } else {
+ /* Check for retval attribute */
+ for (iterator = method->parameter_dcls; iterator != NULL;
+ iterator = IDL_LIST(iterator).next) {
+
+ IDL_tree original_tree = state->tree;
+
+ state->tree = IDL_LIST(iterator).data;
+
+ if (IDL_tree_property_get(IDL_PARAM_DCL(state->tree).simple_declarator,
+ "retval")) {
+ retval_param = iterator;
+
+ state->tree = IDL_PARAM_DCL(state->tree).param_type_spec;
+
+ /*
+ * Put in type of parameter
+ */
+
+ if (!xpcom_to_java_type(state)) {
+ return FALSE;
+ }
+#ifdef VBOX_XPIDL_EMULATE_GENJIFACES
+ if (IDL_tree_property_get(IDL_PARAM_DCL(IDL_LIST(iterator).data).simple_declarator, "array")) {
+ fputs("[]", state->file);
+ }
+#endif
+ }
+
+ state->tree = original_tree;
+ }
+
+ if (retval_param == NULL) {
+ fputs("void", state->file);
+ }
+ }
+
+ /*
+ * Write method name
+ */
+#ifdef VBOX_XPIDL_EMULATE_GENJIFACES
+ if (is_java_keyword(tolower(method_name[0]), method_name)) {
+ fprintf(state->file, " %c%s_(", tolower(method_name[0]), method_name + 1);
+ } else {
+ fprintf(state->file, " %c%s(", tolower(method_name[0]), method_name + 1);
+ }
+#else
+ fprintf(state->file, " %c%s(", tolower(method_name[0]), method_name + 1);
+#endif
+
+ /*
+ * Write parameters
+ */
+ for (iterator = method->parameter_dcls; iterator != NULL;
+ iterator = IDL_LIST(iterator).next) {
+
+ /* Skip "retval" */
+ if (iterator == retval_param) {
+ continue;
+ }
+
+ if (iterator != method->parameter_dcls) {
+ fputs(", ", state->file);
+ }
+
+ state->tree = IDL_LIST(iterator).data;
+
+#ifdef VBOX_XPIDL_EMULATE_GENJIFACES_DIFF
+ if (!xpcom_to_java_param(state, nparam++)) {
+#else
+ if (!xpcom_to_java_param(state)) {
+#endif
+ return FALSE;
+ }
+ }
+
+ fputs(")", state->file);
+
+ if (method->raises_expr) {
+ IDL_tree iter = method->raises_expr;
+ IDL_tree dataNode = IDL_LIST(iter).data;
+
+ fputs(" throws ", state->file);
+ fputs(IDL_IDENT(dataNode).str, state->file);
+ iter = IDL_LIST(iter).next;
+
+ while (iter) {
+ dataNode = IDL_LIST(iter).data;
+ fprintf(state->file, ", %s", IDL_IDENT(dataNode).str);
+ iter = IDL_LIST(iter).next;
+ }
+ }
+
+ fputs(";\n", state->file);
+
+ return TRUE;
+
+}
+
+
+static gboolean
+constant_declaration(TreeState *state)
+{
+ struct _IDL_CONST_DCL *declaration = &IDL_CONST_DCL(state->tree);
+ const char *name = IDL_IDENT(declaration->ident).str;
+ IDL_tree real_type;
+
+ if (!verify_const_declaration(state->tree))
+ return FALSE;
+
+ /* Could be a typedef; try to map it to the real type. */
+ real_type = find_underlying_type(declaration->const_type);
+ real_type = real_type ? real_type : declaration->const_type;
+
+ fputc('\n', state->file);
+#ifndef VBOX_XPIDL_EMULATE_GENJIFACES_DIFF
+ xpidl_write_comment(state, 4);
+#endif
+
+#ifdef VBOX_XPIDL_EMULATE_GENJIFACES
+# ifdef VBOX_XPIDL_EMULATE_GENJIFACES_DIFF
+ fputs(" public static final ", state->file);
+# else
+ fputs(" public static final ", state->file);
+# endif
+ if (IDL_TYPE_INTEGER(real_type).f_type == IDL_INTEGER_TYPE_LONG) {
+ if (IDL_TYPE_INTEGER(real_type).f_signed)
+ fprintf(state->file, "int %s = %" IDL_LL "d;\n", name, IDL_INTEGER(declaration->const_exp).value);
+ else
+ fprintf(state->file, "long %s = %" IDL_LL "uL;\n", name, IDL_INTEGER(declaration->const_exp).value);
+ } else {
+ if (IDL_TYPE_INTEGER(real_type).f_signed)
+ fprintf(state->file, "short %s = %" IDL_LL "d;\n", name, IDL_INTEGER(declaration->const_exp).value);
+ else
+ fprintf(state->file, "int %s = %" IDL_LL "u;\n", name, IDL_INTEGER(declaration->const_exp).value);
+ }
+#else /* !VBOX_XPIDL_EMULATE_GENJIFACES */
+ fprintf(state->file, " public static final %s %s = %d;\n",
+ (IDL_TYPE_INTEGER(real_type).f_type == IDL_INTEGER_TYPE_LONG
+ ? "long" : "short"),
+ name, (int) IDL_INTEGER(declaration->const_exp).value);
+#endif /* !VBOX_XPIDL_EMULATE_GENJIFACES */
+
+ return TRUE;
+
+}
+
+#define ATTR_IDENT(tree) (IDL_IDENT(IDL_LIST(IDL_ATTR_DCL((tree)).simple_declarations).data))
+#define ATTR_PROPS(tree) (IDL_LIST(IDL_ATTR_DCL((tree)).simple_declarations).data)
+#define ATTR_TYPE_DECL(tree) (IDL_ATTR_DCL((tree)).param_type_spec)
+
+
+static gboolean
+attribute_declaration(TreeState *state)
+{
+ gboolean read_only = IDL_ATTR_DCL(state->tree).f_readonly;
+ char *attribute_name = ATTR_IDENT(state->tree).str;
+
+ gboolean method_noscript =
+ (IDL_tree_property_get(ATTR_PROPS(state->tree), "noscript") != NULL);
+
+#ifdef VBOX_XPIDL_EMULATE_GENJIFACES
+ /*
+ * Skip most non-scriptable attributes.
+ */
+ if (method_noscript) {
+ return TRUE;
+ }
+#endif
+
+#if 0
+ /*
+ * Disabled here because I can't verify this check against possible
+ * users of the java xpidl backend.
+ */
+ if (!verify_attribute_declaration(state->tree))
+ return FALSE;
+#endif
+
+ /* Comment */
+ fputc('\n', state->file);
+#ifndef VBOX_XPIDL_EMULATE_GENJIFACES_DIFF
+ xpidl_write_comment(state, 4);
+#endif
+
+ state->tree = ATTR_TYPE_DECL(state->tree);
+
+ /*
+ * Write access permission ("public" unless nonscriptable)
+ */
+#ifdef VBOX_XPIDL_EMULATE_GENJIFACES_DIFF
+ fputs(" ", state->file);
+#else
+ fputs(" ", state->file);
+#endif
+ if (!method_noscript) {
+ fputs("public ", state->file);
+ }
+
+ /*
+ * Write the proper Java return value for the get operation
+ */
+ if (!xpcom_to_java_type(state)) {
+ return FALSE;
+ }
+
+ /*
+ * Write the name of the accessor ("get") method.
+ */
+ fprintf(state->file, " get%c%s();\n",
+ toupper(attribute_name[0]), attribute_name + 1);
+
+
+ if (!read_only) {
+ /* Nonscriptable methods become package-protected */
+#ifdef VBOX_XPIDL_EMULATE_GENJIFACES_DIFF
+ fputs("\n ", state->file);
+#else
+ fputs(" ", state->file);
+#endif
+ if (!method_noscript) {
+ fputs("public ", state->file);
+ }
+
+ /*
+ * Write attribute access method name and return type
+ */
+ fprintf(state->file, "void set%c%s(",
+ toupper(attribute_name[0]),
+ attribute_name+1);
+
+ /*
+ * Write the proper Java type for the set operation
+ */
+ if (!xpcom_to_java_type(state)) {
+ return FALSE;
+ }
+
+ /*
+ * Write the name of the formal parameter.
+ */
+#ifdef VBOX_XPIDL_EMULATE_GENJIFACES_DIFF
+ fputs(" arg1);\n", state->file);
+#else
+ fputs(" value);\n", state->file);
+#endif
+ }
+
+ return TRUE;
+}
+
+
+static gboolean
+enum_declaration(TreeState *state)
+{
+ XPIDL_WARNING((state->tree, IDL_WARNING1,
+ "enums not supported, enum \'%s\' ignored",
+ IDL_IDENT(IDL_TYPE_ENUM(state->tree).ident).str));
+ return TRUE;
+}
+
+backend *
+xpidl_java_dispatch(void)
+{
+ static backend result;
+ static nodeHandler table[IDLN_LAST];
+ static gboolean initialized = FALSE;
+
+ result.emit_prolog = java_prolog;
+ result.emit_epilog = java_epilog;
+
+ if (!initialized) {
+#ifdef VBOX_XPIDL_EMULATE_GENJIFACES
+ table[IDLN_INTERFACE] = interface_declaration_wrapper;
+#else
+ table[IDLN_INTERFACE] = interface_declaration;
+#endif
+ table[IDLN_LIST] = process_list;
+
+ table[IDLN_OP_DCL] = method_declaration;
+ table[IDLN_ATTR_DCL] = attribute_declaration;
+ table[IDLN_CONST_DCL] = constant_declaration;
+
+ table[IDLN_TYPE_DCL] = type_declaration;
+ table[IDLN_FORWARD_DCL] = forward_declaration;
+
+ table[IDLN_TYPE_ENUM] = enum_declaration;
+
+ initialized = TRUE;
+ }
+
+ result.dispatch_table = table;
+ return &result;
+}
+
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpidl/xpidl_typelib.c b/src/libs/xpcom18a4/xpcom/typelib/xpidl/xpidl_typelib.c
new file mode 100644
index 00000000..f2daae0d
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpidl/xpidl_typelib.c
@@ -0,0 +1,1237 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: NPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Netscape 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/NPL/
+ *
+ * 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 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 NPL, 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 NPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * Generate typelib files for use with InterfaceInfo.
+ * http://www.mozilla.org/scriptable/typelib_file.html
+ */
+
+#include "xpidl.h"
+#include <xpt_xdr.h>
+#include <xpt_struct.h>
+#include <time.h> /* XXX XP? */
+
+struct priv_data {
+ XPTHeader *header;
+ uint16 ifaces;
+ GHashTable *interface_map;
+ XPTInterfaceDescriptor *current;
+ XPTArena *arena;
+ uint16 next_method;
+ uint16 next_const;
+ uint16 next_type; /* used for 'additional_types' for idl arrays */
+};
+
+#define HEADER(state) (((struct priv_data *)state->priv)->header)
+#define IFACES(state) (((struct priv_data *)state->priv)->ifaces)
+#define IFACE_MAP(state) (((struct priv_data *)state->priv)->interface_map)
+#define CURRENT(state) (((struct priv_data *)state->priv)->current)
+#define ARENA(state) (((struct priv_data *)state->priv)->arena)
+#define NEXT_METH(state) (((struct priv_data *)state->priv)->next_method)
+#define NEXT_CONST(state) (((struct priv_data *)state->priv)->next_const)
+#define NEXT_TYPE(state) (((struct priv_data *)state->priv)->next_type)
+
+#ifdef DEBUG_shaver
+/* #define DEBUG_shaver_sort */
+#endif
+
+typedef struct {
+ char *full_name;
+ char *name;
+ char *name_space;
+ char *iid;
+ gboolean is_forward_dcl;
+} NewInterfaceHolder;
+
+static NewInterfaceHolder*
+CreateNewInterfaceHolder(char *name, char *name_space, char *iid,
+ gboolean is_forward_dcl)
+{
+ NewInterfaceHolder *holder = calloc(1, sizeof(NewInterfaceHolder));
+ if (holder) {
+ holder->is_forward_dcl = is_forward_dcl;
+ if (name)
+ holder->name = xpidl_strdup(name);
+ if (name_space)
+ holder->name_space = xpidl_strdup(name_space);
+ if (holder->name && holder->name_space) {
+ holder->full_name = calloc(1, strlen(holder->name) +
+ strlen(holder->name_space) + 2);
+ }
+ if (holder->full_name) {
+ strcpy(holder->full_name, holder->name_space);
+ strcat(holder->full_name, ".");
+ strcat(holder->full_name, holder->name);
+ }
+ else
+ holder->full_name = holder->name;
+ if (iid)
+ holder->iid = xpidl_strdup(iid);
+ }
+ return holder;
+}
+
+static void
+DeleteNewInterfaceHolder(NewInterfaceHolder *holder)
+{
+ if (holder) {
+ if (holder->full_name && holder->full_name != holder->name)
+ free(holder->full_name);
+ if (holder->name)
+ free(holder->name);
+ if (holder->name_space)
+ free(holder->name_space);
+ if (holder->iid)
+ free(holder->iid);
+ free(holder);
+ }
+}
+
+/*
+ * If p is an ident for an interface, and we don't have an entry in the
+ * interface map yet, add one.
+ */
+static gboolean
+add_interface_maybe(IDL_tree_func_data *tfd, gpointer user_data)
+{
+ TreeState *state = user_data;
+ IDL_tree up;
+ if (IDL_NODE_TYPE(tfd->tree) == IDLN_IDENT) {
+ IDL_tree_type node_type = IDL_NODE_TYPE((up = IDL_NODE_UP(tfd->tree)));
+ if (node_type == IDLN_INTERFACE || node_type == IDLN_FORWARD_DCL) {
+
+ /* We only want to add a new entry if there is no entry by this
+ * name or if the previously found entry was just a forward
+ * declaration and the new entry is not.
+ */
+
+ char *iface = IDL_IDENT(tfd->tree).str;
+ NewInterfaceHolder *old_holder = (NewInterfaceHolder *)
+ g_hash_table_lookup(IFACE_MAP(state), iface);
+ if (old_holder && old_holder->is_forward_dcl &&
+ node_type != IDLN_FORWARD_DCL)
+ {
+ g_hash_table_remove(IFACE_MAP(state), iface);
+ DeleteNewInterfaceHolder(old_holder);
+ old_holder = NULL;
+ }
+ if (!old_holder) {
+ /* XXX should we parse here and store a struct nsID *? */
+ char *iid = (char *)IDL_tree_property_get(tfd->tree, "uuid");
+ char *name_space = (char *)
+ IDL_tree_property_get(tfd->tree, "namespace");
+ NewInterfaceHolder *holder =
+ CreateNewInterfaceHolder(iface, name_space, iid,
+ (gboolean) node_type == IDLN_FORWARD_DCL);
+ if (!holder)
+ return FALSE;
+ g_hash_table_insert(IFACE_MAP(state),
+ holder->full_name, holder);
+ IFACES(state)++;
+#ifdef DEBUG_shaver_ifaces
+ fprintf(stderr, "adding interface #%d: %s/%s\n", IFACES(state),
+ iface, iid[0] ? iid : "<unresolved>");
+#endif
+ }
+ } else {
+#ifdef DEBUG_shaver_ifaces
+ fprintf(stderr, "ident %s isn't an interface (%s)\n",
+ IDL_IDENT(tfd->tree).str, IDL_NODE_TYPE_NAME(up));
+#endif
+ }
+ }
+
+ return TRUE;
+}
+
+/* Find all the interfaces referenced in the tree (uses add_interface_maybe) */
+static gboolean
+find_interfaces(IDL_tree_func_data *tfd, gpointer user_data)
+{
+ IDL_tree node = NULL;
+
+ switch (IDL_NODE_TYPE(tfd->tree)) {
+ case IDLN_ATTR_DCL:
+ node = IDL_ATTR_DCL(tfd->tree).param_type_spec;
+ break;
+ case IDLN_OP_DCL:
+ IDL_tree_walk_in_order(IDL_OP_DCL(tfd->tree).parameter_dcls, find_interfaces,
+ user_data);
+ node = IDL_OP_DCL(tfd->tree).op_type_spec;
+ break;
+ case IDLN_PARAM_DCL:
+ node = IDL_PARAM_DCL(tfd->tree).param_type_spec;
+ break;
+ case IDLN_INTERFACE:
+ node = IDL_INTERFACE(tfd->tree).inheritance_spec;
+ if (node)
+ xpidl_list_foreach(node, add_interface_maybe, user_data);
+ node = IDL_INTERFACE(tfd->tree).ident;
+ break;
+ case IDLN_FORWARD_DCL:
+ node = IDL_FORWARD_DCL(tfd->tree).ident;
+ break;
+ default:
+ node = NULL;
+ }
+
+ if (node && IDL_NODE_TYPE(node) == IDLN_IDENT) {
+ IDL_tree_func_data new_tfd;
+ new_tfd.tree = node;
+ add_interface_maybe(&new_tfd, user_data);
+ }
+
+ return TRUE;
+}
+
+#ifdef DEBUG_shaver
+/* for calling from gdb */
+static void
+print_IID(struct nsID *iid, FILE *file)
+{
+ char iid_buf[UUID_LENGTH];
+
+ xpidl_sprint_iid(iid, iid_buf);
+ fprintf(file, "%s\n", iid_buf);
+}
+#endif
+
+/* fill the interface_directory IDE table from the interface_map */
+static gboolean
+fill_ide_table(gpointer key, gpointer value, gpointer user_data)
+{
+ TreeState *state = user_data;
+ NewInterfaceHolder *holder = (NewInterfaceHolder *) value;
+ struct nsID id;
+ XPTInterfaceDirectoryEntry *ide;
+
+ XPT_ASSERT(holder);
+
+#ifdef DEBUG_shaver_ifaces
+ fprintf(stderr, "filling %s\n", holder->full_name);
+#endif
+
+ if (holder->iid) {
+ if (strlen(holder->iid) != 36) {
+ IDL_tree_error(state->tree, "IID %s is the wrong length\n",
+ holder->iid);
+ return FALSE;
+ }
+ if (!xpidl_parse_iid(&id, holder->iid)) {
+ IDL_tree_error(state->tree, "cannot parse IID %s\n", holder->iid);
+ return FALSE;
+ }
+ } else {
+ memset(&id, 0, sizeof(id));
+ }
+
+ ide = &(HEADER(state)->interface_directory[IFACES(state)]);
+ if (!XPT_FillInterfaceDirectoryEntry(ARENA(state), ide, &id, holder->name,
+ holder->name_space, NULL)) {
+ IDL_tree_error(state->tree, "INTERNAL: XPT_FillIDE failed for %s\n",
+ holder->full_name);
+ return FALSE;
+ }
+
+ IFACES(state)++;
+ DeleteNewInterfaceHolder(holder);
+ return TRUE;
+}
+
+static int
+compare_IDEs(const void *ap, const void *bp)
+{
+ const XPTInterfaceDirectoryEntry *a = ap, *b = bp;
+ const nsID *aid = &a->iid, *bid = &b->iid;
+ const char *ans, *bns;
+
+ int i;
+#define COMPARE(field) if (aid->field > bid->field) return 1; \
+ if (bid->field > aid->field) return -1;
+ COMPARE(m0);
+ COMPARE(m1);
+ COMPARE(m2);
+ for (i = 0; i < 8; i++) {
+ COMPARE(m3[i]);
+ }
+
+ /* defend against NULL name_space by using empty string. */
+ ans = a->name_space ? a->name_space : "";
+ bns = b->name_space ? b->name_space : "";
+
+ if (a->name_space && b->name_space) {
+ if ((i = strcmp(a->name_space, b->name_space)))
+ return i;
+ } else {
+ if (a->name_space || b->name_space) {
+ if (a->name_space)
+ return -1;
+ return 1;
+ }
+ }
+ /* these had better not be NULL... */
+ return strcmp(a->name, b->name);
+#undef COMPARE
+}
+
+/* sort the IDE block as per the typelib spec: IID order, unresolved first */
+static void
+sort_ide_block(TreeState *state)
+{
+ XPTInterfaceDirectoryEntry *ide;
+ int i;
+
+ /* boy, I sure hope qsort works correctly everywhere */
+#ifdef DEBUG_shaver_sort
+ fputs("before sort:\n", stderr);
+ for (i = 0; i < IFACES(state); i++) {
+ fputs(" ", stderr);
+ print_IID(&HEADER(state)->interface_directory[i].iid, stderr);
+ fputc('\n', stderr);
+ }
+#endif
+ qsort(HEADER(state)->interface_directory, IFACES(state),
+ sizeof(*ide), compare_IDEs);
+#ifdef DEBUG_shaver_sort
+ fputs("after sort:\n", stderr);
+ for (i = 0; i < IFACES(state); i++) {
+ fputs(" ", stderr);
+ print_IID(&HEADER(state)->interface_directory[i].iid, stderr);
+ fputc('\n', stderr);
+ }
+#endif
+
+ for (i = 0; i < IFACES(state); i++) {
+ ide = HEADER(state)->interface_directory + i;
+ g_hash_table_insert(IFACE_MAP(state), ide->name, (void *)(i + 1));
+ }
+
+ return;
+}
+
+static gboolean
+typelib_list(TreeState *state)
+{
+ IDL_tree iter;
+ for (iter = state->tree; iter; iter = IDL_LIST(iter).next) {
+ state->tree = IDL_LIST(iter).data;
+ if (!xpidl_process_node(state))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static gboolean
+typelib_prolog(TreeState *state)
+{
+ state->priv = calloc(1, sizeof(struct priv_data));
+ if (!state->priv)
+ return FALSE;
+ IFACES(state) = 0;
+ IFACE_MAP(state) = g_hash_table_new(g_str_hash, g_str_equal);
+ if (!IFACE_MAP(state)) {
+ /* XXX report error */
+ free(state->priv);
+ return FALSE;
+ }
+ /* find all interfaces, top-level and referenced by others */
+ IDL_tree_walk_in_order(state->tree, find_interfaces, state);
+ ARENA(state) = XPT_NewArena(1024, sizeof(double), "main xpidl arena");
+ HEADER(state) = XPT_NewHeader(ARENA(state), IFACES(state),
+ major_version, minor_version);
+
+ /* fill IDEs from hash table */
+ IFACES(state) = 0;
+ g_hash_table_foreach_remove(IFACE_MAP(state), fill_ide_table, state);
+
+ /* if any are left then we must have failed in fill_ide_table */
+ if (g_hash_table_size(IFACE_MAP(state)))
+ return FALSE;
+
+ /* sort the IDEs by IID order and store indices in the interface map */
+ sort_ide_block(state);
+
+ return TRUE;
+}
+
+static gboolean
+typelib_epilog(TreeState *state)
+{
+ XPTState *xstate = XPT_NewXDRState(XPT_ENCODE, NULL, 0);
+ XPTCursor curs, *cursor = &curs;
+ PRUint32 i, len, header_sz;
+ PRUint32 oldOffset;
+ PRUint32 newOffset;
+ char *data;
+
+ /* Write any annotations */
+ if (emit_typelib_annotations) {
+ PRUint32 annotation_len, written_so_far;
+ char *annotate_val, *timestr;
+ time_t now;
+ static char *annotation_format =
+ "Created from %s.idl\nCreation date: %sInterfaces:";
+
+ /* fill in the annotations, listing resolved interfaces in order */
+
+ (void)time(&now);
+ timestr = ctime(&now);
+
+ /* Avoid dependence on nspr; no PR_smprintf and friends. */
+
+ /* How large should the annotation string be? */
+ annotation_len = strlen(annotation_format) + strlen(state->basename) +
+ strlen(timestr);
+#ifdef VBOX
+ /* note that '%s' is contained two times in annotation_format and both
+ * format specifiers are replaced by a string. So in fact we reserve 4
+ * bytes minus one byte (for the terminating '\0') more than necessary. */
+#endif
+ for (i = 0; i < HEADER(state)->num_interfaces; i++) {
+ XPTInterfaceDirectoryEntry *ide;
+ ide = &HEADER(state)->interface_directory[i];
+ if (ide->interface_descriptor) {
+ annotation_len += strlen(ide->name) + 1;
+ }
+ }
+
+ annotate_val = (char *) malloc(annotation_len);
+ written_so_far = sprintf(annotate_val, annotation_format,
+ state->basename, timestr);
+
+ for (i = 0; i < HEADER(state)->num_interfaces; i++) {
+ XPTInterfaceDirectoryEntry *ide;
+ ide = &HEADER(state)->interface_directory[i];
+ if (ide->interface_descriptor) {
+ written_so_far += sprintf(annotate_val + written_so_far, " %s",
+ ide->name);
+ }
+ }
+
+ HEADER(state)->annotations =
+ XPT_NewAnnotation(ARENA(state),
+ XPT_ANN_LAST | XPT_ANN_PRIVATE,
+ XPT_NewStringZ(ARENA(state), "xpidl 0.99.9"),
+ XPT_NewStringZ(ARENA(state), annotate_val));
+ free(annotate_val);
+ } else {
+ HEADER(state)->annotations =
+ XPT_NewAnnotation(ARENA(state), XPT_ANN_LAST, NULL, NULL);
+ }
+
+ if (!HEADER(state)->annotations) {
+ /* XXX report out of memory error */
+ return FALSE;
+ }
+
+ /* Write the typelib */
+ header_sz = XPT_SizeOfHeaderBlock(HEADER(state));
+
+ if (!xstate ||
+ !XPT_MakeCursor(xstate, XPT_HEADER, header_sz, cursor))
+ goto destroy_header;
+ oldOffset = cursor->offset;
+ if (!XPT_DoHeader(ARENA(state), cursor, &HEADER(state)))
+ goto destroy;
+ newOffset = cursor->offset;
+ XPT_GetXDRDataLength(xstate, XPT_HEADER, &len);
+ HEADER(state)->file_length = len;
+ XPT_GetXDRDataLength(xstate, XPT_DATA, &len);
+ HEADER(state)->file_length += len;
+ XPT_SeekTo(cursor, oldOffset);
+ if (!XPT_DoHeaderPrologue(ARENA(state), cursor, &HEADER(state), NULL))
+ goto destroy;
+ XPT_SeekTo(cursor, newOffset);
+ XPT_GetXDRData(xstate, XPT_HEADER, &data, &len);
+ fwrite(data, len, 1, state->file);
+ XPT_GetXDRData(xstate, XPT_DATA, &data, &len);
+ fwrite(data, len, 1, state->file);
+
+ destroy:
+ XPT_DestroyXDRState(xstate);
+ destroy_header:
+ /* XXX XPT_DestroyHeader(HEADER(state)) */
+
+ XPT_FreeHeader(ARENA(state), HEADER(state));
+ XPT_DestroyArena(ARENA(state));
+
+ /* XXX should destroy priv_data here */
+
+ return TRUE;
+}
+
+static XPTInterfaceDirectoryEntry *
+FindInterfaceByName(XPTInterfaceDirectoryEntry *ides, uint16 num_interfaces,
+ const char *name)
+{
+ uint16 i;
+ for (i = 0; i < num_interfaces; i++) {
+ if (!strcmp(ides[i].name, name))
+ return &ides[i];
+ }
+ return NULL;
+}
+
+static gboolean
+typelib_interface(TreeState *state)
+{
+ IDL_tree iface = state->tree, iter;
+ char *name = IDL_IDENT(IDL_INTERFACE(iface).ident).str;
+ XPTInterfaceDirectoryEntry *ide;
+ XPTInterfaceDescriptor *id;
+ uint16 parent_id = 0;
+ PRUint8 interface_flags = 0;
+
+ if (!verify_interface_declaration(iface))
+ return FALSE;
+
+ if (IDL_tree_property_get(IDL_INTERFACE(iface).ident, "scriptable"))
+ interface_flags |= XPT_ID_SCRIPTABLE;
+
+ if (IDL_tree_property_get(IDL_INTERFACE(iface).ident, "function"))
+ interface_flags |= XPT_ID_FUNCTION;
+
+ ide = FindInterfaceByName(HEADER(state)->interface_directory,
+ HEADER(state)->num_interfaces, name);
+ if (!ide) {
+ IDL_tree_error(iface, "ERROR: didn't find interface %s in "
+ "IDE block. Giving up.\n", name);
+ return FALSE;
+ }
+
+ if ((iter = IDL_INTERFACE(iface).inheritance_spec)) {
+ char *parent;
+ if (IDL_LIST(iter).next) {
+ IDL_tree_error(iface,
+ "ERROR: more than one parent interface for %s\n",
+ name);
+ return FALSE;
+ }
+ parent = IDL_IDENT(IDL_LIST(iter).data).str;
+ parent_id = (uint16)(uint32)g_hash_table_lookup(IFACE_MAP(state),
+ parent);
+ if (!parent_id) {
+ IDL_tree_error(iface,
+ "ERROR: no index found for %s. Giving up.\n",
+ parent);
+ return FALSE;
+ }
+ }
+
+ id = XPT_NewInterfaceDescriptor(ARENA(state), parent_id, 0, 0,
+ interface_flags);
+ if (!id)
+ return FALSE;
+
+ CURRENT(state) = ide->interface_descriptor = id;
+#ifdef DEBUG_shaver_ifaces
+ fprintf(stderr, "DBG: starting interface %s @ %p\n", name, id);
+#endif
+
+ NEXT_METH(state) = 0;
+ NEXT_CONST(state) = 0;
+ NEXT_TYPE(state) = 0;
+
+ state->tree = IDL_INTERFACE(iface).body;
+ if (state->tree && !xpidl_process_node(state))
+ return FALSE;
+#ifdef DEBUG_shaver_ifaces
+ fprintf(stderr, "DBG: ending interface %s\n", name);
+#endif
+ return TRUE;
+}
+
+static gboolean
+find_arg_with_name(TreeState *state, const char *name, int16 *argnum)
+{
+ int16 count;
+ IDL_tree params;
+
+ XPT_ASSERT(state);
+ XPT_ASSERT(name);
+ XPT_ASSERT(argnum);
+
+ params = IDL_OP_DCL(IDL_NODE_UP(IDL_NODE_UP(state->tree))).parameter_dcls;
+ for (count = 0;
+ params != NULL && IDL_LIST(params).data != NULL;
+ params = IDL_LIST(params).next, count++)
+ {
+ const char *cur_name = IDL_IDENT(
+ IDL_PARAM_DCL(IDL_LIST(params).data).simple_declarator).str;
+ if (!strcmp(cur_name, name)) {
+ /* XXX ought to verify that this is the right type here */
+ /* XXX for iid_is this must be an iid */
+ /* XXX for size_is and length_is this must be a uint32 */
+ *argnum = count;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/* return value is for success or failure */
+static gboolean
+get_size_and_length(TreeState *state, IDL_tree type,
+ int16 *size_is_argnum, int16 *length_is_argnum,
+ gboolean *has_size_is, gboolean *has_length_is)
+{
+ *has_size_is = FALSE;
+ *has_length_is = FALSE;
+
+ if (IDL_NODE_TYPE(state->tree) == IDLN_PARAM_DCL) {
+ IDL_tree sd = IDL_PARAM_DCL(state->tree).simple_declarator;
+ const char *size_is;
+ const char *length_is;
+
+ /* only if size_is is found does any of this matter */
+ size_is = IDL_tree_property_get(sd, "size_is");
+ if (!size_is)
+ return TRUE;
+
+ if (!find_arg_with_name(state, size_is, size_is_argnum)) {
+ IDL_tree_error(state->tree, "can't find matching argument for "
+ "[size_is(%s)]\n", size_is);
+ return FALSE;
+ }
+ *has_size_is = TRUE;
+
+ /* length_is is optional */
+ length_is = IDL_tree_property_get(sd, "length_is");
+ if (length_is) {
+ *has_length_is = TRUE;
+ if (!find_arg_with_name(state, length_is, length_is_argnum)) {
+ IDL_tree_error(state->tree, "can't find matching argument for "
+ "[length_is(%s)]\n", length_is);
+ return FALSE;
+ }
+ }
+ }
+ return TRUE;
+}
+
+static gboolean
+fill_td_from_type(TreeState *state, XPTTypeDescriptor *td, IDL_tree type)
+{
+ IDL_tree up;
+ int16 size_is_argnum;
+ int16 length_is_argnum;
+ gboolean has_size_is;
+ gboolean has_length_is;
+ gboolean is_array = FALSE;
+
+ if (type) {
+
+ /* deal with array */
+
+ if (IDL_NODE_TYPE(state->tree) == IDLN_PARAM_DCL) {
+ IDL_tree sd = IDL_PARAM_DCL(state->tree).simple_declarator;
+ if (IDL_tree_property_get(sd, "array")) {
+
+ is_array = TRUE;
+
+ /* size_is is required! */
+ if (!get_size_and_length(state, type,
+ &size_is_argnum, &length_is_argnum,
+ &has_size_is, &has_length_is)) {
+ /* error was reported by helper function */
+ return FALSE;
+ }
+
+ if (!has_size_is) {
+ IDL_tree_error(state->tree, "[array] requires [size_is()]\n");
+ return FALSE;
+ }
+
+ td->prefix.flags = TD_ARRAY | XPT_TDP_POINTER;
+ td->argnum = size_is_argnum;
+
+ if (has_length_is)
+ td->argnum2 = length_is_argnum;
+ else
+ td->argnum2 = size_is_argnum;
+
+ /*
+ * XXX - NOTE - this will be broken for multidimensional
+ * arrays because of the realloc XPT_InterfaceDescriptorAddTypes
+ * uses. The underlying 'td' can change as we recurse in to get
+ * additional dimensions. Luckily, we don't yet support more
+ * than on dimension in the arrays
+ */
+ /* setup the additional_type */
+ if (!XPT_InterfaceDescriptorAddTypes(ARENA(state),
+ CURRENT(state), 1)) {
+ g_error("out of memory\n");
+ return FALSE;
+ }
+ td->type.additional_type = NEXT_TYPE(state);
+ td = &CURRENT(state)->additional_types[NEXT_TYPE(state)];
+ NEXT_TYPE(state)++ ;
+ }
+ }
+
+handle_typedef:
+ switch (IDL_NODE_TYPE(type)) {
+ case IDLN_TYPE_INTEGER: {
+ gboolean sign = IDL_TYPE_INTEGER(type).f_signed;
+ switch(IDL_TYPE_INTEGER(type).f_type) {
+ case IDL_INTEGER_TYPE_SHORT:
+ td->prefix.flags = sign ? TD_INT16 : TD_UINT16;
+ break;
+ case IDL_INTEGER_TYPE_LONG:
+ td->prefix.flags = sign ? TD_INT32 : TD_UINT32;
+ break;
+ case IDL_INTEGER_TYPE_LONGLONG:
+ td->prefix.flags = sign ? TD_INT64 : TD_UINT64;
+ break;
+ }
+ break;
+ }
+ case IDLN_TYPE_CHAR:
+ td->prefix.flags = TD_CHAR;
+ break;
+ case IDLN_TYPE_WIDE_CHAR:
+ td->prefix.flags = TD_WCHAR;
+ break;
+ case IDLN_TYPE_STRING:
+ if (is_array) {
+ td->prefix.flags = TD_PSTRING | XPT_TDP_POINTER;
+ } else {
+ if (!get_size_and_length(state, type,
+ &size_is_argnum, &length_is_argnum,
+ &has_size_is, &has_length_is)) {
+ /* error was reported by helper function */
+ return FALSE;
+ }
+ if (has_size_is) {
+ td->prefix.flags = TD_PSTRING_SIZE_IS | XPT_TDP_POINTER;
+ td->argnum = size_is_argnum;
+ if (has_length_is)
+ td->argnum2 = length_is_argnum;
+ else
+ td->argnum2 = size_is_argnum;
+ } else {
+ td->prefix.flags = TD_PSTRING | XPT_TDP_POINTER;
+ }
+ }
+ break;
+ case IDLN_TYPE_WIDE_STRING:
+ if (is_array) {
+ td->prefix.flags = TD_PWSTRING | XPT_TDP_POINTER;
+ } else {
+ if (!get_size_and_length(state, type,
+ &size_is_argnum, &length_is_argnum,
+ &has_size_is, &has_length_is)) {
+ /* error was reported by helper function */
+ return FALSE;
+ }
+ if (has_size_is) {
+ td->prefix.flags = TD_PWSTRING_SIZE_IS | XPT_TDP_POINTER;
+ td->argnum = size_is_argnum;
+ if (has_length_is)
+ td->argnum2 = length_is_argnum;
+ else
+ td->argnum2 = size_is_argnum;
+ } else {
+ td->prefix.flags = TD_PWSTRING | XPT_TDP_POINTER;
+ }
+ }
+ break;
+ case IDLN_TYPE_BOOLEAN:
+ td->prefix.flags = TD_BOOL;
+ break;
+ case IDLN_TYPE_OCTET:
+ td->prefix.flags = TD_UINT8;
+ break;
+ case IDLN_TYPE_FLOAT:
+ switch (IDL_TYPE_FLOAT (type).f_type) {
+ case IDL_FLOAT_TYPE_FLOAT:
+ td->prefix.flags = TD_FLOAT;
+ break;
+ case IDL_FLOAT_TYPE_DOUBLE:
+ td->prefix.flags = TD_DOUBLE;
+ break;
+ /* XXX 'long double' just ignored, or what? */
+ default: break;
+ }
+ break;
+ case IDLN_IDENT:
+ if (!(up = IDL_NODE_UP(type))) {
+ IDL_tree_error(state->tree,
+ "ERROR: orphan ident %s in param list\n",
+ IDL_IDENT(type).str);
+ return FALSE;
+ }
+ switch (IDL_NODE_TYPE(up)) {
+ /* This whole section is abominably ugly */
+ case IDLN_FORWARD_DCL:
+ case IDLN_INTERFACE: {
+ XPTInterfaceDirectoryEntry *ide, *ides;
+ uint16 num_ifaces;
+ char *className;
+ const char *iid_is;
+handle_iid_is:
+ ides = HEADER(state)->interface_directory;
+ num_ifaces = HEADER(state)->num_interfaces;
+ /* might get here via the goto, so re-check type */
+ if (IDL_NODE_TYPE(up) == IDLN_INTERFACE)
+ className = IDL_IDENT(IDL_INTERFACE(up).ident).str;
+ else if (IDL_NODE_TYPE(up) == IDLN_FORWARD_DCL)
+ className = IDL_IDENT(IDL_FORWARD_DCL(up).ident).str;
+ else
+ className = IDL_IDENT(IDL_NATIVE(up).ident).str;
+ iid_is = NULL;
+
+ if (IDL_NODE_TYPE(state->tree) == IDLN_PARAM_DCL) {
+ iid_is =
+ IDL_tree_property_get(IDL_PARAM_DCL(state->tree).simple_declarator,
+ "iid_is");
+ }
+ if (iid_is) {
+ int16 argnum;
+ if (!find_arg_with_name(state, iid_is, &argnum)) {
+ IDL_tree_error(state->tree,
+ "can't find matching argument for "
+ "[iid_is(%s)]\n", iid_is);
+ return FALSE;
+ }
+ td->prefix.flags = TD_INTERFACE_IS_TYPE | XPT_TDP_POINTER;
+ td->argnum = argnum;
+ } else {
+ td->prefix.flags = TD_INTERFACE_TYPE | XPT_TDP_POINTER;
+ ide = FindInterfaceByName(ides, num_ifaces, className);
+ if (!ide || ide < ides || ide > ides + num_ifaces) {
+ IDL_tree_error(state->tree,
+ "unknown iface %s in param\n",
+ className);
+ return FALSE;
+ }
+ td->type.iface = ide - ides + 1;
+#ifdef DEBUG_shaver_index
+ fprintf(stderr, "DBG: index %d for %s\n",
+ td->type.iface, className);
+#endif
+ }
+ break;
+ }
+ case IDLN_NATIVE: {
+ char *ident;
+
+ /* jband - adding goto for iid_is when type is native */
+ if (IDL_NODE_TYPE(state->tree) == IDLN_PARAM_DCL &&
+ IDL_tree_property_get(IDL_PARAM_DCL(state->tree).simple_declarator,
+ "iid_is"))
+ goto handle_iid_is;
+
+ ident = IDL_IDENT(type).str;
+ if (IDL_tree_property_get(type, "nsid")) {
+ td->prefix.flags = TD_PNSIID;
+ if (IDL_tree_property_get(type, "ref"))
+ td->prefix.flags |= XPT_TDP_POINTER | XPT_TDP_REFERENCE;
+ else if (IDL_tree_property_get(type,"ptr"))
+ td->prefix.flags |= XPT_TDP_POINTER;
+ } else if (IDL_tree_property_get(type, "domstring")) {
+ td->prefix.flags = TD_DOMSTRING | XPT_TDP_POINTER;
+ if (IDL_tree_property_get(type, "ref"))
+ td->prefix.flags |= XPT_TDP_REFERENCE;
+ } else if (IDL_tree_property_get(type, "astring")) {
+ td->prefix.flags = TD_ASTRING | XPT_TDP_POINTER;
+ if (IDL_tree_property_get(type, "ref"))
+ td->prefix.flags |= XPT_TDP_REFERENCE;
+ } else if (IDL_tree_property_get(type, "utf8string")) {
+ td->prefix.flags = TD_UTF8STRING | XPT_TDP_POINTER;
+ if (IDL_tree_property_get(type, "ref"))
+ td->prefix.flags |= XPT_TDP_REFERENCE;
+ } else if (IDL_tree_property_get(type, "cstring")) {
+ td->prefix.flags = TD_CSTRING | XPT_TDP_POINTER;
+ if (IDL_tree_property_get(type, "ref"))
+ td->prefix.flags |= XPT_TDP_REFERENCE;
+ } else {
+ td->prefix.flags = TD_VOID | XPT_TDP_POINTER;
+ }
+ break;
+ }
+ default:
+ if (IDL_NODE_TYPE(IDL_NODE_UP(up)) == IDLN_TYPE_DCL) {
+ /* restart with the underlying type */
+ IDL_tree new_type;
+ new_type = IDL_TYPE_DCL(IDL_NODE_UP(up)).type_spec;
+#ifdef DEBUG_shaver_misc
+ fprintf(stderr, "following %s typedef to %s\n",
+ IDL_IDENT(type).str, IDL_NODE_TYPE_NAME(new_type));
+#endif
+ /*
+ * Do a nice messy goto rather than recursion so that
+ * we can avoid screwing up the *array* information.
+ */
+/* return fill_td_from_type(state, td, new_type); */
+ if (new_type) {
+ type = new_type;
+ goto handle_typedef;
+ } else {
+ /* do what we would do in recursion if !type */
+ td->prefix.flags = TD_VOID;
+ return TRUE;
+ }
+ }
+ IDL_tree_error(state->tree,
+ "can't handle %s ident in param list\n",
+#ifdef DEBUG_shaver
+ /* XXX is this safe to use on Win now? */
+ IDL_NODE_TYPE_NAME(IDL_NODE_UP(type))
+#else
+ "that type of"
+#endif
+ );
+#ifdef DEBUG_shaver
+ XPT_ASSERT(0);
+#endif
+ return FALSE;
+ }
+ break;
+ default:
+ IDL_tree_error(state->tree, "can't handle %s in param list\n",
+#ifdef DEBUG_shaver
+ /* XXX is this safe to use on Win now? */
+ IDL_NODE_TYPE_NAME(IDL_NODE_UP(type))
+#else
+ "that type"
+#endif
+ );
+ return FALSE;
+ }
+ } else {
+ td->prefix.flags = TD_VOID;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+fill_pd_from_type(TreeState *state, XPTParamDescriptor *pd, uint8 flags,
+ IDL_tree type)
+{
+ pd->flags = flags;
+ return fill_td_from_type(state, &pd->type, type);
+}
+
+static gboolean
+fill_pd_from_param(TreeState *state, XPTParamDescriptor *pd, IDL_tree tree)
+{
+ uint8 flags = 0;
+ gboolean is_dipper_type = DIPPER_TYPE(IDL_PARAM_DCL(tree).param_type_spec);
+
+ switch (IDL_PARAM_DCL(tree).attr) {
+ case IDL_PARAM_IN:
+ flags = XPT_PD_IN;
+ break;
+ case IDL_PARAM_OUT:
+ flags = XPT_PD_OUT;
+ break;
+ case IDL_PARAM_INOUT:
+ flags = XPT_PD_IN | XPT_PD_OUT;
+ break;
+ }
+
+ if (IDL_tree_property_get(IDL_PARAM_DCL(tree).simple_declarator,
+ "retval")) {
+ if (flags != XPT_PD_OUT) {
+ IDL_tree_error(tree, "can't have [retval] with in%s param "
+ "(only out)\n",
+ flags & XPT_PD_OUT ? "out" : "");
+ return FALSE;
+ }
+ flags |= XPT_PD_RETVAL;
+ }
+
+ if (is_dipper_type && (flags & XPT_PD_OUT)) {
+ flags &= ~XPT_PD_OUT;
+ flags |= XPT_PD_IN | XPT_PD_DIPPER;
+ }
+
+ if (IDL_tree_property_get(IDL_PARAM_DCL(tree).simple_declarator,
+ "shared")) {
+ if (flags & XPT_PD_IN) {
+ IDL_tree_error(tree, "can't have [shared] with in%s param "
+ "(only out)\n",
+ flags & XPT_PD_OUT ? "out" : "");
+ return FALSE;
+ }
+ flags |= XPT_PD_SHARED;
+ }
+
+ /* stick param where we can see it later */
+ state->tree = tree;
+ return fill_pd_from_type(state, pd, flags,
+ IDL_PARAM_DCL(tree).param_type_spec);
+}
+
+/* XXXshaver common with xpidl_header.c */
+#define ATTR_IDENT(tree) (IDL_IDENT(IDL_LIST(IDL_ATTR_DCL(tree).simple_declarations).data))
+#define ATTR_TYPE_DECL(tree) (IDL_ATTR_DCL(tree).param_type_spec)
+#define ATTR_TYPE(tree) (IDL_NODE_TYPE(ATTR_TYPE_DECL(tree)))
+
+static gboolean
+fill_pd_as_nsresult(XPTParamDescriptor *pd)
+{
+ pd->type.prefix.flags = TD_UINT32; /* TD_NSRESULT */
+ return TRUE;
+}
+
+static gboolean
+typelib_attr_accessor(TreeState *state, XPTMethodDescriptor *meth,
+ gboolean getter, gboolean hidden)
+{
+ uint8 methflags = 0;
+ uint8 pdflags = 0;
+
+ methflags |= getter ? XPT_MD_GETTER : XPT_MD_SETTER;
+ methflags |= hidden ? XPT_MD_HIDDEN : 0;
+ if (!XPT_FillMethodDescriptor(ARENA(state), meth, methflags,
+ ATTR_IDENT(state->tree).str, 1))
+ return FALSE;
+
+ if (getter) {
+ if (DIPPER_TYPE(ATTR_TYPE_DECL(state->tree))) {
+ pdflags |= (XPT_PD_RETVAL | XPT_PD_IN | XPT_PD_DIPPER);
+ } else {
+ pdflags |= (XPT_PD_RETVAL | XPT_PD_OUT);
+ }
+ } else {
+ pdflags |= XPT_PD_IN;
+ }
+
+ if (!fill_pd_from_type(state, meth->params, pdflags,
+ ATTR_TYPE_DECL(state->tree)))
+ return FALSE;
+
+ fill_pd_as_nsresult(meth->result);
+ NEXT_METH(state)++;
+ return TRUE;
+}
+
+static gboolean
+typelib_attr_dcl(TreeState *state)
+{
+ XPTInterfaceDescriptor *id = CURRENT(state);
+ XPTMethodDescriptor *meth;
+ gboolean read_only = IDL_ATTR_DCL(state->tree).f_readonly;
+
+ /* XXX this only handles the first ident; elsewhere too... */
+ IDL_tree ident =
+ IDL_LIST(IDL_ATTR_DCL(state->tree).simple_declarations).data;
+
+ /* If it's marked [noscript], mark it as hidden in the typelib. */
+ gboolean hidden = (IDL_tree_property_get(ident, "noscript") != NULL);
+
+ if (!verify_attribute_declaration(state->tree))
+ return FALSE;
+
+ if (!XPT_InterfaceDescriptorAddMethods(ARENA(state), id,
+ (PRUint16) (read_only ? 1 : 2)))
+ return FALSE;
+
+ meth = &id->method_descriptors[NEXT_METH(state)];
+
+ return typelib_attr_accessor(state, meth, TRUE, hidden) &&
+ (read_only || typelib_attr_accessor(state, meth + 1, FALSE, hidden));
+}
+
+static gboolean
+typelib_op_dcl(TreeState *state)
+{
+ XPTInterfaceDescriptor *id = CURRENT(state);
+ XPTMethodDescriptor *meth;
+ struct _IDL_OP_DCL *op = &IDL_OP_DCL(state->tree);
+ IDL_tree iter;
+ uint16 num_args = 0;
+ uint8 op_flags = 0;
+ gboolean op_notxpcom = (IDL_tree_property_get(op->ident, "notxpcom")
+ != NULL);
+ gboolean op_noscript = (IDL_tree_property_get(op->ident, "noscript")
+ != NULL);
+
+ if (!verify_method_declaration(state->tree))
+ return FALSE;
+
+ if (!XPT_InterfaceDescriptorAddMethods(ARENA(state), id, 1))
+ return FALSE;
+
+ meth = &id->method_descriptors[NEXT_METH(state)];
+
+ for (iter = op->parameter_dcls; iter; iter = IDL_LIST(iter).next)
+ num_args++; /* count params */
+ if (op->op_type_spec && !op_notxpcom)
+ num_args++; /* fake param for _retval */
+
+ if (op_noscript)
+ op_flags |= XPT_MD_HIDDEN;
+ if (op_notxpcom)
+ op_flags |= XPT_MD_NOTXPCOM;
+
+ /* XXXshaver constructor? */
+
+#ifdef DEBUG_shaver_method
+ fprintf(stdout, "DBG: adding method %s (nargs %d)\n",
+ IDL_IDENT(op->ident).str, num_args);
+#endif
+ if (!XPT_FillMethodDescriptor(ARENA(state), meth, op_flags,
+ IDL_IDENT(op->ident).str,
+ (uint8) num_args))
+ return FALSE;
+
+ for (num_args = 0, iter = op->parameter_dcls; iter;
+ iter = IDL_LIST(iter).next, num_args++) {
+ XPTParamDescriptor *pd = &meth->params[num_args];
+ if (!fill_pd_from_param(state, pd, IDL_LIST(iter).data))
+ return FALSE;
+ }
+
+ /* stick retval param where we can see it later */
+ state->tree = op->op_type_spec;
+
+ /* XXX unless [notxpcom] */
+ if (!op_notxpcom) {
+ if (op->op_type_spec) {
+ uint8 pdflags = DIPPER_TYPE(op->op_type_spec) ?
+ (XPT_PD_RETVAL | XPT_PD_IN | XPT_PD_DIPPER) :
+ (XPT_PD_RETVAL | XPT_PD_OUT);
+
+ if (!fill_pd_from_type(state, &meth->params[num_args],
+ pdflags, op->op_type_spec))
+ return FALSE;
+ }
+
+ if (!fill_pd_as_nsresult(meth->result))
+ return FALSE;
+ } else {
+#ifdef DEBUG_shaver_notxpcom
+ fprintf(stderr, "%s is notxpcom\n", IDL_IDENT(op->ident).str);
+#endif
+ if (!fill_pd_from_type(state, meth->result, XPT_PD_RETVAL,
+ op->op_type_spec))
+ return FALSE;
+ }
+ NEXT_METH(state)++;
+ return TRUE;
+}
+
+static gboolean
+typelib_const_dcl(TreeState *state)
+{
+ struct _IDL_CONST_DCL *dcl = &IDL_CONST_DCL(state->tree);
+ const char *name = IDL_IDENT(dcl->ident).str;
+ gboolean is_long;
+ gboolean sign;
+ IDL_tree real_type;
+ XPTInterfaceDescriptor *id;
+ XPTConstDescriptor *cd;
+ IDL_longlong_t value;
+
+ if (!verify_const_declaration(state->tree))
+ return FALSE;
+
+ /* Could be a typedef; try to map it to the real type. */
+ real_type = find_underlying_type(dcl->const_type);
+ real_type = real_type ? real_type : dcl->const_type;
+ is_long = (IDL_TYPE_INTEGER(real_type).f_type == IDL_INTEGER_TYPE_LONG);
+
+ id = CURRENT(state);
+ if (!XPT_InterfaceDescriptorAddConsts(ARENA(state), id, 1))
+ return FALSE;
+ cd = &id->const_descriptors[NEXT_CONST(state)];
+
+ cd->name = IDL_IDENT(dcl->ident).str;
+#ifdef DEBUG_shaver_const
+ fprintf(stderr, "DBG: adding const %s\n", cd->name);
+#endif
+ if (!fill_td_from_type(state, &cd->type, dcl->const_type))
+ return FALSE;
+
+ value = IDL_INTEGER(dcl->const_exp).value;
+ sign = IDL_TYPE_INTEGER(dcl->const_type).f_signed;
+ if (is_long) {
+ if (sign)
+ cd->value.i32 = value;
+ else
+ cd->value.ui32 = value;
+ } else {
+ if (sign)
+ cd->value.i16 = value;
+ else
+ cd->value.ui16 = value;
+ }
+ NEXT_CONST(state)++;
+ return TRUE;
+}
+
+static gboolean
+typelib_enum(TreeState *state)
+{
+ XPIDL_WARNING((state->tree, IDL_WARNING1,
+ "enums not supported, enum \'%s\' ignored",
+ IDL_IDENT(IDL_TYPE_ENUM(state->tree).ident).str));
+ return TRUE;
+}
+
+backend *
+xpidl_typelib_dispatch(void)
+{
+ static backend result;
+ static nodeHandler table[IDLN_LAST];
+ static gboolean initialized = FALSE;
+
+ result.emit_prolog = typelib_prolog;
+ result.emit_epilog = typelib_epilog;
+
+ if (!initialized) {
+ /* Initialize non-NULL elements */
+ table[IDLN_LIST] = typelib_list;
+ table[IDLN_ATTR_DCL] = typelib_attr_dcl;
+ table[IDLN_OP_DCL] = typelib_op_dcl;
+ table[IDLN_INTERFACE] = typelib_interface;
+ table[IDLN_CONST_DCL] = typelib_const_dcl;
+ table[IDLN_TYPE_ENUM] = typelib_enum;
+ table[IDLN_NATIVE] = check_native;
+ initialized = TRUE;
+ }
+
+ result.dispatch_table = table;
+ return &result;
+}
+
+
+
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpidl/xpidl_util.c b/src/libs/xpcom18a4/xpcom/typelib/xpidl/xpidl_util.c
new file mode 100644
index 00000000..25d04212
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpidl/xpidl_util.c
@@ -0,0 +1,851 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: NPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Netscape 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/NPL/
+ *
+ * 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 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 NPL, 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 NPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * Utility functions called by various backends.
+ */
+
+#include "xpidl.h"
+
+/* XXXbe static */ char OOM[] = "ERROR: out of memory\n";
+
+void *
+xpidl_malloc(size_t nbytes)
+{
+ void *p = malloc(nbytes);
+ if (!p) {
+ fputs(OOM, stderr);
+ exit(1);
+ }
+ return p;
+}
+
+char *
+xpidl_strdup(const char *s)
+{
+#if defined(XP_MAC) || defined(XP_SOLARIS) /* bird: dunno why this is required, but whatever*/
+ size_t len = strlen(s);
+ char *ns = malloc(len + 1);
+ if (ns)
+ memcpy(ns, s, len + 1);
+#else
+ char *ns = strdup(s);
+#endif
+ if (!ns) {
+ fputs(OOM, stderr);
+ exit(1);
+ }
+ return ns;
+}
+
+void
+xpidl_write_comment(TreeState *state, int indent)
+{
+ fprintf(state->file, "%*s/* ", indent, "");
+ IDL_tree_to_IDL(state->tree, state->ns, state->file,
+ IDLF_OUTPUT_NO_NEWLINES |
+ IDLF_OUTPUT_NO_QUALIFY_IDENTS |
+ IDLF_OUTPUT_PROPERTIES);
+ fputs(" */\n", state->file);
+}
+
+/*
+ * Print an iid to into a supplied buffer; the buffer should be at least
+ * UUID_LENGTH bytes.
+ */
+gboolean
+xpidl_sprint_iid(nsID *id, char iidbuf[])
+{
+ int printed;
+
+ printed = sprintf(iidbuf,
+ "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ (PRUint32) id->m0, (PRUint32) id->m1,(PRUint32) id->m2,
+ (PRUint32) id->m3[0], (PRUint32) id->m3[1],
+ (PRUint32) id->m3[2], (PRUint32) id->m3[3],
+ (PRUint32) id->m3[4], (PRUint32) id->m3[5],
+ (PRUint32) id->m3[6], (PRUint32) id->m3[7]);
+
+#ifdef SPRINTF_RETURNS_STRING
+ return (printed && strlen((char *)printed) == 36);
+#else
+ return (printed == 36);
+#endif
+}
+
+/* We only parse the {}-less format. */
+static const char nsIDFmt2[] =
+ "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x";
+
+/*
+ * Parse a uuid string into an nsID struct. We cannot link against libxpcom,
+ * so we re-implement nsID::Parse here.
+ */
+gboolean
+xpidl_parse_iid(nsID *id, const char *str)
+{
+ PRInt32 count = 0;
+ PRInt32 n1, n2, n3[8];
+ PRInt32 n0, i;
+
+ XPT_ASSERT(str != NULL);
+
+ if (strlen(str) != 36) {
+ return FALSE;
+ }
+
+#ifdef DEBUG_shaver_iid
+ fprintf(stderr, "parsing iid %s\n", str);
+#endif
+
+ count = sscanf(str, nsIDFmt2,
+ &n0, &n1, &n2,
+ &n3[0],&n3[1],&n3[2],&n3[3],
+ &n3[4],&n3[5],&n3[6],&n3[7]);
+
+ id->m0 = (PRInt32) n0;
+ id->m1 = (PRInt16) n1;
+ id->m2 = (PRInt16) n2;
+ for (i = 0; i < 8; i++) {
+ id->m3[i] = (PRInt8) n3[i];
+ }
+
+#ifdef DEBUG_shaver_iid
+ if (count == 11) {
+ fprintf(stderr, "IID parsed to ");
+ print_IID(id, stderr);
+ fputs("\n", stderr);
+ }
+#endif
+ return (gboolean)(count == 11);
+}
+
+gboolean
+verify_const_declaration(IDL_tree const_tree) {
+ struct _IDL_CONST_DCL *dcl = &IDL_CONST_DCL(const_tree);
+ const char *name = IDL_IDENT(dcl->ident).str;
+ IDL_tree real_type;
+
+ /* const -> list -> interface */
+ if (!IDL_NODE_UP(IDL_NODE_UP(const_tree)) ||
+ IDL_NODE_TYPE(IDL_NODE_UP(IDL_NODE_UP(const_tree)))
+ != IDLN_INTERFACE) {
+ IDL_tree_error(const_tree,
+ "const declaration \'%s\' outside interface",
+ name);
+ return FALSE;
+ }
+
+ /* Could be a typedef; try to map it to the real type. */
+ real_type = find_underlying_type(dcl->const_type);
+ real_type = real_type ? real_type : dcl->const_type;
+ if (IDL_NODE_TYPE(real_type) == IDLN_TYPE_INTEGER &&
+ (IDL_TYPE_INTEGER(real_type).f_type == IDL_INTEGER_TYPE_SHORT ||
+ IDL_TYPE_INTEGER(real_type).f_type == IDL_INTEGER_TYPE_LONG))
+ {
+ if (!IDL_TYPE_INTEGER(real_type).f_signed &&
+ IDL_INTEGER(dcl->const_exp).value < 0)
+ {
+#ifndef G_HAVE_GINT64
+ /*
+ * For platforms without longlong support turned on we can get
+ * confused by the high bit of the long value and think that it
+ * represents a negative value in an unsigned declaration.
+ * In that case we don't know if it is the programmer who is
+ * confused or the compiler. So we issue a warning instead of
+ * an error.
+ */
+ if (IDL_TYPE_INTEGER(real_type).f_type == IDL_INTEGER_TYPE_LONG)
+ {
+ XPIDL_WARNING((const_tree, IDL_WARNING1,
+ "unsigned const declaration \'%s\' "
+ "initialized with (possibly) negative constant",
+ name));
+ return TRUE;
+ }
+#endif
+ IDL_tree_error(const_tree,
+ "unsigned const declaration \'%s\' initialized with "
+ "negative constant",
+ name);
+ return FALSE;
+ }
+ } else {
+ IDL_tree_error(const_tree,
+ "const declaration \'%s\' must be of type short or long",
+ name);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+
+/*
+ * This method consolidates error checking needed when coercing the XPIDL compiler
+ * via the -t flag to generate output for a specific version of XPConnect.
+ */
+static gboolean
+verify_type_fits_version(IDL_tree in_tree, IDL_tree error_tree)
+{
+ if (major_version == 1 && minor_version == 1)
+ {
+ /* XPIDL Version 1.1 checks */
+
+ /* utf8string, cstring, and astring types are not supported */
+ if (IDL_tree_property_get(in_tree, "utf8string") != NULL ||
+ IDL_tree_property_get(in_tree, "cstring") != NULL ||
+ IDL_tree_property_get(in_tree, "astring") != NULL)
+ {
+ IDL_tree_error(error_tree,
+ "Cannot use [utf8string], [cstring] and [astring] "
+ "types when generating version 1.1 typelibs\n");
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+gboolean
+verify_attribute_declaration(IDL_tree attr_tree)
+{
+ IDL_tree iface;
+ IDL_tree ident;
+ IDL_tree attr_type;
+ gboolean scriptable_interface;
+
+ /* We don't support attributes named IID, conflicts with static GetIID
+ * member. The conflict is due to certain compilers (VC++) choosing a
+ * different vtable order, placing GetIID at the beginning regardless
+ * of it's placement
+ */
+ if (strcmp(
+ IDL_IDENT(
+ IDL_LIST(IDL_ATTR_DCL(attr_tree).simple_declarations).data).str,
+ "IID") == 0) {
+ IDL_tree_error(attr_tree,
+ "Attributes named IID not supported, causes vtable "
+ "ordering problems");
+ return FALSE;
+ }
+ /*
+ * Verify that we've been called on an interface, and decide if the
+ * interface was marked [scriptable].
+ */
+ if (IDL_NODE_UP(attr_tree) && IDL_NODE_UP(IDL_NODE_UP(attr_tree)) &&
+ IDL_NODE_TYPE(iface = IDL_NODE_UP(IDL_NODE_UP(attr_tree)))
+ == IDLN_INTERFACE)
+ {
+ scriptable_interface =
+ (IDL_tree_property_get(IDL_INTERFACE(iface).ident, "scriptable")
+ != NULL);
+ } else {
+ IDL_tree_error(attr_tree,
+ "verify_attribute_declaration called on a non-interface?");
+ return FALSE;
+ }
+
+ /*
+ * Grab the first of the list of idents and hope that it'll
+ * say scriptable or no.
+ */
+ ident = IDL_LIST(IDL_ATTR_DCL(attr_tree).simple_declarations).data;
+
+ /*
+ * If the interface isn't scriptable, or the attribute is marked noscript,
+ * there's no need to check.
+ */
+ if (!scriptable_interface ||
+ IDL_tree_property_get(ident, "noscript") != NULL)
+ return TRUE;
+
+ /*
+ * If it should be scriptable, check that the type is non-native. nsid,
+ * domstring, utf8string, cstring, astring are exempted.
+ */
+ attr_type = IDL_ATTR_DCL(attr_tree).param_type_spec;
+
+ if (attr_type != NULL)
+ {
+ if (UP_IS_NATIVE(attr_type) &&
+ IDL_tree_property_get(attr_type, "nsid") == NULL &&
+ IDL_tree_property_get(attr_type, "domstring") == NULL &&
+ IDL_tree_property_get(attr_type, "utf8string") == NULL &&
+ IDL_tree_property_get(attr_type, "cstring") == NULL &&
+ IDL_tree_property_get(attr_type, "astring") == NULL)
+ {
+ IDL_tree_error(attr_tree,
+ "attributes in [scriptable] interfaces that are "
+ "non-scriptable because they refer to native "
+ "types must be marked [noscript]\n");
+ return FALSE;
+ }
+ /*
+ * We currently don't support properties of type nsid that aren't
+ * pointers or references, unless they are marked [notxpcom} and
+ * must be read-only
+ */
+
+ if ((IDL_tree_property_get(ident, "notxpcom") == NULL || !(IDL_ATTR_DCL(attr_tree).f_readonly)) &&
+ IDL_tree_property_get(attr_type,"nsid") != NULL &&
+ IDL_tree_property_get(attr_type,"ptr") == NULL &&
+ IDL_tree_property_get(attr_type,"ref") == NULL)
+ {
+ IDL_tree_error(attr_tree,
+ "Feature not currently supported: "
+ "attributes with a type of nsid must be marked "
+ "either [ptr] or [ref], or "
+ "else must be marked [notxpcom] "
+ "and must be read-only\n");
+ return FALSE;
+ }
+
+ /*
+ * Run additional error checks on the attribute type if targetting an
+ * older version of XPConnect.
+ */
+
+ if (!verify_type_fits_version(attr_type, attr_tree))
+ return FALSE;
+ }
+
+ if (IDL_LIST(IDL_ATTR_DCL(attr_tree).simple_declarations).next != NULL)
+ {
+ IDL_tree_error(attr_tree,
+ "multiple attributes in a single declaration is not supported\n");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*
+ * Find the underlying type of an identifier typedef.
+ *
+ * All the needed tree-walking seems pretty shaky; isn't there something in
+ * libIDL to automate this?
+ */
+IDL_tree /* IDL_TYPE_DCL */
+find_underlying_type(IDL_tree typedef_ident)
+{
+ IDL_tree up;
+
+ if (typedef_ident == NULL || IDL_NODE_TYPE(typedef_ident) != IDLN_IDENT)
+ return NULL;
+
+ up = IDL_NODE_UP(typedef_ident);
+ if (up == NULL || IDL_NODE_TYPE(up) != IDLN_LIST)
+ return NULL;
+ up = IDL_NODE_UP(up);
+ if (up == NULL || IDL_NODE_TYPE(up) != IDLN_TYPE_DCL)
+ return NULL;
+
+ return IDL_TYPE_DCL(up).type_spec;
+}
+
+static IDL_tree /* IDL_PARAM_DCL */
+find_named_parameter(IDL_tree method_tree, const char *param_name)
+{
+ IDL_tree iter;
+ for (iter = IDL_OP_DCL(method_tree).parameter_dcls; iter;
+ iter = IDL_LIST(iter).next)
+ {
+ IDL_tree param = IDL_LIST(iter).data;
+ IDL_tree simple_decl = IDL_PARAM_DCL(param).simple_declarator;
+ const char *current_name = IDL_IDENT(simple_decl).str;
+ if (strcmp(current_name, param_name) == 0)
+ return param;
+ }
+ return NULL;
+}
+
+typedef enum ParamAttrType {
+ IID_IS,
+ LENGTH_IS,
+ SIZE_IS
+} ParamAttrType;
+
+/*
+ * Check that parameters referred to by attributes such as size_is exist and
+ * refer to parameters of the appropriate type.
+ */
+static gboolean
+check_param_attribute(IDL_tree method_tree, IDL_tree param,
+ ParamAttrType whattocheck)
+{
+ const char *method_name = IDL_IDENT(IDL_OP_DCL(method_tree).ident).str;
+ const char *referred_name = NULL;
+ IDL_tree param_type = IDL_PARAM_DCL(param).param_type_spec;
+ IDL_tree simple_decl = IDL_PARAM_DCL(param).simple_declarator;
+ const char *param_name = IDL_IDENT(simple_decl).str;
+ const char *attr_name;
+ const char *needed_type;
+
+ if (whattocheck == IID_IS) {
+ attr_name = "iid_is";
+ needed_type = "IID";
+ } else if (whattocheck == LENGTH_IS) {
+ attr_name = "length_is";
+ needed_type = "unsigned long (or PRUint32)";
+ } else if (whattocheck == SIZE_IS) {
+ attr_name = "size_is";
+ needed_type = "unsigned long (or PRUint32)";
+ } else {
+ XPT_ASSERT("asked to check an unknown attribute type!");
+ return TRUE;
+ }
+
+ referred_name = IDL_tree_property_get(simple_decl, attr_name);
+ if (referred_name != NULL) {
+ IDL_tree referred_param = find_named_parameter(method_tree,
+ referred_name);
+ IDL_tree referred_param_type;
+ if (referred_param == NULL) {
+ IDL_tree_error(method_tree,
+ "attribute [%s(%s)] refers to missing "
+ "parameter \"%s\"",
+ attr_name, referred_name, referred_name);
+ return FALSE;
+ }
+ if (referred_param == param) {
+ IDL_tree_error(method_tree,
+ "attribute [%s(%s)] refers to it's own parameter",
+ attr_name, referred_name);
+ return FALSE;
+ }
+
+ referred_param_type = IDL_PARAM_DCL(referred_param).param_type_spec;
+ if (whattocheck == IID_IS) {
+ /* require IID type */
+ if (IDL_tree_property_get(referred_param_type, "nsid") == NULL) {
+ IDL_tree_error(method_tree,
+ "target \"%s\" of [%s(%s)] attribute "
+ "must be of %s type",
+ referred_name, attr_name, referred_name,
+ needed_type);
+ return FALSE;
+ }
+ } else if (whattocheck == LENGTH_IS || whattocheck == SIZE_IS) {
+ /* require PRUint32 type */
+ IDL_tree real_type;
+
+ /* Could be a typedef; try to map it to the real type. */
+ real_type = find_underlying_type(referred_param_type);
+ real_type = real_type ? real_type : referred_param_type;
+
+ if (IDL_NODE_TYPE(real_type) != IDLN_TYPE_INTEGER ||
+ IDL_TYPE_INTEGER(real_type).f_signed != FALSE ||
+ IDL_TYPE_INTEGER(real_type).f_type != IDL_INTEGER_TYPE_LONG)
+ {
+ IDL_tree_error(method_tree,
+ "target \"%s\" of [%s(%s)] attribute "
+ "must be of %s type",
+ referred_name, attr_name, referred_name,
+ needed_type);
+
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * Common method verification code, called by *op_dcl in the various backends.
+ */
+gboolean
+verify_method_declaration(IDL_tree method_tree)
+{
+ struct _IDL_OP_DCL *op = &IDL_OP_DCL(method_tree);
+ IDL_tree iface;
+ IDL_tree iter;
+ gboolean notxpcom;
+ gboolean scriptable_interface;
+ gboolean scriptable_method;
+ gboolean seen_retval = FALSE;
+ const char *method_name = IDL_IDENT(IDL_OP_DCL(method_tree).ident).str;
+
+ /* We don't support attributes named IID, conflicts with static GetIID
+ * member. The conflict is due to certain compilers (VC++) choosing a
+ * different vtable order, placing GetIID at the beginning regardless
+ * of it's placement
+ */
+ if (strcmp(method_name, "GetIID") == 0) {
+ IDL_tree_error(method_tree,
+ "Methods named GetIID not supported, causes vtable "
+ "ordering problems");
+ return FALSE;
+ }
+ if (op->f_varargs) {
+ /* We don't currently support varargs. */
+ IDL_tree_error(method_tree, "varargs are not currently supported");
+ return FALSE;
+ }
+
+ /*
+ * Verify that we've been called on an interface, and decide if the
+ * interface was marked [scriptable].
+ */
+ if (IDL_NODE_UP(method_tree) && IDL_NODE_UP(IDL_NODE_UP(method_tree)) &&
+ IDL_NODE_TYPE(iface = IDL_NODE_UP(IDL_NODE_UP(method_tree)))
+ == IDLN_INTERFACE)
+ {
+ scriptable_interface =
+ (IDL_tree_property_get(IDL_INTERFACE(iface).ident, "scriptable")
+ != NULL);
+ } else {
+ IDL_tree_error(method_tree,
+ "verify_method_declaration called on a non-interface?");
+ return FALSE;
+ }
+
+ /*
+ * Require that any method in an interface marked as [scriptable], that
+ * *isn't* scriptable because it refers to some native type, be marked
+ * [noscript] or [notxpcom].
+ *
+ * Also check that iid_is points to nsid, and length_is, size_is points
+ * to unsigned long.
+ */
+ notxpcom = IDL_tree_property_get(op->ident, "notxpcom") != NULL;
+
+ scriptable_method = scriptable_interface &&
+ !notxpcom &&
+ IDL_tree_property_get(op->ident, "noscript") == NULL;
+
+ /* Loop through the parameters and check. */
+ for (iter = op->parameter_dcls; iter; iter = IDL_LIST(iter).next) {
+ IDL_tree param = IDL_LIST(iter).data;
+ IDL_tree param_type =
+ IDL_PARAM_DCL(param).param_type_spec;
+ IDL_tree simple_decl =
+ IDL_PARAM_DCL(param).simple_declarator;
+ const char *param_name = IDL_IDENT(simple_decl).str;
+
+ /*
+ * Reject this method if it should be scriptable and some parameter is
+ * native that isn't marked with either nsid, domstring, utf8string,
+ * cstring, astring or iid_is.
+ */
+ if (scriptable_method &&
+ UP_IS_NATIVE(param_type) &&
+ IDL_tree_property_get(param_type, "nsid") == NULL &&
+ IDL_tree_property_get(simple_decl, "iid_is") == NULL &&
+ IDL_tree_property_get(param_type, "domstring") == NULL &&
+ IDL_tree_property_get(param_type, "utf8string") == NULL &&
+ IDL_tree_property_get(param_type, "cstring") == NULL &&
+ IDL_tree_property_get(param_type, "astring") == NULL)
+ {
+ IDL_tree_error(method_tree,
+ "methods in [scriptable] interfaces that are "
+ "non-scriptable because they refer to native "
+ "types (parameter \"%s\") must be marked "
+ "[noscript]", param_name);
+ return FALSE;
+ }
+
+ /*
+ * nsid's parameters that aren't ptr's or ref's are not currently
+ * supported in xpcom or non-xpcom (marked with [notxpcom]) methods
+ * as input parameters
+ */
+ if (!(notxpcom && IDL_PARAM_DCL(param).attr != IDL_PARAM_IN) &&
+ IDL_tree_property_get(param_type, "nsid") != NULL &&
+ IDL_tree_property_get(param_type, "ptr") == NULL &&
+ IDL_tree_property_get(param_type, "ref") == NULL)
+ {
+ IDL_tree_error(method_tree,
+ "Feature currently not supported: "
+ "parameter \"%s\" is of type nsid and "
+ "must be marked either [ptr] or [ref] "
+ "or method \"%s\" must be marked [notxpcom] "
+ "and must not be an input parameter",
+ param_name,
+ method_name);
+ return FALSE;
+ }
+ /*
+ * Sanity checks on return values.
+ */
+ if (IDL_tree_property_get(simple_decl, "retval") != NULL) {
+ if (IDL_LIST(iter).next != NULL) {
+ IDL_tree_error(method_tree,
+ "only the last parameter can be marked [retval]");
+ return FALSE;
+ }
+ if (op->op_type_spec) {
+ IDL_tree_error(method_tree,
+ "can't have [retval] with non-void return type");
+ return FALSE;
+ }
+ /* In case XPConnect relaxes the retval-is-last restriction. */
+ if (seen_retval) {
+ IDL_tree_error(method_tree,
+ "can't have more than one [retval] parameter");
+ return FALSE;
+ }
+ seen_retval = TRUE;
+ }
+
+ /*
+ * Confirm that [shared] attributes are only used with string, wstring,
+ * or native (but not nsid, domstring, utf8string, cstring or astring)
+ * and can't be used with [array].
+ */
+ if (IDL_tree_property_get(simple_decl, "shared") != NULL) {
+ IDL_tree real_type;
+ real_type = find_underlying_type(param_type);
+ real_type = real_type ? real_type : param_type;
+
+ if (IDL_tree_property_get(simple_decl, "array") != NULL) {
+ IDL_tree_error(method_tree,
+ "[shared] parameter \"%s\" cannot "
+ "be of array type", param_name);
+ return FALSE;
+ }
+
+ if (!(IDL_NODE_TYPE(real_type) == IDLN_TYPE_STRING ||
+ IDL_NODE_TYPE(real_type) == IDLN_TYPE_WIDE_STRING ||
+ (UP_IS_NATIVE(real_type) &&
+ !IDL_tree_property_get(real_type, "nsid") &&
+ !IDL_tree_property_get(real_type, "domstring") &&
+ !IDL_tree_property_get(real_type, "utf8string") &&
+ !IDL_tree_property_get(real_type, "cstring") &&
+ !IDL_tree_property_get(real_type, "astring"))))
+ {
+ IDL_tree_error(method_tree,
+ "[shared] parameter \"%s\" must be of type "
+ "string, wstring or native", param_name);
+ return FALSE;
+ }
+ }
+
+ /*
+ * inout is not allowed with "domstring", "UTF8String", "CString"
+ * and "AString" types
+ */
+ if (IDL_PARAM_DCL(param).attr == IDL_PARAM_INOUT &&
+ UP_IS_NATIVE(param_type) &&
+ (IDL_tree_property_get(param_type, "domstring") != NULL ||
+ IDL_tree_property_get(param_type, "utf8string") != NULL ||
+ IDL_tree_property_get(param_type, "cstring") != NULL ||
+ IDL_tree_property_get(param_type, "astring") != NULL )) {
+ IDL_tree_error(method_tree,
+ "[domstring], [utf8string], [cstring], [astring] "
+ "types cannot be used as inout parameters");
+ return FALSE;
+ }
+
+
+ /*
+ * arrays of domstring, utf8string, cstring, astring types not allowed
+ */
+ if (IDL_tree_property_get(simple_decl, "array") != NULL &&
+ UP_IS_NATIVE(param_type) &&
+ (IDL_tree_property_get(param_type, "domstring") != NULL ||
+ IDL_tree_property_get(param_type, "utf8string") != NULL ||
+ IDL_tree_property_get(param_type, "cstring") != NULL ||
+ IDL_tree_property_get(param_type, "astring") != NULL)) {
+ IDL_tree_error(method_tree,
+ "[domstring], [utf8string], [cstring], [astring] "
+ "types cannot be used in array parameters");
+ return FALSE;
+ }
+
+ if (!check_param_attribute(method_tree, param, IID_IS) ||
+ !check_param_attribute(method_tree, param, LENGTH_IS) ||
+ !check_param_attribute(method_tree, param, SIZE_IS))
+ return FALSE;
+
+ /*
+ * Run additional error checks on the parameter type if targetting an
+ * older version of XPConnect.
+ */
+
+ if (!verify_type_fits_version(param_type, method_tree))
+ return FALSE;
+
+ }
+
+ /* XXX q: can return type be nsid? */
+ /* Native return type? */
+ if (scriptable_method &&
+ op->op_type_spec != NULL && UP_IS_NATIVE(op->op_type_spec) &&
+ IDL_tree_property_get(op->op_type_spec, "nsid") == NULL &&
+ IDL_tree_property_get(op->op_type_spec, "domstring") == NULL &&
+ IDL_tree_property_get(op->op_type_spec, "utf8string") == NULL &&
+ IDL_tree_property_get(op->op_type_spec, "cstring") == NULL &&
+ IDL_tree_property_get(op->op_type_spec, "astring") == NULL)
+ {
+ IDL_tree_error(method_tree,
+ "methods in [scriptable] interfaces that are "
+ "non-scriptable because they return native "
+ "types must be marked [noscript]");
+ return FALSE;
+ }
+
+
+ /*
+ * nsid's parameters that aren't ptr's or ref's are not currently
+ * supported in xpcom
+ */
+ if (!notxpcom &&
+ op->op_type_spec != NULL &&
+ IDL_tree_property_get(op->op_type_spec, "nsid") != NULL &&
+ IDL_tree_property_get(op->op_type_spec, "ptr") == NULL &&
+ IDL_tree_property_get(op->op_type_spec, "ref") == NULL)
+ {
+ IDL_tree_error(method_tree,
+ "Feature currently not supported: "
+ "return value is of type nsid and "
+ "must be marked either [ptr] or [ref], "
+ "or else method \"%s\" must be marked [notxpcom] ",
+ method_name);
+ return FALSE;
+ }
+
+ /*
+ * Run additional error checks on the return type if targetting an
+ * older version of XPConnect.
+ */
+
+ if (op->op_type_spec != NULL &&
+ !verify_type_fits_version(op->op_type_spec, method_tree))
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*
+ * Verify that a native declaration has an associated C++ expression, i.e. that
+ * it's of the form native <idl-name>(<c++-name>)
+ */
+gboolean
+check_native(TreeState *state)
+{
+ char *native_name;
+ /* require that native declarations give a native type */
+ if (IDL_NATIVE(state->tree).user_type)
+ return TRUE;
+ native_name = IDL_IDENT(IDL_NATIVE(state->tree).ident).str;
+ IDL_tree_error(state->tree,
+ "``native %s;'' needs C++ type: ``native %s(<C++ type>);''",
+ native_name, native_name);
+ return FALSE;
+}
+
+/*
+ * Print a GSList as char strings to a file.
+ */
+void
+printlist(FILE *outfile, GSList *slist)
+{
+ guint i;
+ guint len = g_slist_length(slist);
+
+ for(i = 0; i < len; i++) {
+ fprintf(outfile,
+ "%s\n", (char *)g_slist_nth_data(slist, i));
+ }
+}
+
+void
+xpidl_list_foreach(IDL_tree p, IDL_tree_func foreach, gpointer user_data)
+{
+ IDL_tree_func_data tfd;
+
+ while (p) {
+ struct _IDL_LIST *list = &IDL_LIST(p);
+ tfd.tree = list->data;
+ if (!foreach(&tfd, user_data))
+ return;
+ p = list->next;
+ }
+}
+
+/*
+ * Verify that the interface declaration is correct
+ */
+gboolean
+verify_interface_declaration(IDL_tree interface_tree)
+{
+ IDL_tree iter;
+ /*
+ * If we have the scriptable attribute then make sure all of our direct
+ * parents have it as well.
+ * NOTE: We don't recurse since all interfaces will fall through here
+ */
+ if (IDL_tree_property_get(IDL_INTERFACE(interface_tree).ident,
+ "scriptable")) {
+ for (iter = IDL_INTERFACE(interface_tree).inheritance_spec; iter;
+ iter = IDL_LIST(iter).next) {
+ if (IDL_tree_property_get(
+ IDL_INTERFACE(iter).ident, "scriptable") == 0) {
+ XPIDL_WARNING((interface_tree,IDL_WARNING1,
+ "%s is scriptable but inherits from the non-scriptable interface %s\n",
+ IDL_IDENT(IDL_INTERFACE(interface_tree).ident).str,
+ IDL_IDENT(IDL_INTERFACE(iter).ident).str));
+ }
+ }
+ }
+ return TRUE;
+}
+
+/*
+ * Return a pointer to the start of the base filename of path
+ */
+char *
+xpidl_basename(const char * path)
+{
+ char * result = g_path_get_basename(path);
+ /*
+ *If this is windows then we'll handle either / or \ as a separator
+ * g_basename only handles \ for windows
+ */
+#if defined(XP_WIN32)
+# error adapt regarding g_basename() vs. g_path_get_basename()!
+ const char * slash = strrchr(path, '/');
+ /* If we found a slash and its after the current default OS separator */
+ if (slash != NULL && (slash > result))
+ result = slash + 1;
+#endif
+ return result;
+}
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpt/.cvsignore b/src/libs/xpcom18a4/xpcom/typelib/xpt/.cvsignore
new file mode 100644
index 00000000..f3c7a7c5
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpt/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpt/Makefile.in b/src/libs/xpcom18a4/xpcom/typelib/xpt/Makefile.in
new file mode 100644
index 00000000..1447128f
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpt/Makefile.in
@@ -0,0 +1,50 @@
+#
+# ***** 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
+
+DIRS = public src tools
+
+include $(topsrcdir)/config/rules.mk
+
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpt/public/.cvsignore b/src/libs/xpcom18a4/xpcom/typelib/xpt/public/.cvsignore
new file mode 100644
index 00000000..f3c7a7c5
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpt/public/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpt/public/Makefile.in b/src/libs/xpcom18a4/xpcom/typelib/xpt/public/Makefile.in
new file mode 100644
index 00000000..3e452486
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpt/public/Makefile.in
@@ -0,0 +1,51 @@
+#
+# ***** 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
+
+EXPORTS = xpt_arena.h xpt_struct.h xpt_xdr.h
+EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))
+
+include $(topsrcdir)/config/rules.mk
+
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpt/public/xpt_arena.h b/src/libs/xpcom18a4/xpcom/typelib/xpt/public/xpt_arena.h
new file mode 100644
index 00000000..2b277467
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpt/public/xpt_arena.h
@@ -0,0 +1,145 @@
+/* -*- Mode: C; tab-width: 4; 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 ***** */
+
+/*
+ * Simple arena allocator for xpt (which avoids using NSPR).
+ */
+
+#ifndef __xpt_arena_h__
+#define __xpt_arena_h__
+
+#include "prtypes.h"
+#include <stdlib.h>
+
+#ifdef VBOX_WITH_XPCOM_NAMESPACE_CLEANUP
+#define XPT_NewArena VBoxNsxpXPT_NewArena
+#define XPT_ArenaMalloc VBoxNsxpXPT_ArenaMalloc
+#define XPT_DestroyArena VBoxNsxpXPT_DestroyArena
+#define XPT_ArenaFree VBoxNsxpXPT_ArenaFree
+#define XPT_DestroyArena VBoxNsxpXPT_DestroyArena
+#define XPT_DumpStats VBoxNsxpXPT_DumpStats
+#define XPT_NotifyDoneLoading VBoxNsxpXPT_NotifyDoneLoading
+#define XPT_ArenaStrDup VBoxNsxpXPT_ArenaStrDup
+#define XPT_AssertFailed VBoxNsxpXPT_AssertFailed
+#endif /* VBOX_WITH_XPCOM_NAMESPACE_CLEANUP */
+
+/*
+ * The linkage of XPT API functions differs depending on whether the file is
+ * used within the XPT library or not. Any source file within the XPT
+ * library should define EXPORT_XPT_API whereas any client of the library
+ * should not.
+ */
+#ifdef EXPORT_XPT_API
+#define XPT_PUBLIC_API(t) PR_IMPLEMENT(t)
+#define XPT_PUBLIC_DATA(t) PR_IMPLEMENT_DATA(t)
+#else
+#ifdef _WIN32
+# define XPT_PUBLIC_API(t) __declspec(dllimport) t
+# define XPT_PUBLIC_DATA(t) __declspec(dllimport) t
+#else
+# define XPT_PUBLIC_API(t) PR_IMPLEMENT(t)
+# define XPT_PUBLIC_DATA(t) t
+#endif
+#endif
+#define XPT_FRIEND_API(t) XPT_PUBLIC_API(t)
+#define XPT_FRIEND_DATA(t) XPT_PUBLIC_DATA(t)
+
+PR_BEGIN_EXTERN_C
+
+/*
+ * Simple Arena support. Use with caution!
+ */
+
+typedef struct XPTArena XPTArena;
+
+XPT_PUBLIC_API(XPTArena *)
+XPT_NewArena(PRUint32 block_size, size_t alignment, const char* name);
+
+XPT_PUBLIC_API(void)
+XPT_DestroyArena(XPTArena *arena);
+
+XPT_PUBLIC_API(void)
+XPT_DumpStats(XPTArena *arena);
+
+XPT_PUBLIC_API(void *)
+XPT_ArenaMalloc(XPTArena *arena, size_t size);
+
+XPT_PUBLIC_API(char *)
+XPT_ArenaStrDup(XPTArena *arena, const char * s);
+
+XPT_PUBLIC_API(void)
+XPT_NotifyDoneLoading(XPTArena *arena);
+
+XPT_PUBLIC_API(void)
+XPT_ArenaFree(XPTArena *arena, void* block);
+
+/* --------------------------------------------------------- */
+
+#define XPT_MALLOC(_arena, _bytes) \
+ XPT_ArenaMalloc((_arena), (_bytes))
+
+#ifdef DEBUG
+#define XPT_FREE(_arena, _ptr) \
+ XPT_ArenaFree((_arena), (_ptr))
+#else
+#define XPT_FREE(_arena, _ptr) \
+ ((void)0)
+#endif
+
+#define XPT_STRDUP(_arena, _s) \
+ XPT_ArenaStrDup((_arena), (_s))
+
+#define XPT_CALLOC(_arena, _size) XPT_MALLOC((_arena), (_size))
+#define XPT_NEW(_arena, _struct) ((_struct *) XPT_MALLOC((_arena), sizeof(_struct)))
+#define XPT_NEWZAP(_arena, _struct) XPT_NEW((_arena), _struct)
+#define XPT_DELETE(_arena, _ptr) do{XPT_FREE((_arena), (_ptr)); ((_ptr)) = NULL;}while(0)
+#define XPT_FREEIF(_arena, _ptr) do{if ((_ptr)) XPT_FREE((_arena), (_ptr));}while(0)
+
+/* --------------------------------------------------------- */
+
+#ifdef DEBUG
+XPT_PUBLIC_API(void)
+XPT_AssertFailed(const char *s, const char *file, PRUint32 lineno);
+#define XPT_ASSERT(_expr) \
+ ((_expr)?((void)0):XPT_AssertFailed(# _expr, __FILE__, __LINE__))
+#else
+#define XPT_ASSERT(_expr) ((void)0)
+#endif
+
+PR_END_EXTERN_C
+
+#endif /* __xpt_arena_h__ */
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpt/public/xpt_struct.h b/src/libs/xpcom18a4/xpcom/typelib/xpt/public/xpt_struct.h
new file mode 100644
index 00000000..c7f36f2d
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpt/public/xpt_struct.h
@@ -0,0 +1,562 @@
+/* -*- Mode: C; tab-width: 4; 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 ***** */
+
+/*
+ * Structures matching the in-memory representation of typelib structures.
+ * http://www.mozilla.org/scriptable/typelib_file.html
+ */
+
+#ifndef __xpt_struct_h__
+#define __xpt_struct_h__
+
+#include "xpt_arena.h"
+
+#ifdef VBOX_WITH_XPCOM_NAMESPACE_CLEANUP
+#define XPT_NewHeader VBoxNsxpXPT_NewHeader
+#define XPT_NewStringZ VBoxNsxpXPT_NewStringZ
+#define XPT_NewAnnotation VBoxNsxpXPT_NewAnnotation
+#define XPT_SizeOfHeaderBlock VBoxNsxpXPT_SizeOfHeaderBlock
+#define XPT_NewInterfaceDescriptor VBoxNsxpXPT_NewInterfaceDescriptor
+#define XPT_FillInterfaceDirectoryEntry VBoxNsxpXPT_FillInterfaceDirectoryEntry
+#define XPT_FillMethodDescriptor VBoxNsxpXPT_FillMethodDescriptor
+#define XPT_FreeHeader VBoxNsxpXPT_FreeHeader
+#define XPT_ParseVersionString VBoxNsxpXPT_ParseVersionString
+#define XPT_DestroyInterfaceDirectoryEntry VBoxNsxpXPT_DestroyInterfaceDirectoryEntry
+#define XPT_FillParamDescriptor VBoxNsxpXPT_FillParamDescriptor
+#define XPT_FreeInterfaceDescriptor VBoxNsxpXPT_FreeInterfaceDescriptor
+#define XPT_InterfaceDescriptorAddConsts VBoxNsxpXPT_InterfaceDescriptorAddConsts
+#define XPT_InterfaceDescriptorAddMethods VBoxNsxpXPT_InterfaceDescriptorAddMethods
+#define XPT_InterfaceDescriptorAddTypes VBoxNsxpXPT_InterfaceDescriptorAddTypes
+#define XPT_GetInterfaceIndexByName VBoxNsxpXPT_GetInterfaceIndexByName
+#define XPT_NewString VBoxNsxpXPT_NewString
+#define XPT_SizeOfHeader VBoxNsxpXPT_SizeOfHeader
+#endif /* VBOX_WITH_XPCOM_NAMESPACE_CLEANUP */
+
+PR_BEGIN_EXTERN_C
+
+/*
+ * Originally, I was going to have structures that exactly matched the on-disk
+ * representation, but that proved difficult: different compilers can pack
+ * their structs differently, and that makes overlaying them atop a
+ * read-from-disk byte buffer troublesome. So now I just have some structures
+ * that are used in memory, and we're going to write a nice XDR library to
+ * write them to disk and stuff. It is pure joy. -- shaver
+ */
+
+/* Structures for the typelib components */
+
+typedef struct XPTHeader XPTHeader;
+typedef struct XPTInterfaceDirectoryEntry XPTInterfaceDirectoryEntry;
+typedef struct XPTInterfaceDescriptor XPTInterfaceDescriptor;
+typedef struct XPTConstDescriptor XPTConstDescriptor;
+typedef struct XPTMethodDescriptor XPTMethodDescriptor;
+typedef struct XPTParamDescriptor XPTParamDescriptor;
+typedef struct XPTTypeDescriptor XPTTypeDescriptor;
+typedef struct XPTTypeDescriptorPrefix XPTTypeDescriptorPrefix;
+typedef struct XPTString XPTString;
+typedef struct XPTAnnotation XPTAnnotation;
+#ifndef nsID_h__
+/*
+ * We can't include nsID.h, because it's full of C++ goop and we're not doing
+ * C++ here, so we define our own minimal struct. We protect against multiple
+ * definitions of this struct, though, and use the same field naming.
+ */
+struct nsID {
+ PRUint32 m0;
+ PRUint16 m1;
+ PRUint16 m2;
+ PRUint8 m3[8];
+};
+
+typedef struct nsID nsID;
+#endif
+
+#define XPT_COPY_IID(to, from) \
+ (to).m0 = (from).m0; \
+ (to).m1 = (from).m1; \
+ (to).m2 = (from).m2; \
+ (to).m3[0] = (from).m3[0]; \
+ (to).m3[1] = (from).m3[1]; \
+ (to).m3[2] = (from).m3[2]; \
+ (to).m3[3] = (from).m3[3]; \
+ (to).m3[4] = (from).m3[4]; \
+ (to).m3[5] = (from).m3[5]; \
+ (to).m3[6] = (from).m3[6]; \
+ (to).m3[7] = (from).m3[7];
+
+
+/*
+ * Every XPCOM typelib file begins with a header.
+ */
+struct XPTHeader {
+ PRUint8 magic[16];
+ PRUint8 major_version;
+ PRUint8 minor_version;
+ PRUint16 num_interfaces;
+ PRUint32 file_length;
+ XPTInterfaceDirectoryEntry *interface_directory;
+ PRUint32 data_pool;
+ XPTAnnotation *annotations;
+};
+
+#define XPT_MAGIC "XPCOM\nTypeLib\r\n\032"
+/* For error messages. */
+#define XPT_MAGIC_STRING "XPCOM\\nTypeLib\\r\\n\\032"
+#define XPT_MAJOR_VERSION 0x01
+#define XPT_MINOR_VERSION 0x02
+
+/* Any file with a major version number of XPT_MAJOR_INCOMPATIBLE_VERSION
+ * or higher is to be considered incompatible by this version of xpt and
+ * we will refuse to read it. We will return a header with magic, major and
+ * minor versions set from the file. num_interfaces and file_length will be
+ * set to zero to confirm our inability to read the file; i.e. even if some
+ * client of this library gets out of sync with us regarding the agreed upon
+ * value for XPT_MAJOR_INCOMPATIBLE_VERSION, anytime num_interfaces and
+ * file_length are both zero we *know* that this library refused to read the
+ * file due to version imcompatibility.
+ */
+#define XPT_MAJOR_INCOMPATIBLE_VERSION 0x02
+
+/*
+ * The "[-t version number]" cmd line parameter to the XPIDL compiler and XPT
+ * linker specifies the major and minor version number of the output
+ * type library.
+ *
+ * The goal is for the compiler to check that the input IDL file only uses
+ * constructs that are supported in the version specified. The linker will
+ * check that all typelib files it reads are of the version specified or
+ * below.
+ *
+ * Both the compiler and the linker will report errors and abort if these
+ * checks fail.
+ *
+ * When you rev up major or minor versions of the type library in the future,
+ * think about the new stuff that you added to the type library and add checks
+ * to make sure that occurrences of that new "stuff" will get caught when [-t
+ * version number] is used with the compiler. Here's what you'll probably
+ * have to do each time you rev up major/minor versions:
+ *
+ * 1) Add the current version number string (before your change) to the
+ * XPT_TYPELIB_VERSIONS list.
+ *
+ * 2) Do your changes add new features to XPIDL? Ensure that those new
+ * features are rejected by the XPIDL compiler when any version number in
+ * the XPT_TYPELIB_VERSIONS list is specified on the command line. The
+ * one place that currently does this kind of error checking is the function
+ * verify_type_fits_version() in xpidl_util.c. It currently checks
+ * attribute types, parameter types, and return types. You'll probably have
+ * to add to it or generalize it further based on what kind of changes you
+ * are making.
+ *
+ * 3) You will probably NOT need to make any changes to the error checking
+ * in the linker.
+ */
+
+#define XPT_VERSION_UNKNOWN 0
+#define XPT_VERSION_UNSUPPORTED 1
+#define XPT_VERSION_OLD 2
+#define XPT_VERSION_CURRENT 3
+
+typedef struct {
+ const char* str;
+ PRUint8 major;
+ PRUint8 minor;
+ PRUint16 code;
+} XPT_TYPELIB_VERSIONS_STRUCT;
+
+/* Currently accepted list of versions for typelibs */
+#define XPT_TYPELIB_VERSIONS { \
+ {"1.0", 1, 0, XPT_VERSION_UNSUPPORTED}, \
+ {"1.1", 1, 1, XPT_VERSION_OLD}, \
+ {"1.2", 1, 2, XPT_VERSION_CURRENT} \
+}
+
+extern XPT_PUBLIC_API(PRUint16)
+XPT_ParseVersionString(const char* str, PRUint8* major, PRUint8* minor);
+
+extern XPT_PUBLIC_API(XPTHeader *)
+XPT_NewHeader(XPTArena *arena, PRUint16 num_interfaces,
+ PRUint8 major_version, PRUint8 minor_version);
+
+extern XPT_PUBLIC_API(void)
+XPT_FreeHeader(XPTArena *arena, XPTHeader* aHeader);
+
+/* size of header and annotations */
+extern XPT_PUBLIC_API(PRUint32)
+XPT_SizeOfHeader(XPTHeader *header);
+
+/* size of header and annotations and InterfaceDirectoryEntries */
+extern XPT_PUBLIC_API(PRUint32)
+XPT_SizeOfHeaderBlock(XPTHeader *header);
+
+/*
+ * A contiguous array of fixed-size InterfaceDirectoryEntry records begins at
+ * the byte offset identified by the interface_directory field in the file
+ * header. The array is used to quickly locate an interface description
+ * using its IID. No interface should appear more than once in the array.
+ */
+struct XPTInterfaceDirectoryEntry {
+ nsID iid;
+ char *name;
+ char *name_space;
+ XPTInterfaceDescriptor *interface_descriptor;
+
+#if 0 /* not yet */
+ /* not stored on disk */
+ PRUint32 offset; /* the offset for an ID still to be read */
+#endif
+};
+
+extern XPT_PUBLIC_API(PRBool)
+XPT_FillInterfaceDirectoryEntry(XPTArena *arena,
+ XPTInterfaceDirectoryEntry *ide,
+ nsID *iid, char *name, char *name_space,
+ XPTInterfaceDescriptor *descriptor);
+
+extern XPT_PUBLIC_API(void)
+XPT_DestroyInterfaceDirectoryEntry(XPTArena *arena,
+ XPTInterfaceDirectoryEntry* ide);
+
+/*
+ * An InterfaceDescriptor is a variable-size record used to describe a
+ * single XPCOM interface, including all of its methods.
+ */
+struct XPTInterfaceDescriptor {
+ PRUint16 parent_interface;
+ PRUint16 num_methods;
+ XPTMethodDescriptor *method_descriptors;
+ PRUint16 num_constants;
+ XPTConstDescriptor *const_descriptors;
+ PRUint8 flags;
+
+ /* additional_types are used for arrays where we may need multiple
+ * XPTTypeDescriptors for a single XPTMethodDescriptor. Since we still
+ * want to have a simple array of XPTMethodDescriptor (each with a single
+ * embedded XPTTypeDescriptor), a XPTTypeDescriptor can have a reference
+ * to an 'additional_type'. That reference is an index in this
+ * "additional_types" array. So a given XPTMethodDescriptor might have
+ * a whole chain of these XPTTypeDescriptors to represent, say, a multi
+ * dimensional array.
+ *
+ * Note that in the typelib file these additional types are stored 'inline'
+ * in the MethodDescriptor. But, in the typelib MethodDescriptors can be
+ * of varying sizes, where in XPT's in memory mapping of the data we want
+ * them to be of fixed size. This additional_types scheme is here to allow
+ * for that.
+ */
+
+ XPTTypeDescriptor *additional_types;
+ PRUint16 num_additional_types;
+};
+
+#define XPT_ID_SCRIPTABLE 0x80
+#define XPT_ID_FUNCTION 0x40
+#define XPT_ID_FLAGMASK 0xc0
+#define XPT_ID_TAGMASK (~XPT_ID_FLAGMASK)
+#define XPT_ID_TAG(id) ((id).flags & XPT_ID_TAGMASK)
+
+#define XPT_ID_IS_SCRIPTABLE(flags) (flags & XPT_ID_SCRIPTABLE)
+#define XPT_ID_IS_FUNCTION(flags) (flags & XPT_ID_FUNCTION)
+
+extern XPT_PUBLIC_API(PRBool)
+XPT_GetInterfaceIndexByName(XPTInterfaceDirectoryEntry *ide_block,
+ PRUint16 num_interfaces, char *name,
+ PRUint16 *indexp);
+
+extern XPT_PUBLIC_API(XPTInterfaceDescriptor *)
+XPT_NewInterfaceDescriptor(XPTArena *arena,
+ PRUint16 parent_interface, PRUint16 num_methods,
+ PRUint16 num_constants, PRUint8 flags);
+
+extern XPT_PUBLIC_API(void)
+XPT_FreeInterfaceDescriptor(XPTArena *arena, XPTInterfaceDescriptor* id);
+
+extern XPT_PUBLIC_API(PRBool)
+XPT_InterfaceDescriptorAddTypes(XPTArena *arena, XPTInterfaceDescriptor *id,
+ PRUint16 num);
+
+extern XPT_PUBLIC_API(PRBool)
+XPT_InterfaceDescriptorAddMethods(XPTArena *arena, XPTInterfaceDescriptor *id,
+ PRUint16 num);
+
+extern XPT_PUBLIC_API(PRBool)
+XPT_InterfaceDescriptorAddConsts(XPTArena *arena, XPTInterfaceDescriptor *id,
+ PRUint16 num);
+
+/*
+ * This is our special string struct with a length value associated with it,
+ * which means that it can contains embedded NULs.
+ */
+struct XPTString {
+ PRUint16 length;
+ char *bytes;
+};
+
+extern XPT_PUBLIC_API(XPTString *)
+XPT_NewString(XPTArena *arena, PRUint16 length, char *bytes);
+
+extern XPT_PUBLIC_API(XPTString *)
+XPT_NewStringZ(XPTArena *arena, char *bytes);
+
+/*
+ * A TypeDescriptor is a variable-size record used to identify the type of a
+ * method argument or return value.
+ *
+ * There are three types of TypeDescriptors:
+ *
+ * SimpleTypeDescriptor
+ * InterfaceTypeDescriptor
+ * InterfaceIsTypeDescriptor
+ *
+ * The tag field in the prefix indicates which of the variant TypeDescriptor
+ * records is being used, and hence the way any remaining fields should be
+ * parsed. Values from 0 to 17 refer to SimpleTypeDescriptors. The value 18
+ * designates an InterfaceTypeDescriptor, while 19 represents an
+ * InterfaceIsTypeDescriptor.
+ */
+
+/* why bother with a struct? - other code relies on this being a struct */
+struct XPTTypeDescriptorPrefix {
+ PRUint8 flags;
+};
+
+/* flag bits -- fur and jband were right, I was miserably wrong */
+#define XPT_TDP_POINTER 0x80
+#define XPT_TDP_UNIQUE_POINTER 0x40
+#define XPT_TDP_REFERENCE 0x20
+#define XPT_TDP_FLAGMASK 0xe0
+#define XPT_TDP_TAGMASK (~XPT_TDP_FLAGMASK)
+#define XPT_TDP_TAG(tdp) ((tdp).flags & XPT_TDP_TAGMASK)
+
+#define XPT_TDP_IS_POINTER(flags) (flags & XPT_TDP_POINTER)
+#define XPT_TDP_IS_UNIQUE_POINTER(flags) (flags & XPT_TDP_UNIQUE_POINTER)
+#define XPT_TDP_IS_REFERENCE(flags) (flags & XPT_TDP_REFERENCE)
+
+/*
+ * The following enum maps mnemonic names to the different numeric values
+ * of XPTTypeDescriptor->tag.
+ */
+enum XPTTypeDescriptorTags {
+ TD_INT8 = 0,
+ TD_INT16 = 1,
+ TD_INT32 = 2,
+ TD_INT64 = 3,
+ TD_UINT8 = 4,
+ TD_UINT16 = 5,
+ TD_UINT32 = 6,
+ TD_UINT64 = 7,
+ TD_FLOAT = 8,
+ TD_DOUBLE = 9,
+ TD_BOOL = 10,
+ TD_CHAR = 11,
+ TD_WCHAR = 12,
+ TD_VOID = 13,
+ TD_PNSIID = 14,
+ TD_DOMSTRING = 15,
+ TD_PSTRING = 16,
+ TD_PWSTRING = 17,
+ TD_INTERFACE_TYPE = 18,
+ TD_INTERFACE_IS_TYPE = 19,
+ TD_ARRAY = 20,
+ TD_PSTRING_SIZE_IS = 21,
+ TD_PWSTRING_SIZE_IS = 22,
+ TD_UTF8STRING = 23,
+ TD_CSTRING = 24,
+ TD_ASTRING = 25
+};
+
+struct XPTTypeDescriptor {
+ XPTTypeDescriptorPrefix prefix;
+ PRUint8 argnum; /* used for iid_is and size_is */
+ PRUint8 argnum2; /* used for length_is */
+ union {
+ PRUint16 iface; /* used for TD_INTERFACE_TYPE */
+ PRUint16 additional_type; /* used for TD_ARRAY */
+ } type;
+};
+
+#define XPT_COPY_TYPE(to, from) \
+ (to).prefix.flags = (from).prefix.flags; \
+ (to).argnum = (from).argnum; \
+ (to).argnum2 = (from).argnum2; \
+ (to).type.additional_type = (from).type.additional_type;
+
+/*
+ * A ConstDescriptor is a variable-size record that records the name and
+ * value of a scoped interface constant.
+ *
+ * The types of the method parameter are restricted to the following subset
+ * of TypeDescriptors:
+ *
+ * int8, uint8, int16, uint16, int32, uint32,
+ * int64, uint64, wchar_t, char, string
+ *
+ * The type (and thus the size) of the value record is determined by the
+ * contents of the associated TypeDescriptor record. For instance, if type
+ * corresponds to int16, then value is a two-byte record consisting of a
+ * 16-bit signed integer. For a ConstDescriptor type of string, the value
+ * record is of type String*, i.e. an offset within the data pool to a
+ * String record containing the constant string.
+ */
+union XPTConstValue {
+ PRInt8 i8;
+ PRUint8 ui8;
+ PRInt16 i16;
+ PRUint16 ui16;
+ PRInt32 i32;
+ PRUint32 ui32;
+ PRInt64 i64;
+ PRUint64 ui64;
+ float flt;
+ double dbl;
+ PRBool bul;
+ char ch;
+ PRUint16 wch;
+ nsID *iid;
+ XPTString *string;
+ char *str;
+ PRUint16 *wstr;
+}; /* varies according to type */
+
+struct XPTConstDescriptor {
+ char *name;
+ XPTTypeDescriptor type;
+ union XPTConstValue value;
+};
+
+/*
+ * A ParamDescriptor is a variable-size record used to describe either a
+ * single argument to a method or a method's result.
+ */
+struct XPTParamDescriptor {
+ PRUint8 flags;
+ XPTTypeDescriptor type;
+};
+
+/* flag bits -- jband and fur were right, and I was miserably wrong */
+#define XPT_PD_IN 0x80
+#define XPT_PD_OUT 0x40
+#define XPT_PD_RETVAL 0x20
+#define XPT_PD_SHARED 0x10
+#define XPT_PD_DIPPER 0x08
+#define XPT_PD_FLAGMASK 0xf8
+
+#define XPT_PD_IS_IN(flags) (flags & XPT_PD_IN)
+#define XPT_PD_IS_OUT(flags) (flags & XPT_PD_OUT)
+#define XPT_PD_IS_RETVAL(flags) (flags & XPT_PD_RETVAL)
+#define XPT_PD_IS_SHARED(flags) (flags & XPT_PD_SHARED)
+#define XPT_PD_IS_DIPPER(flags) (flags & XPT_PD_DIPPER)
+
+/* this is bogus
+#define XPT_PARAMDESCRIPTOR_SIZE (XPT_TYPEDESCRIPTOR_SIZE + 1)
+*/
+
+extern XPT_PUBLIC_API(PRBool)
+XPT_FillParamDescriptor(XPTArena *arena,
+ XPTParamDescriptor *pd, PRUint8 flags,
+ XPTTypeDescriptor *type);
+
+/*
+ * A MethodDescriptor is a variable-size record used to describe a single
+ * interface method.
+ */
+struct XPTMethodDescriptor {
+ char *name;
+ XPTParamDescriptor *params;
+ XPTParamDescriptor *result;
+ PRUint8 flags;
+ PRUint8 num_args;
+};
+
+/* flag bits -- jband and fur were right, and I was miserably wrong */
+#define XPT_MD_GETTER 0x80
+#define XPT_MD_SETTER 0x40
+#define XPT_MD_NOTXPCOM 0x20
+#define XPT_MD_CTOR 0x10
+#define XPT_MD_HIDDEN 0x08
+#define XPT_MD_FLAGMASK 0xf8
+
+#define XPT_MD_IS_GETTER(flags) (flags & XPT_MD_GETTER)
+#define XPT_MD_IS_SETTER(flags) (flags & XPT_MD_SETTER)
+#define XPT_MD_IS_NOTXPCOM(flags) (flags & XPT_MD_NOTXPCOM)
+#define XPT_MD_IS_CTOR(flags) (flags & XPT_MD_CTOR)
+#define XPT_MD_IS_HIDDEN(flags) (flags & XPT_MD_HIDDEN)
+
+extern XPT_PUBLIC_API(PRBool)
+XPT_FillMethodDescriptor(XPTArena *arena,
+ XPTMethodDescriptor *meth, PRUint8 flags, char *name,
+ PRUint8 num_args);
+
+/*
+ * Annotation records are variable-size records used to store secondary
+ * information about the typelib, e.g. such as the name of the tool that
+ * generated the typelib file, the date it was generated, etc. The
+ * information is stored with very loose format requirements so as to
+ * allow virtually any private data to be stored in the typelib.
+ *
+ * There are two types of Annotations:
+ *
+ * EmptyAnnotation
+ * PrivateAnnotation
+ *
+ * The tag field of the prefix discriminates among the variant record
+ * types for Annotation's. If the tag is 0, this record is an
+ * EmptyAnnotation. EmptyAnnotation's are ignored - they're only used to
+ * indicate an array of Annotation's that's completely empty. If the tag
+ * is 1, the record is a PrivateAnnotation.
+ */
+
+struct XPTAnnotation {
+ XPTAnnotation *next;
+ PRUint8 flags;
+ /* remaining fields are present in typelib iff XPT_ANN_IS_PRIVATE */
+ XPTString *creator;
+ XPTString *private_data;
+};
+
+#define XPT_ANN_LAST 0x80
+#define XPT_ANN_IS_LAST(flags) (flags & XPT_ANN_LAST)
+#define XPT_ANN_PRIVATE 0x40
+#define XPT_ANN_IS_PRIVATE(flags) (flags & XPT_ANN_PRIVATE)
+
+extern XPT_PUBLIC_API(XPTAnnotation *)
+XPT_NewAnnotation(XPTArena *arena, PRUint8 flags, XPTString *creator,
+ XPTString *private_data);
+
+PR_END_EXTERN_C
+
+#endif /* __xpt_struct_h__ */
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpt/public/xpt_xdr.h b/src/libs/xpcom18a4/xpcom/typelib/xpt/public/xpt_xdr.h
new file mode 100644
index 00000000..89d1c3f6
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpt/public/xpt_xdr.h
@@ -0,0 +1,240 @@
+/* -*- 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 ***** */
+
+/*
+ * Basic APIs for streaming typelib structures to/from disk.
+ */
+
+#ifndef __xpt_xdr_h__
+#define __xpt_xdr_h__
+
+#include "xpt_struct.h"
+
+#ifdef VBOX_WITH_XPCOM_NAMESPACE_CLEANUP
+#define XPT_Do8 VBoxNsxpXPT_Do8
+#define XPT_Do16 VBoxNsxpXPT_Do16
+#define XPT_Do32 VBoxNsxpXPT_Do32
+#define XPT_Do64 VBoxNsxpXPT_Do64
+#define XPT_DoIID VBoxNsxpXPT_DoIID
+#define XPT_DoCString VBoxNsxpXPT_DoCString
+#define XPT_DoString VBoxNsxpXPT_DoString
+#define XPT_DoStringInline VBoxNsxpXPT_DoStringInline
+#define XPT_NewXDRState VBoxNsxpXPT_NewXDRState
+#define XPT_SetDataOffset VBoxNsxpXPT_SetDataOffset
+#define XPT_SeekTo VBoxNsxpXPT_SeekTo
+#define XPT_MakeCursor VBoxNsxpXPT_MakeCursor
+#define XPT_DestroyXDRState VBoxNsxpXPT_DestroyXDRState
+#define XPT_GetXDRData VBoxNsxpXPT_GetXDRData
+#define XPT_GetXDRDataLength VBoxNsxpXPT_GetXDRDataLength
+#define XPT_DoHeader VBoxNsxpXPT_DoHeader
+#define XPT_DoHeaderPrologue VBoxNsxpXPT_DoHeaderPrologue
+#define XPT_UpdateFileLength VBoxNsxpXPT_UpdateFileLength
+#define XPT_DataOffset VBoxNsxpXPT_DataOffset
+#define XPT_GetOffsetForAddr VBoxNsxpXPT_GetOffsetForAddr
+#define XPT_SetOffsetForAddr VBoxNsxpXPT_SetOffsetForAddr
+#define XPT_SetAddrForOffset VBoxNsxpXPT_SetAddrForOffset
+#define XPT_GetAddrForOffset VBoxNsxpXPT_GetAddrForOffset
+#endif /* VBOX_WITH_XPCOM_NAMESPACE_CLEANUP */
+
+PR_BEGIN_EXTERN_C
+
+typedef struct XPTState XPTState;
+typedef struct XPTDatapool XPTDatapool;
+typedef struct XPTCursor XPTCursor;
+
+/* Opaque type, for internal use */
+typedef struct XPTHashTable XPTHashTable;
+
+extern XPT_PUBLIC_API(PRBool)
+XPT_DoString(XPTArena *arena, XPTCursor *cursor, XPTString **strp);
+
+extern XPT_PUBLIC_API(PRBool)
+XPT_DoStringInline(XPTArena *arena, XPTCursor *cursor, XPTString **strp);
+
+extern XPT_PUBLIC_API(PRBool)
+XPT_DoCString(XPTArena *arena, XPTCursor *cursor, char **strp);
+
+extern XPT_PUBLIC_API(PRBool)
+XPT_DoIID(XPTCursor *cursor, nsID *iidp);
+
+extern XPT_PUBLIC_API(PRBool)
+XPT_Do64(XPTCursor *cursor, PRInt64 *u64p);
+
+extern XPT_PUBLIC_API(PRBool)
+XPT_Do32(XPTCursor *cursor, PRUint32 *u32p);
+
+extern XPT_PUBLIC_API(PRBool)
+XPT_Do16(XPTCursor *cursor, PRUint16 *u16p);
+
+extern XPT_PUBLIC_API(PRBool)
+XPT_Do8(XPTCursor *cursor, PRUint8 *u8p);
+
+extern XPT_PUBLIC_API(PRBool)
+XPT_DoHeaderPrologue(XPTArena *arena, XPTCursor *cursor, XPTHeader **headerp, PRUint32 * ide_offset);
+extern XPT_PUBLIC_API(PRBool)
+XPT_DoHeader(XPTArena *arena, XPTCursor *cursor, XPTHeader **headerp);
+
+typedef enum {
+ XPT_ENCODE,
+ XPT_DECODE
+} XPTMode;
+
+typedef enum {
+ XPT_HEADER = 0,
+ XPT_DATA = 1
+} XPTPool;
+
+struct XPTState {
+ XPTMode mode;
+ PRUint32 data_offset;
+ PRUint32 next_cursor[2];
+ XPTDatapool *pool;
+ XPTArena *arena;
+};
+
+struct XPTDatapool {
+ XPTHashTable *offset_map;
+ char *data;
+ PRUint32 count;
+ PRUint32 allocated;
+};
+
+struct XPTCursor {
+ XPTState *state;
+ XPTPool pool;
+ PRUint32 offset;
+ PRUint8 bits;
+};
+
+extern XPT_PUBLIC_API(XPTState *)
+XPT_NewXDRState(XPTMode mode, char *data, PRUint32 len);
+
+extern XPT_PUBLIC_API(PRBool)
+XPT_MakeCursor(XPTState *state, XPTPool pool, PRUint32 len, XPTCursor *cursor);
+
+extern XPT_PUBLIC_API(PRBool)
+XPT_SeekTo(XPTCursor *cursor, PRUint32 offset);
+
+extern XPT_PUBLIC_API(void)
+XPT_DestroyXDRState(XPTState *state);
+
+/* Set file_length based on the data used in the state. (Only ENCODE.) */
+extern XPT_PUBLIC_API(PRBool)
+XPT_UpdateFileLength(XPTState *state);
+
+/* returns the length of the specified data block */
+extern XPT_PUBLIC_API(void)
+XPT_GetXDRDataLength(XPTState *state, XPTPool pool, PRUint32 *len);
+
+extern XPT_PUBLIC_API(void)
+XPT_GetXDRData(XPTState *state, XPTPool pool, char **data, PRUint32 *len);
+
+/* set or get the data offset for the state, depending on mode */
+extern XPT_PUBLIC_API(void)
+XPT_DataOffset(XPTState *state, PRUint32 *data_offsetp);
+
+extern XPT_PUBLIC_API(void)
+XPT_SetDataOffset(XPTState *state, PRUint32 data_offset);
+
+extern XPT_PUBLIC_API(PRUint32)
+XPT_GetOffsetForAddr(XPTCursor *cursor, void *addr);
+
+extern XPT_PUBLIC_API(PRBool)
+XPT_SetOffsetForAddr(XPTCursor *cursor, void *addr, PRUint32 offset);
+
+extern XPT_PUBLIC_API(PRBool)
+XPT_SetAddrForOffset(XPTCursor *cursor, PRUint32 offset, void *addr);
+
+extern XPT_PUBLIC_API(void *)
+XPT_GetAddrForOffset(XPTCursor *cursor, PRUint32 offset);
+
+/* all data structures are big-endian */
+
+#if defined IS_BIG_ENDIAN
+# ifdef VBOX
+# error "Misconfigured endian!"
+# endif
+# define XPT_SWAB32(x) x
+# define XPT_SWAB16(x) x
+#elif defined IS_LITTLE_ENDIAN
+# define XPT_SWAB32(x) (((x) >> 24) | \
+ (((x) >> 8) & 0xff00) | \
+ (((x) << 8) & 0xff0000) | \
+ ((x) << 24))
+# define XPT_SWAB16(x) (((x) >> 8) | ((x) << 8))
+#else
+# error "unknown byte order"
+#endif
+
+/*
+ * If we're decoding, we want to read the offset before we check
+ * for already-decoded values.
+ *
+ * Then we check for repetition: CheckForRepeat will see if we've already
+ * encoded/decoded this value, and if so will set offset/addr correctly
+ * and make already be true. If not, it will set up the cursor for
+ * encoding (reserve space) or decoding (seek to correct location) as
+ * appropriate. In the encode case, it will also set the addr->offset
+ * mapping.
+ */
+
+#define XPT_PREAMBLE_(cursor, addrp, pool, size, new_curs, already) \
+ XPTMode mode = cursor->state->mode; \
+ if (!(mode == XPT_ENCODE || XPT_Do32(cursor, &new_curs.offset)) || \
+ !CheckForRepeat(cursor, (void **)addrp, pool, \
+ mode == XPT_ENCODE ? size : 0u, &new_curs, \
+ &already) || \
+ !(mode == XPT_DECODE || XPT_Do32(cursor, &new_curs.offset))) \
+ return PR_FALSE; \
+ if (already) \
+ return PR_TRUE; \
+
+#define XPT_PREAMBLE_NO_ALLOC(cursor, addrp, pool, size, new_curs, already) \
+ { \
+ XPT_PREAMBLE_(cursor, addrp, pool, size, new_curs, already) \
+ }
+
+#define XPT_ERROR_HANDLE(arena, free_it) \
+ error: \
+ if (cursor->state->mode == XPT_DECODE) \
+ XPT_FREEIF(arena, free_it); \
+ return PR_FALSE;
+
+
+PR_END_EXTERN_C
+
+#endif /* __xpt_xdr_h__ */
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpt/src/.cvsignore b/src/libs/xpcom18a4/xpcom/typelib/xpt/src/.cvsignore
new file mode 100644
index 00000000..f3c7a7c5
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpt/src/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpt/src/Makefile.in b/src/libs/xpcom18a4/xpcom/typelib/xpt/src/Makefile.in
new file mode 100644
index 00000000..e0578556
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpt/src/Makefile.in
@@ -0,0 +1,76 @@
+#
+# ***** 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
+LIBRARY_NAME = xpt
+LIB_IS_C_ONLY = 1
+ifdef CROSS_COMPILE
+HOST_LIBRARY_NAME = hostxpt
+endif
+
+CSRCS = xpt_arena.c xpt_struct.c xpt_xdr.c
+HOST_CSRCS = $(CSRCS)
+
+# we don't want the shared lib, but we want to force the creation of a static lib.
+FORCE_STATIC_LIB = 1
+
+# Force use of PIC
+FORCE_USE_PIC = 1
+
+include $(topsrcdir)/config/rules.mk
+
+DEFINES += -DEXPORT_XPT_API
+HOST_CFLAGS += -DEXPORT_XPT_API
+
+# Build libxpt early so that it'll be available to xpidl, which also
+# must be built early.
+export::
+ @$(MAKE) libs
+
+ifdef CROSS_COMPILE
+ifdef HOST_NSPR_MDCPUCFG
+HOST_CFLAGS += -DMDCPUCFG=$(HOST_NSPR_MDCPUCFG)
+endif
+endif
+
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpt/src/xpt_arena.c b/src/libs/xpcom18a4/xpcom/typelib/xpt/src/xpt_arena.c
new file mode 100644
index 00000000..a0813b8f
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpt/src/xpt_arena.c
@@ -0,0 +1,358 @@
+/* -*- 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 ***** */
+
+/* Quick arena hack for xpt. */
+
+/* XXX This exists because we don't want to drag in NSPR. It *seemed*
+* to make more sense to write a quick and dirty arena than to clone
+* plarena (like js/src did). This is not optimal, but it works.
+* Half of the code here is instrumentation.
+*/
+
+#include "xpt_arena.h"
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef VBOX_USE_IPRT_IN_XPCOM
+# include <iprt/mem.h>
+#endif
+
+
+/*************************/
+/* logging stats support */
+
+#if 0 && defined(DEBUG_jband)
+#define XPT_ARENA_LOGGING 1
+#endif
+
+#ifdef XPT_ARENA_LOGGING
+
+#define LOG_MALLOC(_a, _req, _used) \
+ do{ \
+ XPT_ASSERT((_a)); \
+ ++(_a)->LOG_MallocCallCount; \
+ (_a)->LOG_MallocTotalBytesRequested += (_req); \
+ (_a)->LOG_MallocTotalBytesUsed += (_used); \
+ } while(0)
+
+#define LOG_REAL_MALLOC(_a, _size) \
+ do{ \
+ XPT_ASSERT((_a)); \
+ ++(_a)->LOG_RealMallocCallCount; \
+ (_a)->LOG_RealMallocTotalBytesRequested += (_size); \
+ } while(0)
+
+#define LOG_FREE(_a) \
+ do{ \
+ XPT_ASSERT((_a)); \
+ ++(_a)->LOG_FreeCallCount; \
+ } while(0)
+
+#define LOG_DONE_LOADING(_a) \
+ do{ \
+ XPT_ASSERT((_a)); \
+ (_a)->LOG_LoadingFreeCallCount = (_a)->LOG_FreeCallCount; \
+ } while(0)
+
+#define PRINT_STATS(_a) xpt_DebugPrintArenaStats((_a))
+static void xpt_DebugPrintArenaStats(XPTArena *arena);
+
+#else /* !XPT_ARENA_LOGGING */
+
+#define LOG_MALLOC(_a, _req, _used) ((void)0)
+#define LOG_REAL_MALLOC(_a, _size) ((void)0)
+#define LOG_FREE(_a) ((void)0)
+
+#define LOG_DONE_LOADING(_a) ((void)0)
+#define PRINT_STATS(_a) ((void)0)
+
+#endif /* XPT_ARENA_LOGGING */
+
+/****************************************************/
+
+/* Block header for each block in the arena */
+typedef struct BLK_HDR BLK_HDR;
+struct BLK_HDR
+{
+ BLK_HDR *next;
+ size_t size;
+};
+
+#define XPT_MIN_BLOCK_SIZE 32
+
+/* XXX this is lame. Should clone the code to do this bitwise */
+#define ALIGN_RND(s,a) ((a)==1?(s):((((s)+(a)-1)/(a))*(a)))
+
+struct XPTArena
+{
+ BLK_HDR *first;
+ PRUint8 *next;
+ size_t space;
+ size_t alignment;
+ size_t block_size;
+ char *name;
+
+#ifdef XPT_ARENA_LOGGING
+ PRUint32 LOG_MallocCallCount;
+ PRUint32 LOG_MallocTotalBytesRequested;
+ PRUint32 LOG_MallocTotalBytesUsed;
+ PRUint32 LOG_FreeCallCount;
+ PRUint32 LOG_LoadingFreeCallCount;
+ PRUint32 LOG_RealMallocCallCount;
+ PRUint32 LOG_RealMallocTotalBytesRequested;
+#endif /* XPT_ARENA_LOGGING */
+};
+
+XPT_PUBLIC_API(XPTArena *)
+XPT_NewArena(PRUint32 block_size, size_t alignment, const char* name)
+{
+#ifdef VBOX_USE_IPRT_IN_XPCOM
+ XPTArena *arena = RTMemAllocZ(sizeof(XPTArena));
+#else
+ XPTArena *arena = calloc(1, sizeof(XPTArena));
+#endif
+ if (arena) {
+ XPT_ASSERT(alignment);
+ if (alignment > sizeof(double))
+ alignment = sizeof(double);
+ arena->alignment = alignment;
+
+ if (block_size < XPT_MIN_BLOCK_SIZE)
+ block_size = XPT_MIN_BLOCK_SIZE;
+ arena->block_size = ALIGN_RND(block_size, alignment);
+
+ /* must have room for at least one item! */
+ XPT_ASSERT(arena->block_size >=
+ ALIGN_RND(sizeof(BLK_HDR), alignment) +
+ ALIGN_RND(1, alignment));
+
+ if (name) {
+ arena->name = XPT_STRDUP(arena, name);
+#ifdef XPT_ARENA_LOGGING
+ /* fudge the stats since we are using space in the arena */
+ arena->LOG_MallocCallCount = 0;
+ arena->LOG_MallocTotalBytesRequested = 0;
+ arena->LOG_MallocTotalBytesUsed = 0;
+#endif /* XPT_ARENA_LOGGING */
+ }
+ }
+ return arena;
+}
+
+XPT_PUBLIC_API(void)
+XPT_DestroyArena(XPTArena *arena)
+{
+ BLK_HDR* cur;
+ BLK_HDR* next;
+
+ cur = arena->first;
+ while (cur) {
+ next = cur->next;
+#ifdef VBOX_USE_IPRT_IN_XPCOM
+ RTMemFree(cur);
+#else
+ free(cur);
+#endif
+ cur = next;
+ }
+#ifdef VBOX_USE_IPRT_IN_XPCOM
+ RTMemFree(arena);
+#else
+ free(arena);
+#endif
+}
+
+XPT_PUBLIC_API(void)
+XPT_DumpStats(XPTArena *arena)
+{
+ PRINT_STATS(arena);
+}
+
+
+/*
+* Our alignment rule is that we always round up the size of each allocation
+* so that the 'arena->next' pointer one will point to properly aligned space.
+*/
+
+XPT_PUBLIC_API(void *)
+XPT_ArenaMalloc(XPTArena *arena, size_t size)
+{
+ PRUint8 *cur;
+ size_t bytes;
+
+ if (!size)
+ return NULL;
+
+ if (!arena) {
+ XPT_ASSERT(0);
+ return NULL;
+ }
+
+ bytes = ALIGN_RND(size, arena->alignment);
+
+ LOG_MALLOC(arena, size, bytes);
+
+ if (bytes > arena->space) {
+ BLK_HDR* new_block;
+ size_t block_header_size = ALIGN_RND(sizeof(BLK_HDR), arena->alignment);
+ size_t new_space = arena->block_size;
+
+ if (bytes > new_space - block_header_size)
+ new_space += bytes;
+
+#ifdef VBOX_USE_IPRT_IN_XPCOM
+ new_block = (BLK_HDR*) RTMemAllocZ(new_space/arena->alignment * (size_t)arena->alignment);
+#else
+ new_block = (BLK_HDR*) calloc(new_space/arena->alignment,
+ arena->alignment);
+#endif
+ if (!new_block) {
+ arena->next = NULL;
+ arena->space = 0;
+ return NULL;
+ }
+
+ LOG_REAL_MALLOC(arena, new_space);
+
+ /* link block into the list of blocks for use when we destroy */
+ new_block->next = arena->first;
+ arena->first = new_block;
+
+ /* save other block header info */
+ new_block->size = new_space;
+
+ /* set info for current block */
+ arena->next = ((PRUint8*)new_block) + block_header_size;
+ arena->space = new_space - block_header_size;
+
+#ifdef DEBUG
+ /* mark block for corruption check */
+ memset(arena->next, 0xcd, arena->space);
+#endif
+ }
+
+#ifdef DEBUG
+ {
+ /* do corruption check */
+ size_t i;
+ for (i = 0; i < bytes; ++i) {
+ XPT_ASSERT(arena->next[i] == 0xcd);
+ }
+ /* we guarantee that the block will be filled with zeros */
+ memset(arena->next, 0, bytes);
+ }
+#endif
+
+ cur = arena->next;
+ arena->next += bytes;
+ arena->space -= bytes;
+
+ return cur;
+}
+
+
+XPT_PUBLIC_API(char *)
+XPT_ArenaStrDup(XPTArena *arena, const char * s)
+{
+ size_t len;
+ char* cur;
+
+ if (!s)
+ return NULL;
+
+ len = strlen(s)+1;
+ cur = XPT_ArenaMalloc(arena, len);
+ memcpy(cur, s, len);
+ return cur;
+}
+
+XPT_PUBLIC_API(void)
+XPT_NotifyDoneLoading(XPTArena *arena)
+{
+#ifdef XPT_ARENA_LOGGING
+ if (arena) {
+ LOG_DONE_LOADING(arena);
+ }
+#endif
+}
+
+XPT_PUBLIC_API(void)
+XPT_ArenaFree(XPTArena *arena, void *block)
+{
+ LOG_FREE(arena);
+}
+
+#ifdef XPT_ARENA_LOGGING
+static void xpt_DebugPrintArenaStats(XPTArena *arena)
+{
+ printf("()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()\n");
+ printf("Start xpt arena stats for \"%s\"\n",
+ arena->name ? arena->name : "unnamed arena");
+ printf("\n");
+ printf("%d times arena malloc called\n", (int) arena->LOG_MallocCallCount);
+ printf("%d total bytes requested from arena malloc\n", (int) arena->LOG_MallocTotalBytesRequested);
+ printf("%d average bytes requested per call to arena malloc\n", (int)arena->LOG_MallocCallCount ? (arena->LOG_MallocTotalBytesRequested/arena->LOG_MallocCallCount) : 0);
+ printf("%d average bytes used per call (accounts for alignment overhead)\n", (int)arena->LOG_MallocCallCount ? (arena->LOG_MallocTotalBytesUsed/arena->LOG_MallocCallCount) : 0);
+ printf("%d average bytes used per call (accounts for all overhead and waste)\n", (int)arena->LOG_MallocCallCount ? (arena->LOG_RealMallocTotalBytesRequested/arena->LOG_MallocCallCount) : 0);
+ printf("\n");
+ printf("%d during loading times arena free called\n", (int) arena->LOG_LoadingFreeCallCount);
+ printf("%d during loading approx total bytes not freed\n", (int) arena->LOG_LoadingFreeCallCount * (int) (arena->LOG_MallocCallCount ? (arena->LOG_MallocTotalBytesUsed/arena->LOG_MallocCallCount) : 0));
+ printf("\n");
+ printf("%d total times arena free called\n", (int) arena->LOG_FreeCallCount);
+ printf("%d approx total bytes not freed until arena destruction\n", (int) arena->LOG_FreeCallCount * (int) (arena->LOG_MallocCallCount ? (arena->LOG_MallocTotalBytesUsed/arena->LOG_MallocCallCount) : 0 ));
+ printf("\n");
+ printf("%d times arena called system malloc\n", (int) arena->LOG_RealMallocCallCount);
+ printf("%d total bytes arena requested from system\n", (int) arena->LOG_RealMallocTotalBytesRequested);
+ printf("%d byte block size specified at arena creation time\n", (int) arena->block_size);
+ printf("%d byte block alignment specified at arena creation time\n", (int) arena->alignment);
+ printf("\n");
+ printf("End xpt arena stats\n");
+ printf("()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()\n");
+}
+#endif
+
+/***************************************************************************/
+
+#ifdef DEBUG
+XPT_PUBLIC_API(void)
+XPT_AssertFailed(const char *s, const char *file, PRUint32 lineno)
+{
+ fprintf(stderr, "Assertion failed: %s, file %s, line %d\n",
+ s, file, lineno);
+ abort();
+}
+#endif
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpt/src/xpt_struct.c b/src/libs/xpcom18a4/xpcom/typelib/xpt/src/xpt_struct.c
new file mode 100644
index 00000000..93435910
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpt/src/xpt_struct.c
@@ -0,0 +1,956 @@
+/* -*- 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 ***** */
+
+/* Implementation of XDR routines for typelib structures. */
+
+#include "xpt_xdr.h"
+#include "xpt_struct.h"
+#include <string.h>
+#include <stdio.h>
+
+/***************************************************************************/
+/* Forward declarations. */
+
+static PRUint32
+SizeOfTypeDescriptor(XPTTypeDescriptor *td, XPTInterfaceDescriptor *id);
+
+static PRUint32
+SizeOfMethodDescriptor(XPTMethodDescriptor *md, XPTInterfaceDescriptor *id);
+
+static PRUint32
+SizeOfConstDescriptor(XPTConstDescriptor *cd, XPTInterfaceDescriptor *id);
+
+static PRUint32
+SizeOfInterfaceDescriptor(XPTInterfaceDescriptor *id);
+
+static PRBool
+DoInterfaceDirectoryEntry(XPTArena *arena, XPTCursor *cursor,
+ XPTInterfaceDirectoryEntry *ide, PRUint16 entry_index);
+
+static PRBool
+DoConstDescriptor(XPTArena *arena, XPTCursor *cursor, XPTConstDescriptor *cd,
+ XPTInterfaceDescriptor *id);
+
+static PRBool
+DoMethodDescriptor(XPTArena *arena, XPTCursor *cursor, XPTMethodDescriptor *md,
+ XPTInterfaceDescriptor *id);
+
+static PRBool
+DoAnnotation(XPTArena *arena, XPTCursor *cursor, XPTAnnotation **annp);
+
+static PRBool
+DoInterfaceDescriptor(XPTArena *arena, XPTCursor *outer, XPTInterfaceDescriptor **idp);
+
+static PRBool
+DoTypeDescriptorPrefix(XPTArena *arena, XPTCursor *cursor, XPTTypeDescriptorPrefix *tdp);
+
+static PRBool
+DoTypeDescriptor(XPTArena *arena, XPTCursor *cursor, XPTTypeDescriptor *td,
+ XPTInterfaceDescriptor *id);
+
+static PRBool
+DoParamDescriptor(XPTArena *arena, XPTCursor *cursor, XPTParamDescriptor *pd,
+ XPTInterfaceDescriptor *id);
+
+/***************************************************************************/
+
+XPT_PUBLIC_API(PRUint32)
+XPT_SizeOfHeader(XPTHeader *header)
+{
+ XPTAnnotation *ann, *last;
+ PRUint32 size = 16 /* magic */ +
+ 1 /* major */ + 1 /* minor */ +
+ 2 /* num_interfaces */ + 4 /* file_length */ +
+ 4 /* interface_directory */ + 4 /* data_pool */;
+
+ ann = header->annotations;
+ do {
+ size += 1; /* Annotation prefix */
+ if (XPT_ANN_IS_PRIVATE(ann->flags))
+ size += 2 + ann->creator->length + 2 + ann->private_data->length;
+ last = ann;
+ ann = ann->next;
+ } while (!XPT_ANN_IS_LAST(last->flags));
+
+ return size;
+}
+
+XPT_PUBLIC_API(PRUint32)
+XPT_SizeOfHeaderBlock(XPTHeader *header)
+{
+ PRUint32 size = XPT_SizeOfHeader(header);
+
+ size += header->num_interfaces * sizeof (XPTInterfaceDirectoryEntry);
+
+ return size;
+}
+
+XPT_PUBLIC_API(XPTHeader *)
+XPT_NewHeader(XPTArena *arena, PRUint16 num_interfaces, PRUint8 major_version, PRUint8 minor_version)
+{
+ XPTHeader *header = XPT_NEWZAP(arena, XPTHeader);
+ if (!header)
+ return NULL;
+ memcpy(header->magic, XPT_MAGIC, 16);
+ header->major_version = major_version;
+ header->minor_version = minor_version;
+ header->num_interfaces = num_interfaces;
+ if (num_interfaces) {
+ header->interface_directory =
+ XPT_CALLOC(arena,
+ num_interfaces * sizeof(XPTInterfaceDirectoryEntry));
+ if (!header->interface_directory) {
+ XPT_DELETE(arena, header);
+ return NULL;
+ }
+ }
+ header->data_pool = 0; /* XXX do we even need this struct any more? */
+
+ return header;
+}
+
+XPT_PUBLIC_API(void)
+XPT_FreeHeader(XPTArena *arena, XPTHeader* aHeader)
+{
+ if (aHeader) {
+ XPTAnnotation* ann;
+ XPTInterfaceDirectoryEntry* entry = aHeader->interface_directory;
+ XPTInterfaceDirectoryEntry* end = entry + aHeader->num_interfaces;
+ for (; entry < end; entry++) {
+ XPT_DestroyInterfaceDirectoryEntry(arena, entry);
+ }
+
+ ann = aHeader->annotations;
+ while (ann) {
+ XPTAnnotation* next = ann->next;
+ if (XPT_ANN_IS_PRIVATE(ann->flags)) {
+ XPT_FREEIF(arena, ann->creator);
+ XPT_FREEIF(arena, ann->private_data);
+ }
+ XPT_DELETE(arena, ann);
+ ann = next;
+ }
+
+ XPT_FREEIF(arena, aHeader->interface_directory);
+ XPT_DELETE(arena, aHeader);
+ }
+}
+
+XPT_PUBLIC_API(PRBool)
+XPT_DoHeaderPrologue(XPTArena *arena, XPTCursor *cursor, XPTHeader **headerp, PRUint32 * ide_offset)
+{
+ XPTMode mode = cursor->state->mode;
+ unsigned int i;
+ XPTHeader * header;
+
+ if (mode == XPT_DECODE) {
+ header = XPT_NEWZAP(arena, XPTHeader);
+ if (!header)
+ return PR_FALSE;
+ *headerp = header;
+ } else {
+ header = *headerp;
+ }
+
+ if (mode == XPT_ENCODE) {
+ /* IDEs appear after header, including annotations */
+ if (ide_offset != NULL)
+ {
+ *ide_offset = XPT_SizeOfHeader(*headerp) + 1; /* one-based offset */
+ }
+ header->data_pool = XPT_SizeOfHeaderBlock(*headerp);
+ XPT_SetDataOffset(cursor->state, header->data_pool);
+ }
+
+ for (i = 0; i < sizeof(header->magic); i++) {
+ if (!XPT_Do8(cursor, &header->magic[i]))
+ goto error;
+ }
+
+ if (mode == XPT_DECODE &&
+ strncmp((const char*)header->magic, XPT_MAGIC, 16) != 0)
+ {
+ /* Require that the header contain the proper magic */
+ fprintf(stderr,
+ "libxpt: bad magic header in input file; "
+ "found '%s', expected '%s'\n",
+ header->magic, XPT_MAGIC_STRING);
+ goto error;
+ }
+
+ if (!XPT_Do8(cursor, &header->major_version) ||
+ !XPT_Do8(cursor, &header->minor_version)) {
+ goto error;
+ }
+
+ if (mode == XPT_DECODE &&
+ header->major_version >= XPT_MAJOR_INCOMPATIBLE_VERSION) {
+ /* This file is newer than we are and set to an incompatible version
+ * number. We must set the header state thusly and return.
+ */
+ header->num_interfaces = 0;
+ header->file_length = 0;
+ return PR_TRUE;
+ }
+
+ if (!XPT_Do16(cursor, &header->num_interfaces) ||
+ !XPT_Do32(cursor, &header->file_length) ||
+ (ide_offset != NULL && !XPT_Do32(cursor, ide_offset))) {
+ goto error;
+ }
+ return PR_TRUE;
+ /* XXX need to free child data sometimes! */
+ XPT_ERROR_HANDLE(arena, header);
+}
+
+XPT_PUBLIC_API(PRBool)
+XPT_DoHeader(XPTArena *arena, XPTCursor *cursor, XPTHeader **headerp)
+{
+ const int HEADER_SIZE = 24;
+ XPTMode mode = cursor->state->mode;
+ XPTHeader * header;
+ PRUint32 ide_offset;
+ int i;
+ XPTAnnotation *ann, *next, **annp;
+
+ if (!XPT_DoHeaderPrologue(arena, cursor, headerp, &ide_offset))
+ return PR_FALSE;
+ header = *headerp;
+ /*
+ * Make sure the file length reported in the header is the same size as
+ * as our buffer unless it is zero (not set)
+ */
+ if (mode == XPT_DECODE && (header->file_length != 0 &&
+ cursor->state->pool->allocated < header->file_length)) {
+ fputs("libxpt: File length in header does not match actual length. File may be corrupt\n",
+ stderr);
+ goto error;
+ }
+
+ if (mode == XPT_ENCODE)
+ XPT_DataOffset(cursor->state, &header->data_pool);
+ if (!XPT_Do32(cursor, &header->data_pool))
+ goto error;
+ if (mode == XPT_DECODE)
+ XPT_DataOffset(cursor->state, &header->data_pool);
+
+ if (mode == XPT_DECODE && header->num_interfaces) {
+ header->interface_directory =
+ XPT_CALLOC(arena, header->num_interfaces *
+ sizeof(XPTInterfaceDirectoryEntry));
+ if (!header->interface_directory)
+ goto error;
+ }
+
+ /*
+ * Iterate through the annotations rather than recurring, to avoid blowing
+ * the stack on large xpt files.
+ */
+ ann = next = header->annotations;
+ annp = &header->annotations;
+ do {
+ ann = next;
+ if (!DoAnnotation(arena, cursor, &ann))
+ goto error;
+ if (mode == XPT_DECODE) {
+ /*
+ * Make sure that we store the address of the newly allocated
+ * annotation in the previous annotation's ``next'' slot, or
+ * header->annotations for the first one.
+ */
+ *annp = ann;
+ annp = &ann->next;
+ }
+ next = ann->next;
+ } while (!XPT_ANN_IS_LAST(ann->flags));
+
+ /* shouldn't be necessary now, but maybe later */
+ XPT_SeekTo(cursor, ide_offset);
+
+ for (i = 0; i < header->num_interfaces; i++) {
+ if (!DoInterfaceDirectoryEntry(arena, cursor,
+ &header->interface_directory[i],
+ (PRUint16)(i + 1)))
+ goto error;
+ }
+
+ return PR_TRUE;
+
+ /* XXX need to free child data sometimes! */
+ XPT_ERROR_HANDLE(arena, header);
+}
+
+XPT_PUBLIC_API(PRBool)
+XPT_FillInterfaceDirectoryEntry(XPTArena *arena,
+ XPTInterfaceDirectoryEntry *ide,
+ nsID *iid, char *name, char *name_space,
+ XPTInterfaceDescriptor *descriptor)
+{
+ XPT_COPY_IID(ide->iid, *iid);
+ ide->name = name ? XPT_STRDUP(arena, name) : NULL; /* what good is it w/o a name? */
+ ide->name_space = name_space ? XPT_STRDUP(arena, name_space) : NULL;
+ ide->interface_descriptor = descriptor;
+ return PR_TRUE;
+}
+
+XPT_PUBLIC_API(void)
+XPT_DestroyInterfaceDirectoryEntry(XPTArena *arena,
+ XPTInterfaceDirectoryEntry* ide)
+{
+ if (ide) {
+ if (ide->name) XPT_FREE(arena, ide->name);
+ if (ide->name_space) XPT_FREE(arena, ide->name_space);
+ XPT_FreeInterfaceDescriptor(arena, ide->interface_descriptor);
+ }
+}
+
+/* InterfaceDirectoryEntry records go in the header */
+PRBool
+DoInterfaceDirectoryEntry(XPTArena *arena, XPTCursor *cursor,
+ XPTInterfaceDirectoryEntry *ide, PRUint16 entry_index)
+{
+ XPTMode mode = cursor->state->mode;
+
+ /* write the IID in our cursor space */
+ if (!XPT_DoIID(cursor, &(ide->iid)) ||
+
+ /* write the name string in the data pool, and the offset in our
+ cursor space */
+ !XPT_DoCString(arena, cursor, &(ide->name)) ||
+
+ /* write the name_space string in the data pool, and the offset in our
+ cursor space */
+ !XPT_DoCString(arena, cursor, &(ide->name_space)) ||
+
+ /* do InterfaceDescriptors -- later, only on encode (see below) */
+ !DoInterfaceDescriptor(arena, cursor, &ide->interface_descriptor)) {
+ goto error;
+ }
+
+ if (mode == XPT_DECODE)
+ XPT_SetOffsetForAddr(cursor, ide, entry_index);
+
+ return PR_TRUE;
+
+ XPT_ERROR_HANDLE(arena, ide);
+}
+
+XPT_PUBLIC_API(XPTInterfaceDescriptor *)
+XPT_NewInterfaceDescriptor(XPTArena *arena,
+ PRUint16 parent_interface, PRUint16 num_methods,
+ PRUint16 num_constants, PRUint8 flags)
+{
+
+ XPTInterfaceDescriptor *id = XPT_NEWZAP(arena, XPTInterfaceDescriptor);
+ if (!id)
+ return NULL;
+
+ if (num_methods) {
+ id->method_descriptors = XPT_CALLOC(arena, num_methods *
+ sizeof(XPTMethodDescriptor));
+ if (!id->method_descriptors)
+ goto free_id;
+ id->num_methods = num_methods;
+ }
+
+ if (num_constants) {
+ id->const_descriptors = XPT_CALLOC(arena, num_constants *
+ sizeof(XPTConstDescriptor));
+ if (!id->const_descriptors)
+ goto free_meth;
+ id->num_constants = num_constants;
+ }
+
+ if (parent_interface) {
+ id->parent_interface = parent_interface;
+ } else {
+ id->parent_interface = 0;
+ }
+
+ id->flags = flags;
+
+ return id;
+
+ free_meth:
+ XPT_FREEIF(arena, id->method_descriptors);
+ free_id:
+ XPT_DELETE(arena, id);
+ return NULL;
+}
+
+XPT_PUBLIC_API(void)
+XPT_FreeInterfaceDescriptor(XPTArena *arena, XPTInterfaceDescriptor* id)
+{
+ if (id) {
+ XPTMethodDescriptor *md, *mdend;
+ XPTConstDescriptor *cd, *cdend;
+
+ /* Free up method descriptors */
+ md = id->method_descriptors;
+ mdend = md + id->num_methods;
+ for (; md < mdend; md++) {
+ XPT_FREEIF(arena, md->name);
+ XPT_FREEIF(arena, md->params);
+ XPT_FREEIF(arena, md->result);
+ }
+ XPT_FREEIF(arena, id->method_descriptors);
+
+ /* Free up const descriptors */
+ cd = id->const_descriptors;
+ cdend = cd + id->num_constants;
+ for (; cd < cdend; cd++) {
+ XPT_FREEIF(arena, cd->name);
+ }
+ XPT_FREEIF(arena, id->const_descriptors);
+
+ /* Free up type descriptors */
+ XPT_FREEIF(arena, id->additional_types);
+
+ XPT_DELETE(arena, id);
+ }
+}
+
+XPT_PUBLIC_API(PRBool)
+XPT_InterfaceDescriptorAddTypes(XPTArena *arena, XPTInterfaceDescriptor *id,
+ PRUint16 num)
+{
+ XPTTypeDescriptor *old = id->additional_types;
+ XPTTypeDescriptor *new;
+ size_t old_size = id->num_additional_types * sizeof(XPTTypeDescriptor);
+ size_t new_size = (num * sizeof(XPTTypeDescriptor)) + old_size;
+
+ /* XXX should grow in chunks to minimize alloc overhead */
+ new = XPT_CALLOC(arena, new_size);
+ if (!new)
+ return PR_FALSE;
+ if (old) {
+ if (old_size)
+ memcpy(new, old, old_size);
+ XPT_FREE(arena, old);
+ }
+ id->additional_types = new;
+ id->num_additional_types += num;
+ return PR_TRUE;
+}
+
+XPT_PUBLIC_API(PRBool)
+XPT_InterfaceDescriptorAddMethods(XPTArena *arena, XPTInterfaceDescriptor *id,
+ PRUint16 num)
+{
+ XPTMethodDescriptor *old = id->method_descriptors;
+ XPTMethodDescriptor *new;
+ size_t old_size = id->num_methods * sizeof(XPTMethodDescriptor);
+ size_t new_size = (num * sizeof(XPTMethodDescriptor)) + old_size;
+
+ /* XXX should grow in chunks to minimize alloc overhead */
+ new = XPT_CALLOC(arena, new_size);
+ if (!new)
+ return PR_FALSE;
+ if (old) {
+ if (old_size)
+ memcpy(new, old, old_size);
+ XPT_FREE(arena, old);
+ }
+ id->method_descriptors = new;
+ id->num_methods += num;
+ return PR_TRUE;
+}
+
+XPT_PUBLIC_API(PRBool)
+XPT_InterfaceDescriptorAddConsts(XPTArena *arena, XPTInterfaceDescriptor *id,
+ PRUint16 num)
+{
+ XPTConstDescriptor *old = id->const_descriptors;
+ XPTConstDescriptor *new;
+ size_t old_size = id->num_constants * sizeof(XPTConstDescriptor);
+ size_t new_size = (num * sizeof(XPTConstDescriptor)) + old_size;
+
+ /* XXX should grow in chunks to minimize alloc overhead */
+ new = XPT_CALLOC(arena, new_size);
+ if (!new)
+ return PR_FALSE;
+ if (old) {
+ if (old_size)
+ memcpy(new, old, old_size);
+ XPT_FREE(arena, old);
+ }
+ id->const_descriptors = new;
+ id->num_constants += num;
+ return PR_TRUE;
+}
+
+PRUint32
+SizeOfTypeDescriptor(XPTTypeDescriptor *td, XPTInterfaceDescriptor *id)
+{
+ PRUint32 size = 1; /* prefix */
+
+ switch (XPT_TDP_TAG(td->prefix)) {
+ case TD_INTERFACE_TYPE:
+ size += 2; /* interface_index */
+ break;
+ case TD_INTERFACE_IS_TYPE:
+ size += 1; /* argnum */
+ break;
+ case TD_ARRAY:
+ size += 2 + SizeOfTypeDescriptor(
+ &id->additional_types[td->type.additional_type], id);
+ break;
+ case TD_PSTRING_SIZE_IS:
+ size += 2; /* argnum + argnum2 */
+ break;
+ case TD_PWSTRING_SIZE_IS:
+ size += 2; /* argnum + argnum2 */
+ break;
+ default:
+ /* nothing special */
+ break;
+ }
+ return size;
+}
+
+PRUint32
+SizeOfMethodDescriptor(XPTMethodDescriptor *md, XPTInterfaceDescriptor *id)
+{
+ PRUint32 i, size = 1 /* flags */ + 4 /* name */ + 1 /* num_args */;
+
+ for (i = 0; i < md->num_args; i++)
+ size += 1 + SizeOfTypeDescriptor(&md->params[i].type, id);
+
+ size += 1 + SizeOfTypeDescriptor(&md->result->type, id);
+ return size;
+}
+
+PRUint32
+SizeOfConstDescriptor(XPTConstDescriptor *cd, XPTInterfaceDescriptor *id)
+{
+ PRUint32 size = 4 /* name */ + SizeOfTypeDescriptor(&cd->type, id);
+
+ switch (XPT_TDP_TAG(cd->type.prefix)) {
+ case TD_INT8:
+ case TD_UINT8:
+ case TD_CHAR:
+ size ++;
+ break;
+ case TD_INT16:
+ case TD_UINT16:
+ case TD_WCHAR:
+ size += 2;
+ break;
+ case TD_INT32:
+ case TD_UINT32:
+ case TD_PSTRING:
+ size += 4;
+ break;
+ case TD_INT64:
+ case TD_UINT64:
+ size += 8;
+ break;
+ default:
+ fprintf(stderr, "libxpt: illegal type in ConstDescriptor: 0x%02x\n",
+ XPT_TDP_TAG(cd->type.prefix));
+ return 0;
+ }
+
+ return size;
+}
+
+PRUint32
+SizeOfInterfaceDescriptor(XPTInterfaceDescriptor *id)
+{
+ PRUint32 size = 2 /* parent interface */ + 2 /* num_methods */
+ + 2 /* num_constants */ + 1 /* flags */, i;
+ for (i = 0; i < id->num_methods; i++)
+ size += SizeOfMethodDescriptor(&id->method_descriptors[i], id);
+ for (i = 0; i < id->num_constants; i++)
+ size += SizeOfConstDescriptor(&id->const_descriptors[i], id);
+ return size;
+}
+
+PRBool
+DoInterfaceDescriptor(XPTArena *arena, XPTCursor *outer,
+ XPTInterfaceDescriptor **idp)
+{
+ XPTMode mode = outer->state->mode;
+ XPTInterfaceDescriptor *id;
+ XPTCursor curs, *cursor = &curs;
+ PRUint32 i, id_sz = 0;
+
+ if (mode == XPT_DECODE) {
+ id = XPT_NEWZAP(arena, XPTInterfaceDescriptor);
+ if (!id)
+ return PR_FALSE;
+ *idp = id;
+ } else {
+ id = *idp;
+ if (!id) {
+ id_sz = 0;
+ return XPT_Do32(outer, &id_sz);
+ }
+ id_sz = SizeOfInterfaceDescriptor(id);
+ }
+
+ if (!XPT_MakeCursor(outer->state, XPT_DATA, id_sz, cursor))
+ goto error;
+
+ if (!XPT_Do32(outer, &cursor->offset))
+ goto error;
+ if (mode == XPT_DECODE && !cursor->offset) {
+ XPT_DELETE(arena, *idp);
+ return PR_TRUE;
+ }
+ if(!XPT_Do16(cursor, &id->parent_interface) ||
+ !XPT_Do16(cursor, &id->num_methods)) {
+ goto error;
+ }
+
+ if (mode == XPT_DECODE && id->num_methods) {
+ id->method_descriptors = XPT_CALLOC(arena, id->num_methods *
+ sizeof(XPTMethodDescriptor));
+ if (!id->method_descriptors)
+ goto error;
+ }
+
+ for (i = 0; i < id->num_methods; i++) {
+ if (!DoMethodDescriptor(arena, cursor, &id->method_descriptors[i], id))
+ goto error;
+ }
+
+ if (!XPT_Do16(cursor, &id->num_constants)) {
+ goto error;
+ }
+
+ if (mode == XPT_DECODE && id->num_constants) {
+ id->const_descriptors = XPT_CALLOC(arena, id->num_constants *
+ sizeof(XPTConstDescriptor));
+ if (!id->const_descriptors)
+ goto error;
+ }
+
+ for (i = 0; i < id->num_constants; i++) {
+ if (!DoConstDescriptor(arena, cursor, &id->const_descriptors[i], id)) {
+ goto error;
+ }
+ }
+
+ if (!XPT_Do8(cursor, &id->flags)) {
+ goto error;
+ }
+
+ return PR_TRUE;
+
+ XPT_ERROR_HANDLE(arena, id);
+}
+
+PRBool
+DoConstDescriptor(XPTArena *arena, XPTCursor *cursor, XPTConstDescriptor *cd,
+ XPTInterfaceDescriptor *id)
+{
+ PRBool ok = PR_FALSE;
+
+ if (!XPT_DoCString(arena, cursor, &cd->name) ||
+ !DoTypeDescriptor(arena, cursor, &cd->type, id)) {
+
+ return PR_FALSE;
+ }
+
+ switch(XPT_TDP_TAG(cd->type.prefix)) {
+ case TD_INT8:
+ ok = XPT_Do8(cursor, (PRUint8*) &cd->value.i8);
+ break;
+ case TD_INT16:
+ ok = XPT_Do16(cursor, (PRUint16*) &cd->value.i16);
+ break;
+ case TD_INT32:
+ ok = XPT_Do32(cursor, (PRUint32*) &cd->value.i32);
+ break;
+ case TD_INT64:
+ ok = XPT_Do64(cursor, &cd->value.i64);
+ break;
+ case TD_UINT8:
+ ok = XPT_Do8(cursor, &cd->value.ui8);
+ break;
+ case TD_UINT16:
+ ok = XPT_Do16(cursor, &cd->value.ui16);
+ break;
+ case TD_UINT32:
+ ok = XPT_Do32(cursor, &cd->value.ui32);
+ break;
+ case TD_UINT64:
+ ok = XPT_Do64(cursor, (PRInt64 *)&cd->value.ui64);
+ break;
+ case TD_CHAR:
+ ok = XPT_Do8(cursor, (PRUint8*) &cd->value.ch);
+ break;
+ case TD_WCHAR:
+ ok = XPT_Do16(cursor, &cd->value.wch);
+ break;
+ /* fall-through */
+ default:
+ fprintf(stderr, "illegal type!\n");
+ break;
+ }
+
+ return ok;
+
+}
+
+XPT_PUBLIC_API(PRBool)
+XPT_FillMethodDescriptor(XPTArena *arena, XPTMethodDescriptor *meth,
+ PRUint8 flags, char *name, PRUint8 num_args)
+{
+ meth->flags = flags & XPT_MD_FLAGMASK;
+ meth->name = XPT_STRDUP(arena, name);
+ if (!meth->name)
+ return PR_FALSE;
+ meth->num_args = num_args;
+ if (num_args) {
+ meth->params = XPT_CALLOC(arena, num_args * sizeof(XPTParamDescriptor));
+ if (!meth->params)
+ goto free_name;
+ } else {
+ meth->params = NULL;
+ }
+ meth->result = XPT_NEWZAP(arena, XPTParamDescriptor);
+ if (!meth->result)
+ goto free_params;
+ return PR_TRUE;
+
+ free_params:
+ XPT_DELETE(arena, meth->params);
+ free_name:
+ XPT_DELETE(arena, meth->name);
+ return PR_FALSE;
+}
+
+PRBool
+DoMethodDescriptor(XPTArena *arena, XPTCursor *cursor, XPTMethodDescriptor *md,
+ XPTInterfaceDescriptor *id)
+{
+ XPTMode mode = cursor->state->mode;
+ int i;
+
+ if (!XPT_Do8(cursor, &md->flags) ||
+ !XPT_DoCString(arena, cursor, &md->name) ||
+ !XPT_Do8(cursor, &md->num_args))
+ return PR_FALSE;
+
+ if (mode == XPT_DECODE && md->num_args) {
+ md->params = XPT_CALLOC(arena, md->num_args * sizeof(XPTParamDescriptor));
+ if (!md->params)
+ return PR_FALSE;
+ }
+
+ for(i = 0; i < md->num_args; i++) {
+ if (!DoParamDescriptor(arena, cursor, &md->params[i], id))
+ goto error;
+ }
+
+ if (mode == XPT_DECODE) {
+ md->result = XPT_NEWZAP(arena, XPTParamDescriptor);
+ if (!md->result)
+ return PR_FALSE;
+ }
+
+ if (!md->result ||
+ !DoParamDescriptor(arena, cursor, md->result, id))
+ goto error;
+
+ return PR_TRUE;
+
+ XPT_ERROR_HANDLE(arena, md->params);
+}
+
+XPT_PUBLIC_API(PRBool)
+XPT_FillParamDescriptor(XPTArena *arena, XPTParamDescriptor *pd, PRUint8 flags,
+ XPTTypeDescriptor *type)
+{
+ pd->flags = flags & XPT_PD_FLAGMASK;
+ XPT_COPY_TYPE(pd->type, *type);
+ return PR_TRUE;
+}
+
+PRBool
+DoParamDescriptor(XPTArena *arena, XPTCursor *cursor, XPTParamDescriptor *pd,
+ XPTInterfaceDescriptor *id)
+{
+ if (!XPT_Do8(cursor, &pd->flags) ||
+ !DoTypeDescriptor(arena, cursor, &pd->type, id))
+ return PR_FALSE;
+
+ return PR_TRUE;
+}
+
+PRBool
+DoTypeDescriptorPrefix(XPTArena *arena, XPTCursor *cursor, XPTTypeDescriptorPrefix *tdp)
+{
+ return XPT_Do8(cursor, &tdp->flags);
+}
+
+PRBool
+DoTypeDescriptor(XPTArena *arena, XPTCursor *cursor, XPTTypeDescriptor *td,
+ XPTInterfaceDescriptor *id)
+{
+ if (!DoTypeDescriptorPrefix(arena, cursor, &td->prefix)) {
+ goto error;
+ }
+
+ switch (XPT_TDP_TAG(td->prefix)) {
+ case TD_INTERFACE_TYPE:
+ if (!XPT_Do16(cursor, &td->type.iface))
+ goto error;
+ break;
+ case TD_INTERFACE_IS_TYPE:
+ if (!XPT_Do8(cursor, &td->argnum))
+ goto error;
+ break;
+ case TD_ARRAY:
+ if (!XPT_Do8(cursor, &td->argnum) ||
+ !XPT_Do8(cursor, &td->argnum2))
+ goto error;
+
+ if (cursor->state->mode == XPT_DECODE) {
+ if(!XPT_InterfaceDescriptorAddTypes(arena, id, 1))
+ goto error;
+ td->type.additional_type = id->num_additional_types - 1;
+ }
+
+ if (!DoTypeDescriptor(arena, cursor,
+ &id->additional_types[td->type.additional_type],
+ id))
+ goto error;
+ break;
+ case TD_PSTRING_SIZE_IS:
+ case TD_PWSTRING_SIZE_IS:
+ if (!XPT_Do8(cursor, &td->argnum) ||
+ !XPT_Do8(cursor, &td->argnum2))
+ goto error;
+ break;
+
+ default:
+ /* nothing special */
+ break;
+ }
+ return PR_TRUE;
+
+ XPT_ERROR_HANDLE(arena, td);
+}
+
+XPT_PUBLIC_API(XPTAnnotation *)
+XPT_NewAnnotation(XPTArena *arena, PRUint8 flags, XPTString *creator,
+ XPTString *private_data)
+{
+ XPTAnnotation *ann = XPT_NEWZAP(arena, XPTAnnotation);
+ if (!ann)
+ return NULL;
+ ann->flags = flags;
+ if (XPT_ANN_IS_PRIVATE(flags)) {
+ ann->creator = creator;
+ ann->private_data = private_data;
+ }
+ return ann;
+}
+
+PRBool
+DoAnnotation(XPTArena *arena, XPTCursor *cursor, XPTAnnotation **annp)
+{
+ XPTMode mode = cursor->state->mode;
+ XPTAnnotation *ann;
+
+ if (mode == XPT_DECODE) {
+ ann = XPT_NEWZAP(arena, XPTAnnotation);
+ if (!ann)
+ return PR_FALSE;
+ *annp = ann;
+ } else {
+ ann = *annp;
+ }
+
+ if (!XPT_Do8(cursor, &ann->flags))
+ goto error;
+
+ if (XPT_ANN_IS_PRIVATE(ann->flags)) {
+ if (!XPT_DoStringInline(arena, cursor, &ann->creator) ||
+ !XPT_DoStringInline(arena, cursor, &ann->private_data))
+ goto error_2;
+ }
+
+ return PR_TRUE;
+
+ error_2:
+ if (ann && XPT_ANN_IS_PRIVATE(ann->flags)) {
+ XPT_FREEIF(arena, ann->creator);
+ XPT_FREEIF(arena, ann->private_data);
+ }
+ XPT_ERROR_HANDLE(arena, ann);
+}
+
+PRBool
+XPT_GetInterfaceIndexByName(XPTInterfaceDirectoryEntry *ide_block,
+ PRUint16 num_interfaces, char *name,
+ PRUint16 *indexp)
+{
+ int i;
+
+ for (i=1; i<=num_interfaces; i++) {
+ fprintf(stderr, "%s == %s ?\n", ide_block[i].name, name);
+ if (strcmp(ide_block[i].name, name) == 0) {
+ *indexp = i;
+ return PR_TRUE;
+ }
+ }
+ *indexp = 0;
+ return PR_FALSE;
+}
+
+static XPT_TYPELIB_VERSIONS_STRUCT versions[] = XPT_TYPELIB_VERSIONS;
+#define XPT_TYPELIB_VERSIONS_COUNT (sizeof(versions) / sizeof(versions[0]))
+
+XPT_PUBLIC_API(PRUint16)
+XPT_ParseVersionString(const char* str, PRUint8* major, PRUint8* minor)
+{
+ int i;
+ for (i = 0; i < XPT_TYPELIB_VERSIONS_COUNT; i++) {
+ if (!strcmp(versions[i].str, str)) {
+ *major = versions[i].major;
+ *minor = versions[i].minor;
+ return versions[i].code;
+ }
+ }
+ return XPT_VERSION_UNKNOWN;
+}
+
+
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpt/src/xpt_xdr.c b/src/libs/xpcom18a4/xpcom/typelib/xpt/src/xpt_xdr.c
new file mode 100644
index 00000000..cd9261d0
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpt/src/xpt_xdr.c
@@ -0,0 +1,665 @@
+/* -*- 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 ***** */
+
+/* Implementation of XDR primitives. */
+
+#include "xpt_xdr.h"
+#include "nspr.h"
+#include <string.h> /* strchr */
+
+static PRBool
+CheckForRepeat(XPTCursor *cursor, void **addrp, XPTPool pool, PRUint32 len,
+ XPTCursor *new_cursor, PRBool *already);
+
+#define ENCODING(cursor) \
+ ((cursor)->state->mode == XPT_ENCODE)
+
+#define CURS_POOL_OFFSET_RAW(cursor) \
+ ((cursor)->pool == XPT_HEADER \
+ ? (cursor)->offset \
+ : (XPT_ASSERT((cursor)->state->data_offset), \
+ (cursor)->offset + (cursor)->state->data_offset))
+
+#define CURS_POOL_OFFSET(cursor) \
+ (CURS_POOL_OFFSET_RAW(cursor) - 1)
+
+/* can be used as lvalue */
+#define CURS_POINT(cursor) \
+ ((cursor)->state->pool->data[CURS_POOL_OFFSET(cursor)])
+
+#if defined(DEBUG_shaver) || defined(DEBUG_jband) || defined(DEBUG_mccabe)
+#define DBG(x) printf##x
+#else
+#define DBG(x) (0)
+#endif
+
+/* XXX fail if XPT_DATA and !state->data_offset */
+#define CHECK_COUNT_(cursor, space) \
+ /* if we're in the header, then exceeding the data_offset is illegal */ \
+((cursor)->pool == XPT_HEADER ? \
+ (ENCODING(cursor) && \
+ ((cursor)->state->data_offset && \
+ ((cursor)->offset - 1 + (space) > (cursor)->state->data_offset)) \
+ ? (DBG(("no space left in HEADER %d + %d > %d\n", (cursor)->offset, \
+ (space), (cursor)->state->data_offset)) && PR_FALSE) \
+ : PR_TRUE) : \
+ /* if we're in the data area and we're about to exceed the allocation */ \
+ (CURS_POOL_OFFSET(cursor) + (space) > (cursor)->state->pool->allocated ? \
+ /* then grow if we're in ENCODE mode */ \
+ (ENCODING(cursor) ? GrowPool((cursor)->state->arena, \
+ (cursor)->state->pool, \
+ (cursor)->state->pool->allocated, \
+ 0, CURS_POOL_OFFSET(cursor) + (space)) \
+ /* and fail if we're in DECODE mode */ \
+ : (DBG(("can't extend in DECODE")) && PR_FALSE)) \
+ /* otherwise we're OK */ \
+ : PR_TRUE))
+
+#define CHECK_COUNT(cursor, space) \
+ (CHECK_COUNT_(cursor, space) \
+ ? PR_TRUE \
+ : (XPT_ASSERT(0), \
+ fprintf(stderr, "FATAL: can't no room for %d in cursor\n", space), \
+ PR_FALSE))
+
+/* increase the data allocation for the pool by XPT_GROW_CHUNK */
+#define XPT_GROW_CHUNK 8192
+
+/*
+ * quick and dirty hardcoded hashtable, to avoid dependence on nspr or glib.
+ * XXXmccabe it might turn out that we could use a simpler data structure here.
+ */
+typedef struct XPTHashRecord {
+ void *key;
+ void *value;
+ struct XPTHashRecord *next;
+} XPTHashRecord;
+
+#define XPT_HASHSIZE 512
+
+struct XPTHashTable { /* it's already typedef'ed from before. */
+ XPTHashRecord *buckets[XPT_HASHSIZE];
+ XPTArena *arena;
+};
+
+static XPTHashTable *
+XPT_NewHashTable(XPTArena *arena) {
+ XPTHashTable *table;
+ table = XPT_NEWZAP(arena, XPTHashTable);
+ if (table)
+ table->arena = arena;
+ return table;
+}
+
+static void trimrecord(XPTArena* arena, XPTHashRecord *record) {
+ if (record == NULL)
+ return;
+ trimrecord(arena, record->next);
+ XPT_DELETE(arena, record);
+}
+
+static void
+XPT_HashTableDestroy(XPTHashTable *table) {
+ int i;
+ for (i = 0; i < XPT_HASHSIZE; i++)
+ trimrecord(table->arena, table->buckets[i]);
+ XPT_FREE(table->arena, table);
+}
+
+static void *
+XPT_HashTableAdd(XPTHashTable *table, void *key, void *value) {
+ XPTHashRecord **bucketloc = table->buckets +
+ (((PRUint32)(uintptr_t)key) % XPT_HASHSIZE);
+ XPTHashRecord *bucket;
+
+ while (*bucketloc != NULL)
+ bucketloc = &((*bucketloc)->next);
+
+ bucket = XPT_NEW(table->arena, XPTHashRecord);
+ bucket->key = key;
+ bucket->value = value;
+ bucket->next = NULL;
+ *bucketloc = bucket;
+ return value;
+}
+
+static void *
+XPT_HashTableLookup(XPTHashTable *table, void *key) {
+ XPTHashRecord *bucket = table->buckets[(PRUint32)(uintptr_t)key % XPT_HASHSIZE];
+ while (bucket != NULL) {
+ if (bucket->key == key)
+ return bucket->value;
+ bucket = bucket->next;
+ }
+ return NULL;
+}
+
+XPT_PUBLIC_API(XPTState *)
+XPT_NewXDRState(XPTMode mode, char *data, PRUint32 len)
+{
+ XPTState *state;
+ XPTArena *arena;
+
+ arena = XPT_NewArena(512, sizeof(double), "an XDRState");
+ if (!arena)
+ return NULL;
+
+ state = XPT_NEWZAP(arena, XPTState);
+ if (!state)
+ goto err_free_arena;
+
+ state->arena = arena;
+ state->mode = mode;
+ state->pool = XPT_NEW(arena, XPTDatapool);
+ state->next_cursor[0] = state->next_cursor[1] = 1;
+ if (!state->pool)
+ goto err_free_state;
+
+ state->pool->count = 0;
+ state->pool->offset_map = XPT_NewHashTable(arena);
+
+ if (!state->pool->offset_map)
+ goto err_free_pool;
+ if (mode == XPT_DECODE) {
+ state->pool->data = data;
+ state->pool->allocated = len;
+ } else {
+ state->pool->data = XPT_MALLOC(arena, XPT_GROW_CHUNK);
+ if (!state->pool->data)
+ goto err_free_hash;
+ state->pool->allocated = XPT_GROW_CHUNK;
+ }
+
+ return state;
+
+ err_free_hash:
+ XPT_HashTableDestroy(state->pool->offset_map);
+ err_free_pool:
+ XPT_DELETE(arena, state->pool);
+ err_free_state:
+ XPT_DELETE(arena, state);
+ err_free_arena:
+ if (arena)
+ XPT_DestroyArena(arena);
+ return NULL;
+}
+
+XPT_PUBLIC_API(void)
+XPT_DestroyXDRState(XPTState *state)
+{
+ XPTArena *arena = state->arena;
+
+ if (state->pool->offset_map)
+ XPT_HashTableDestroy(state->pool->offset_map);
+ if (state->mode == XPT_ENCODE)
+ XPT_DELETE(arena, state->pool->data);
+ XPT_DELETE(arena, state->pool);
+ XPT_DELETE(arena, state);
+ if (arena)
+ XPT_DestroyArena(arena);
+}
+
+XPT_PUBLIC_API(void)
+XPT_GetXDRDataLength(XPTState *state, XPTPool pool, PRUint32 *len)
+{
+ *len = state->next_cursor[pool] - 1;
+}
+
+XPT_PUBLIC_API(void)
+XPT_GetXDRData(XPTState *state, XPTPool pool, char **data, PRUint32 *len)
+{
+ if (pool == XPT_HEADER) {
+ *data = state->pool->data;
+ } else {
+ *data = state->pool->data + state->data_offset;
+ }
+ *len = state->next_cursor[pool] - 1;
+}
+
+/* All offsets are 1-based */
+XPT_PUBLIC_API(void)
+XPT_DataOffset(XPTState *state, PRUint32 *data_offsetp)
+{
+ if (state->mode == XPT_DECODE)
+ XPT_SetDataOffset(state, *data_offsetp);
+ else
+ *data_offsetp = state->data_offset;
+}
+
+/* if 'exact' is set use that, else grow by the next chunk but
+ * be sure to grow no less that 'at_least' so that we can't get
+ * behind on required space.
+ */
+static PRBool
+GrowPool(XPTArena *arena, XPTDatapool *pool, PRUint32 old_size,
+ PRUint32 exact, PRUint32 at_least)
+{
+ PRUint32 total_size;
+ char *newdata;
+
+ if (exact) {
+ XPT_ASSERT(exact > pool->allocated);
+ total_size = exact;
+ } else {
+ total_size = pool->allocated + XPT_GROW_CHUNK;
+ if (at_least > total_size)
+ total_size = at_least;
+ }
+
+ newdata = XPT_MALLOC(arena, total_size);
+ if (!newdata)
+ return PR_FALSE;
+ if (pool->data) {
+ if (old_size)
+ memcpy(newdata, pool->data, old_size);
+ XPT_FREE(arena, pool->data);
+ }
+ pool->data = newdata;
+ pool->allocated = total_size;
+ return PR_TRUE;
+}
+
+XPT_PUBLIC_API(void)
+XPT_SetDataOffset(XPTState *state, PRUint32 data_offset)
+{
+ state->data_offset = data_offset;
+ /* make sure we've allocated enough space for the header */
+ if (state->mode == XPT_ENCODE &&
+ data_offset > state->pool->allocated) {
+ (void)GrowPool(state->arena, state->pool, state->pool->allocated,
+ data_offset, 0);
+ }
+}
+
+XPT_PUBLIC_API(PRBool)
+XPT_MakeCursor(XPTState *state, XPTPool pool, PRUint32 len, XPTCursor *cursor)
+{
+ cursor->state = state;
+ cursor->pool = pool;
+ cursor->bits = 0;
+ cursor->offset = state->next_cursor[pool];
+
+ if (!(CHECK_COUNT(cursor, len)))
+ return PR_FALSE;
+
+ /* this check should be in CHECK_CURSOR */
+ if (pool == XPT_DATA && !state->data_offset) {
+ fprintf(stderr, "no data offset for XPT_DATA cursor!\n");
+ return PR_FALSE;
+ }
+
+ state->next_cursor[pool] += len;
+
+ return PR_TRUE;
+}
+
+XPT_PUBLIC_API(PRBool)
+XPT_SeekTo(XPTCursor *cursor, PRUint32 offset)
+{
+ /* XXX do some real checking and update len and stuff */
+ cursor->offset = offset;
+ return PR_TRUE;
+}
+
+XPT_PUBLIC_API(XPTString *)
+XPT_NewString(XPTArena *arena, PRUint16 length, char *bytes)
+{
+ XPTString *str = XPT_NEW(arena, XPTString);
+ if (!str)
+ return NULL;
+ str->length = length;
+ /* Alloc one extra to store the trailing nul. */
+ str->bytes = XPT_MALLOC(arena, length + 1u);
+ if (!str->bytes) {
+ XPT_DELETE(arena, str);
+ return NULL;
+ }
+ memcpy(str->bytes, bytes, length);
+ /* nul-terminate it. */
+ str->bytes[length] = '\0';
+ return str;
+}
+
+XPT_PUBLIC_API(XPTString *)
+XPT_NewStringZ(XPTArena *arena, char *bytes)
+{
+ PRUint32 length = strlen(bytes);
+ if (length > 0xffff)
+ return NULL; /* too long */
+ return XPT_NewString(arena, (PRUint16)length, bytes);
+}
+
+XPT_PUBLIC_API(PRBool)
+XPT_DoStringInline(XPTArena *arena, XPTCursor *cursor, XPTString **strp)
+{
+ XPTString *str = *strp;
+ XPTMode mode = cursor->state->mode;
+ int i;
+
+ if (mode == XPT_DECODE) {
+ str = XPT_NEWZAP(arena, XPTString);
+ if (!str)
+ return PR_FALSE;
+ *strp = str;
+ }
+
+ if (!XPT_Do16(cursor, &str->length))
+ goto error;
+
+ if (mode == XPT_DECODE)
+ if (!(str->bytes = XPT_MALLOC(arena, str->length + 1u)))
+ goto error;
+
+ for (i = 0; i < str->length; i++)
+ if (!XPT_Do8(cursor, (PRUint8 *)&str->bytes[i]))
+ goto error_2;
+
+ if (mode == XPT_DECODE)
+ str->bytes[str->length] = 0;
+
+ return PR_TRUE;
+ error_2:
+ XPT_DELETE(arena, str->bytes);
+ error:
+ XPT_DELETE(arena, str);
+ return PR_FALSE;
+}
+
+XPT_PUBLIC_API(PRBool)
+XPT_DoString(XPTArena *arena, XPTCursor *cursor, XPTString **strp)
+{
+ XPTCursor my_cursor;
+ XPTString *str = *strp;
+ PRBool already;
+
+ XPT_PREAMBLE_NO_ALLOC(cursor, strp, XPT_DATA, str->length + 2, my_cursor,
+ already)
+
+ return XPT_DoStringInline(arena, &my_cursor, strp);
+}
+
+XPT_PUBLIC_API(PRBool)
+XPT_DoCString(XPTArena *arena, XPTCursor *cursor, char **identp)
+{
+ XPTCursor my_cursor;
+ char *ident = *identp;
+ PRUint32 offset = 0;
+
+ XPTMode mode = cursor->state->mode;
+
+ if (mode == XPT_DECODE) {
+ char *start, *end;
+ int len;
+
+ if (!XPT_Do32(cursor, &offset))
+ return PR_FALSE;
+
+ if (!offset) {
+ *identp = NULL;
+ return PR_TRUE;
+ }
+
+ my_cursor.pool = XPT_DATA;
+ my_cursor.offset = offset;
+ my_cursor.state = cursor->state;
+ start = &CURS_POINT(&my_cursor);
+
+ end = strchr(start, 0); /* find the end of the string */
+ if (!end) {
+ fprintf(stderr, "didn't find end of string on decode!\n");
+ return PR_FALSE;
+ }
+ len = end - start;
+ XPT_ASSERT(len > 0);
+
+ ident = XPT_MALLOC(arena, len + 1u);
+ if (!ident)
+ return PR_FALSE;
+
+ memcpy(ident, start, (size_t)len);
+ ident[len] = 0;
+ *identp = ident;
+
+ } else {
+
+ if (!ident) {
+ offset = 0;
+ if (!XPT_Do32(cursor, &offset))
+ return PR_FALSE;
+ return PR_TRUE;
+ }
+
+ if (!XPT_MakeCursor(cursor->state, XPT_DATA, strlen(ident) + 1,
+ &my_cursor) ||
+ !XPT_Do32(cursor, &my_cursor.offset))
+ return PR_FALSE;
+
+ while(*ident)
+ if (!XPT_Do8(&my_cursor, (PRUint8 *)ident++))
+ return PR_FALSE;
+ if (!XPT_Do8(&my_cursor, (PRUint8 *)ident)) /* write trailing zero */
+ return PR_FALSE;
+ }
+
+ return PR_TRUE;
+}
+
+/* XXXjband it bothers me that this is one hashtable instead of two.
+ */
+XPT_PUBLIC_API(PRUint32)
+XPT_GetOffsetForAddr(XPTCursor *cursor, void *addr)
+{
+ return (PRUint32)(uintptr_t)XPT_HashTableLookup(cursor->state->pool->offset_map, addr);
+}
+
+XPT_PUBLIC_API(PRBool)
+XPT_SetOffsetForAddr(XPTCursor *cursor, void *addr, PRUint32 offset)
+{
+ return XPT_HashTableAdd(cursor->state->pool->offset_map,
+ addr, (void *)(uintptr_t)offset) != NULL;
+}
+
+XPT_PUBLIC_API(PRBool)
+XPT_SetAddrForOffset(XPTCursor *cursor, PRUint32 offset, void *addr)
+{
+ return XPT_HashTableAdd(cursor->state->pool->offset_map,
+ (void *)(uintptr_t)offset, addr) != NULL;
+}
+
+XPT_PUBLIC_API(void *)
+XPT_GetAddrForOffset(XPTCursor *cursor, PRUint32 offset)
+{
+ return XPT_HashTableLookup(cursor->state->pool->offset_map, (void *)(uintptr_t)offset);
+}
+
+/* Used by XPT_PREAMBLE_NO_ALLOC. */
+static PRBool
+CheckForRepeat(XPTCursor *cursor, void **addrp, XPTPool pool, PRUint32 len,
+ XPTCursor *new_cursor, PRBool *already)
+{
+ void *last = *addrp;
+
+ *already = PR_FALSE;
+ new_cursor->state = cursor->state;
+ new_cursor->pool = pool;
+ new_cursor->bits = 0;
+
+ if (cursor->state->mode == XPT_DECODE) {
+
+ last = XPT_GetAddrForOffset(new_cursor, new_cursor->offset);
+
+ if (last) {
+ *already = PR_TRUE;
+ *addrp = last;
+ }
+
+ } else {
+
+ new_cursor->offset = XPT_GetOffsetForAddr(new_cursor, last);
+ if (new_cursor->offset) {
+ *already = PR_TRUE;
+ return PR_TRUE;
+ }
+
+ /* haven't already found it, so allocate room for it. */
+ if (!XPT_MakeCursor(cursor->state, pool, len, new_cursor) ||
+ !XPT_SetOffsetForAddr(new_cursor, *addrp, new_cursor->offset))
+ return PR_FALSE;
+ }
+ return PR_TRUE;
+}
+
+/*
+ * IIDs are written in struct order, in the usual big-endian way. From the
+ * typelib file spec:
+ *
+ * "For example, this IID:
+ * {00112233-4455-6677-8899-aabbccddeeff}
+ * is converted to the 128-bit value
+ * 0x00112233445566778899aabbccddeeff
+ * Note that the byte storage order corresponds to the layout of the nsIID
+ * C-struct on a big-endian architecture."
+ *
+ * (http://www.mozilla.org/scriptable/typelib_file.html#iid)
+ */
+XPT_PUBLIC_API(PRBool)
+XPT_DoIID(XPTCursor *cursor, nsID *iidp)
+{
+ int i;
+
+ if (!XPT_Do32(cursor, &iidp->m0) ||
+ !XPT_Do16(cursor, &iidp->m1) ||
+ !XPT_Do16(cursor, &iidp->m2))
+ return PR_FALSE;
+
+ for (i = 0; i < 8; i++)
+ if (!XPT_Do8(cursor, (PRUint8 *)&iidp->m3[i]))
+ return PR_FALSE;
+
+ return PR_TRUE;
+}
+
+XPT_PUBLIC_API(PRBool)
+XPT_Do64(XPTCursor *cursor, PRInt64 *u64p)
+{
+ return XPT_Do32(cursor, (PRUint32 *)u64p) &&
+ XPT_Do32(cursor, ((PRUint32 *)u64p) + 1);
+}
+
+/*
+ * When we're writing 32- or 16-bit quantities, we write a byte at a time to
+ * avoid alignment issues. Someone could come and optimize this to detect
+ * well-aligned cases and do a single store, if they cared. I might care
+ * later.
+ */
+XPT_PUBLIC_API(PRBool)
+XPT_Do32(XPTCursor *cursor, PRUint32 *u32p)
+{
+ union {
+ PRUint8 b8[4];
+ PRUint32 b32;
+ } u;
+
+ if (!CHECK_COUNT(cursor, 4))
+ return PR_FALSE;
+
+ if (ENCODING(cursor)) {
+ u.b32 = XPT_SWAB32(*u32p);
+ CURS_POINT(cursor) = u.b8[0];
+ cursor->offset++;
+ CURS_POINT(cursor) = u.b8[1];
+ cursor->offset++;
+ CURS_POINT(cursor) = u.b8[2];
+ cursor->offset++;
+ CURS_POINT(cursor) = u.b8[3];
+ } else {
+ u.b8[0] = CURS_POINT(cursor);
+ cursor->offset++;
+ u.b8[1] = CURS_POINT(cursor);
+ cursor->offset++;
+ u.b8[2] = CURS_POINT(cursor);
+ cursor->offset++;
+ u.b8[3] = CURS_POINT(cursor);
+ *u32p = XPT_SWAB32(u.b32);
+ }
+ cursor->offset++;
+ return PR_TRUE;
+}
+
+XPT_PUBLIC_API(PRBool)
+XPT_Do16(XPTCursor *cursor, PRUint16 *u16p)
+{
+ union {
+ PRUint8 b8[2];
+ PRUint16 b16;
+ } u;
+
+ if (!CHECK_COUNT(cursor, 2))
+ return PR_FALSE;
+
+ if (ENCODING(cursor)) {
+ u.b16 = XPT_SWAB16(*u16p);
+ CURS_POINT(cursor) = u.b8[0];
+ cursor->offset++;
+ CURS_POINT(cursor) = u.b8[1];
+ } else {
+ u.b8[0] = CURS_POINT(cursor);
+ cursor->offset++;
+ u.b8[1] = CURS_POINT(cursor);
+ *u16p = XPT_SWAB16(u.b16);
+ }
+ cursor->offset++;
+
+ return PR_TRUE;
+}
+
+XPT_PUBLIC_API(PRBool)
+XPT_Do8(XPTCursor *cursor, PRUint8 *u8p)
+{
+ if (!CHECK_COUNT(cursor, 1))
+ return PR_FALSE;
+ if (cursor->state->mode == XPT_ENCODE)
+ CURS_POINT(cursor) = *u8p;
+ else
+ *u8p = CURS_POINT(cursor);
+
+ cursor->offset++;
+
+ return PR_TRUE;
+}
+
+
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpt/tests/.cvsignore b/src/libs/xpcom18a4/xpcom/typelib/xpt/tests/.cvsignore
new file mode 100644
index 00000000..ebc62d94
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpt/tests/.cvsignore
@@ -0,0 +1,3 @@
+Makefile
+PrimitiveTest
+SimpleTypeLib
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpt/tests/Makefile.in b/src/libs/xpcom18a4/xpcom/typelib/xpt/tests/Makefile.in
new file mode 100644
index 00000000..afdc31b3
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpt/tests/Makefile.in
@@ -0,0 +1,59 @@
+#
+# ***** 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
+CPP_PROG_LINK = 1
+
+SIMPLE_PROGRAMS = PrimitiveTest$(BIN_SUFFIX) SimpleTypeLib$(BIN_SUFFIX)
+
+CSRCS = PrimitiveTest.c SimpleTypeLib.c
+
+LIBS = \
+ $(XPCOM_LIBS) \
+ $(NSPR_LIBS) \
+ $(NULL)
+
+include $(topsrcdir)/config/rules.mk
+
+DEFINES += -DEXPORT_XPT_API
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpt/tests/PrimitiveTest.c b/src/libs/xpcom18a4/xpcom/typelib/xpt/tests/PrimitiveTest.c
new file mode 100644
index 00000000..aad33ccc
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpt/tests/PrimitiveTest.c
@@ -0,0 +1,157 @@
+/* -*- 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 ***** */
+
+/* Test the xdr primitives from xpt_xdr.c */
+
+#include "xpt_xdr.h"
+#include <stdio.h>
+#include <string.h> /* for memcpy */
+
+#define PASS(msg) \
+ fprintf(stderr, "PASSED : %s\n", msg);
+
+#define FAIL(msg) \
+ fprintf(stderr, "FAILURE: %s\n", msg);
+
+#define TRY_(msg, cond, silent) \
+ if ((cond) && !silent) { \
+ PASS(msg); \
+ } else { \
+ FAIL(msg); \
+ return 1; \
+ }
+
+#define TRY(msg, cond) TRY_(msg, cond, 0)
+#define TRY_Q(msg, cond) TRY_(msg, cond, 1);
+
+XPTString in_str = { 4, "bazz" };
+
+struct TestData {
+ PRUint32 bit32;
+ PRUint16 bit16;
+ PRUint8 bit8[2];
+ char *cstr;
+ XPTString *str;
+} input = { 0xdeadbeef, 0xcafe, {0xba, 0xbe}, "foobar", &in_str},
+ output = {0, 0, {0, 0}, NULL, NULL };
+
+void
+dump_struct(char *label, struct TestData *str)
+{
+ fprintf(stderr, "%s: {%#08x, %#04x, {%#02x, %#02x}, %s, %d/%s}\n",
+ label, str->bit32, str->bit16, str->bit8[0], str->bit8[1],
+ str->cstr, str->str->length, str->str->bytes);
+}
+
+PRBool
+XDR(XPTArena *arena, XPTCursor *cursor, struct TestData *str)
+{
+ TRY("Do32", XPT_Do32(cursor, &str->bit32));
+ TRY("Do16", XPT_Do16(cursor, &str->bit16));
+ TRY("Do8", XPT_Do8 (cursor, &str->bit8[0]));
+ TRY("Do8", XPT_Do8 (cursor, &str->bit8[1]));
+ TRY("DoCString", XPT_DoCString(arena, cursor, &str->cstr));
+ TRY("DoString", XPT_DoString(arena, cursor, &str->str));
+ return 0;
+}
+
+int
+main(int argc, char **argv)
+{
+ XPTArena *arena;
+ XPTState *state;
+ XPTCursor curs, *cursor = &curs;
+ char *header, *data, *whole;
+ PRUint32 hlen, dlen, i;
+
+ TRY("XPT_NewArena", (arena = XPT_NewArena(1024, sizeof(double), "main")));
+
+ TRY("NewState (ENCODE)", (state = XPT_NewXDRState(XPT_ENCODE, NULL, 0)));
+
+ XPT_SetDataOffset(state, sizeof input);
+
+ TRY("MakeCursor", XPT_MakeCursor(state, XPT_HEADER, sizeof input, cursor));
+
+ dump_struct("before", &input);
+
+ if (XDR(arena, cursor, &input))
+ return 1;
+
+ fprintf(stderr, "ENCODE successful\n");
+ XPT_GetXDRData(state, XPT_HEADER, &header, &hlen);
+ fprintf(stderr, "XDR header %d bytes at %p:",
+ hlen, header);
+ for (i = 0; i < hlen; i++)
+ fprintf(stderr, "%c%02x", i ? ',' : ' ', (uint8)header[i]);
+ fprintf(stderr, "\n");
+
+ XPT_GetXDRData(state, XPT_DATA, &data, &dlen);
+
+ fprintf(stderr, "XDR data %d bytes at %p:",
+ dlen, data);
+ for (i = 0; i < dlen; i++)
+ fprintf(stderr, "%c%02x/%c", i ? ',' : ' ', (uint8)data[i],
+ (uint8)data[i]);
+ fprintf(stderr, "\n");
+
+ whole = malloc(dlen + hlen);
+ if (!whole) {
+ fprintf(stderr, "malloc %d failed!\n", dlen + hlen);
+ return 1;
+ }
+
+ /* TRY_Q("malloc", (data2 = malloc(len))); */
+ memcpy(whole, header, hlen);
+ memcpy(whole + hlen, data, dlen);
+ XPT_DestroyXDRState(state);
+
+ TRY("NewState (DECODE)", (state = XPT_NewXDRState(XPT_DECODE, whole,
+ hlen + dlen)));
+
+ TRY("MakeCursor", XPT_MakeCursor(state, XPT_HEADER, sizeof input, cursor));
+ XPT_SetDataOffset(state, sizeof input);
+
+ if (XDR(arena, cursor, &output))
+ return 1;
+
+ dump_struct("after", &output);
+ XPT_DestroyXDRState(state);
+ XPT_DestroyArena(arena);
+ free(whole);
+
+ return 0;
+}
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpt/tests/SimpleTypeLib.c b/src/libs/xpcom18a4/xpcom/typelib/xpt/tests/SimpleTypeLib.c
new file mode 100644
index 00000000..305b8520
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpt/tests/SimpleTypeLib.c
@@ -0,0 +1,192 @@
+/* -*- 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 ***** */
+
+/* Test the structure creation and serialization APIs from xpt_struct.c */
+#include <stdio.h>
+
+#include "xpt_xdr.h"
+#include "xpt_struct.h"
+
+#define PASS(msg) \
+ fprintf(stderr, "PASSED : %s\n", msg);
+
+#define FAIL(msg) \
+ fprintf(stderr, "FAILURE: %s\n", msg);
+
+#define TRY_(msg, cond, silent) \
+ if ((cond) && !silent) { \
+ PASS(msg); \
+ } else { \
+ FAIL(msg); \
+ return 1; \
+ }
+
+#define TRY(msg, cond) TRY_(msg, cond, 0)
+#define TRY_Q(msg, cond) TRY_(msg, cond, 1);
+
+struct nsID iid = {
+ 0x00112233,
+ 0x4455,
+ 0x6677,
+ {0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}
+};
+
+XPTTypeDescriptor td_void;
+
+int
+main(int argc, char **argv)
+{
+ XPTArena *arena;
+ XPTHeader *header;
+ XPTAnnotation *ann;
+ XPTInterfaceDescriptor *id;
+ XPTMethodDescriptor *meth;
+
+ XPTState *state;
+ XPTCursor curs, *cursor = &curs;
+ char *data, *head;
+ FILE *out;
+ PRUint32 len, header_sz;
+
+ PRBool ok;
+
+ td_void.prefix.flags = TD_VOID;
+
+#ifdef XP_MAC
+ if (argc == 0) {
+ static char* args[] = { "SimpleTypeLib", "simple.xpt", NULL };
+ argc = 2;
+ argv = args;
+ }
+#endif
+
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s <filename.xpt>\n"
+ " Creates a simple typelib file.\n", argv[0]);
+
+ return 1;
+ }
+
+ arena = XPT_NewArena(1024, sizeof(double), "main");
+ TRY("XPT_NewArena", arena);
+
+ /* construct a header */
+ header = XPT_NewHeader(arena, 1, XPT_MAJOR_VERSION, XPT_MINOR_VERSION);
+ TRY("NewHeader", header);
+
+
+ ann = XPT_NewAnnotation(arena, XPT_ANN_LAST | XPT_ANN_PRIVATE,
+ XPT_NewStringZ(arena, "SimpleTypeLib 1.0"),
+ XPT_NewStringZ(arena, "See You In Rome"));
+ TRY("NewAnnotation", ann);
+ header->annotations = ann;
+
+ header_sz = XPT_SizeOfHeaderBlock(header);
+
+ id = XPT_NewInterfaceDescriptor(arena, 0, 2, 2, 0);
+ TRY("NewInterfaceDescriptor", id);
+
+ ok = XPT_FillInterfaceDirectoryEntry(arena, header->interface_directory, &iid,
+ "Interface", "NS", id);
+ TRY("FillInterfaceDirectoryEntry", ok);
+
+ /* void method1(void) */
+ meth = &id->method_descriptors[0];
+ ok = XPT_FillMethodDescriptor(arena, meth, 0, "method1", 0);
+ TRY("FillMethodDescriptor", ok);
+ meth->result->flags = 0;
+ meth->result->type.prefix.flags = TD_VOID;
+
+ /* wstring method2(in uint32, in bool) */
+ meth = &id->method_descriptors[1];
+ ok = XPT_FillMethodDescriptor(arena, meth, 0, "method2", 2);
+ TRY("FillMethodDescriptor", ok);
+
+ meth->result->flags = 0;
+ meth->result->type.prefix.flags = TD_PSTRING | XPT_TDP_POINTER;
+ meth->params[0].type.prefix.flags = TD_UINT32;
+ meth->params[0].flags = XPT_PD_IN;
+ meth->params[1].type.prefix.flags = TD_BOOL;
+ meth->params[1].flags = XPT_PD_IN;
+
+#if 0
+ /* const one = 1; */
+ id->const_descriptors[0].name = "one";
+ id->const_descriptors[0].type.prefix.flags = TD_UINT16;
+ id->const_descriptors[0].value.ui16 = 1;
+
+ /* const squeamish = "ossifrage"; */
+ id->const_descriptors[1].name = "squeamish";
+ id->const_descriptors[1].type.prefix.flags = TD_PBSTR | XPT_TDP_POINTER;
+ id->const_descriptors[1].value.string = XPT_NewStringZ(arena, "ossifrage");
+#endif
+
+ /* serialize it */
+ state = XPT_NewXDRState(XPT_ENCODE, NULL, 0);
+ TRY("NewState (ENCODE)", state);
+
+ ok = XPT_MakeCursor(state, XPT_HEADER, header_sz, cursor);
+ TRY("MakeCursor", ok);
+
+ ok = XPT_DoHeader(arena, cursor, &header);
+ TRY("DoHeader", ok);
+
+ out = fopen(argv[1], "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, "\nError writing file: %s\n\n", argv[1]);
+ } else {
+ fprintf(stderr, "\nFile written: %s\n\n", argv[1]);
+ }
+ XPT_DestroyXDRState(state);
+
+ XPT_FreeHeader(arena, header);
+ XPT_DestroyArena(arena);
+
+ return 0;
+}
+
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 <stdio.h>
+#ifdef XP_MAC
+#include <stat.h>
+#include <StandardFile.h>
+#include "FullPath.h"
+#else
+#ifdef XP_OS2_EMX
+#include <sys/types.h>
+#endif
+#include <sys/stat.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#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] <filename.xpt>\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; i<header->num_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; i<id->num_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; i<id->num_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; i<md->num_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, &param_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; i<md->num_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, &param_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; i<str->length; 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 <stdio.h>
+#ifdef XP_MAC
+#include <stat.h>
+#else
+#include <sys/stat.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#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; j<header->num_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; i<trueNumberOfInterfaces; i++) {
+
+ /* Define id to save some keystrokes.
+ */
+ id = IDE_array[i].interface_descriptor;
+
+ /* Check for unresolved interface.
+ */
+ if (id) {
+
+ /* Fix parent_interface first.
+ */
+ if (id->parent_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; j<id->num_methods; j++) {
+ /* Cycle through the params first.
+ */
+ for (k=0; k<id->method_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; i<trueNumberOfInterfaces; i++) {
+ /* Only complain if the IIDs are identical and nonzero. */
+ if (compare_IIDs(&IDE_array[i-1].iid, &IDE_array[i].iid) == 0 &&
+ compare_IDE_with_zero(&IDE_array[i]) != 0) {
+ fprintf(stderr, "FATAL ERROR:\n"
+ "Duplicate IID detected (");
+ print_IID(&IDE_array[i-1].iid, stderr);
+ fprintf(stderr, ") in\n"
+ "interface %s::%s from %s\n"
+ "and\n"
+ "interface %s::%s from %s\n",
+ IDE_array[i-1].name_space ?
+ IDE_array[i-1].name_space : "",
+ IDE_array[i-1].name,
+ argv[fix_array[i-1].file_num+2],
+ IDE_array[i].name_space ?
+ IDE_array[i].name_space : "",
+ IDE_array[i].name,
+ argv[fix_array[i].file_num+2]);
+ return 1;
+ }
+ }
+ }
+
+ header = XPT_NewHeader(arena, (PRUint16)trueNumberOfInterfaces,
+ major_version, minor_version);
+
+ header->annotations = first_ann;
+ for (i=0; i<trueNumberOfInterfaces; i++) {
+ if (!copy_IDE(&IDE_array[i], &header->interface_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; i++) {
+ if (!copy_IDE(&ide[i], &ide[i-1])) {
+ return PR_FALSE;
+ }
+ }
+
+ return PR_TRUE;
+}
+
+/* update_fix_array marks a fixElement as deleted, updates its mapping
+ * to point to the "replacement" element, and moves it to the end of
+ * the array.
+ */
+PRBool
+update_fix_array(XPTArena *arena, fixElement *fix, int element_to_delete,
+ int num_interfaces, int replacement)
+{
+ fixElement *deleted;
+ int i;
+
+ if (element_to_delete >= 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; i<num_interfaces; i++) {
+ if (!copy_fixElement(&fix[i], &fix[i-1])) {
+ return PR_FALSE;
+ }
+ }
+
+ if (!copy_fixElement(deleted, &fix[num_interfaces-1])) {
+ return PR_FALSE;
+ }
+
+ return PR_TRUE;
+}
+
+/* get_new_index returns the new interface index by walking the fix_array
+ * until the file_num and interface_num match the target values. If a match
+ * is found, it checks to see if that element has been deleted. If it has
+ * been deleted, it follows that elements mapping until it gets to the
+ * proper interface (recursion). FYI, Indices are one-based; zero
+ * represents the special case (no parent interface).
+ */
+static int
+get_new_index(const fixElement *fix, int num_elements,
+ int target_file, int target_interface)
+{
+ int i;
+
+ for (i=0; i<num_elements; i++) {
+ if (fix[i].file_num == target_file &&
+ fix[i].interface_num == target_interface) {
+ if (fix[i].is_deleted) {
+ return get_new_index(fix, num_elements,
+ fix[i].maps_to_file_num,
+ fix[i].maps_to_interface_num);
+ }
+ return i+1;
+ }
+ }
+
+ return 0;
+}
+
+PRBool
+copy_IDE(XPTInterfaceDirectoryEntry *from, XPTInterfaceDirectoryEntry *to)
+{
+ if (!from || !to) {
+ return PR_FALSE;
+ }
+
+ to->iid = 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]);
+}
+