summaryrefslogtreecommitdiffstats
path: root/src/libs/xpcom18a4/xpcom/typelib/xpidl
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-11 08:17:27 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-11 08:17:27 +0000
commitf215e02bf85f68d3a6106c2a1f4f7f063f819064 (patch)
tree6bb5b92c046312c4e95ac2620b10ddf482d3fa8b /src/libs/xpcom18a4/xpcom/typelib/xpidl
parentInitial commit. (diff)
downloadvirtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.tar.xz
virtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.zip
Adding upstream version 7.0.14-dfsg.upstream/7.0.14-dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/libs/xpcom18a4/xpcom/typelib/xpidl')
-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
26 files changed, 8410 insertions, 0 deletions
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;
+}