summaryrefslogtreecommitdiffstats
path: root/src/libs/xpcom18a4/nsprpub/lib
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-06 03:01:46 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-06 03:01:46 +0000
commitf8fe689a81f906d1b91bb3220acde2a4ecb14c5b (patch)
tree26484e9d7e2c67806c2d1760196ff01aaa858e8c /src/libs/xpcom18a4/nsprpub/lib
parentInitial commit. (diff)
downloadvirtualbox-f8fe689a81f906d1b91bb3220acde2a4ecb14c5b.tar.xz
virtualbox-f8fe689a81f906d1b91bb3220acde2a4ecb14c5b.zip
Adding upstream version 6.0.4-dfsg.upstream/6.0.4-dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/libs/xpcom18a4/nsprpub/lib')
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/.cvsignore1
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/Makefile.in56
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/ds/.cvsignore2
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/ds/MANIFEST7
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/ds/Makefile.in202
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/ds/plarena.c442
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/ds/plarena.h219
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/ds/plarenas.h126
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/ds/plds.def78
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/ds/plds.rc102
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/ds/plds_symvec.opt37
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/ds/plhash.c541
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/ds/plhash.h183
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/ds/plvrsion.c125
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/libc/.cvsignore1
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/libc/Makefile.in56
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/libc/README20
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/libc/include/.cvsignore1
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/libc/include/MANIFEST9
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/libc/include/Makefile.in61
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/libc/include/README7
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/libc/include/plbase64.h103
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/libc/include/plerror.h71
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/libc/include/plgetopt.h87
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/libc/include/plresolv.h108
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/libc/include/plstr.h505
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/libc/src/.cvsignore2
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/libc/src/Makefile.in202
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/libc/src/README20
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/libc/src/base64.c428
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/libc/src/plc.def94
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/libc/src/plc.rc103
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/libc/src/plc_symvec.opt53
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/libc/src/plerror.c168
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/libc/src/plgetopt.c184
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/libc/src/plvrsion.c125
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/libc/src/strcat.c81
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/libc/src/strccmp.c115
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/libc/src/strchr.c88
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/libc/src/strcmp.c57
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/libc/src/strcpy.c84
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/libc/src/strcstr.c123
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/libc/src/strdup.c100
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/libc/src/strlen.c71
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/libc/src/strpbrk.c100
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/libc/src/strstr.c117
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/libc/src/strtok.c89
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/msgc/.cvsignore1
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/msgc/Makefile.in52
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/msgc/include/.cvsignore1
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/msgc/include/MANIFEST5
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/msgc/include/Makefile.in61
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/msgc/include/gcint.h129
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/msgc/include/prgc.h419
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/msgc/src/.cvsignore1
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/msgc/src/Makefile.in103
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/msgc/src/macgc.c75
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/msgc/src/os2gc.c83
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/msgc/src/prgcapi.c351
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/msgc/src/prmsgc.c3514
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/msgc/src/unixgc.c155
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/msgc/src/win16gc.c77
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/msgc/src/win32gc.c129
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/msgc/tests/.cvsignore1
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/msgc/tests/Makefile.in315
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/msgc/tests/gc1.c257
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/msgc/tests/thrashgc.c274
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/prstreams/.cvsignore1
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/prstreams/Makefile.in207
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/prstreams/plvrsion.c125
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/prstreams/prstrms.cpp550
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/prstreams/prstrms.h153
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/prstreams/prstrms.rc102
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/prstreams/tests/testprstrm/.cvsignore1
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/prstreams/tests/testprstrm/Makefile.in254
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/prstreams/tests/testprstrm/testprstrm.cpp204
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/tests/.cvsignore1
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/tests/Makefile.in259
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/tests/arena.c401
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/tests/base64t.c3047
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/tests/string.c3116
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/tests/windows/makefile82
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/tests/windows/readme.1st37
-rw-r--r--src/libs/xpcom18a4/nsprpub/lib/tests/windows/winevent.c348
84 files changed, 20445 insertions, 0 deletions
diff --git a/src/libs/xpcom18a4/nsprpub/lib/.cvsignore b/src/libs/xpcom18a4/nsprpub/lib/.cvsignore
new file mode 100644
index 00000000..f3c7a7c5
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/src/libs/xpcom18a4/nsprpub/lib/Makefile.in b/src/libs/xpcom18a4/nsprpub/lib/Makefile.in
new file mode 100644
index 00000000..9bdc078e
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/Makefile.in
@@ -0,0 +1,56 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# 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 MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#! gmake
+
+MOD_DEPTH = ..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+export NSPR20=1
+
+include $(topsrcdir)/config/config.mk
+
+DIRS = ds libc
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(TARGETS)
+
diff --git a/src/libs/xpcom18a4/nsprpub/lib/ds/.cvsignore b/src/libs/xpcom18a4/nsprpub/lib/ds/.cvsignore
new file mode 100644
index 00000000..bcab60f5
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/ds/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+_pl_bld.h
diff --git a/src/libs/xpcom18a4/nsprpub/lib/ds/MANIFEST b/src/libs/xpcom18a4/nsprpub/lib/ds/MANIFEST
new file mode 100644
index 00000000..ceda33b7
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/ds/MANIFEST
@@ -0,0 +1,7 @@
+#
+# This is a list of local files which get copied to the mozilla:dist directory
+#
+
+plarenas.h
+plarena.h
+plhash.h
diff --git a/src/libs/xpcom18a4/nsprpub/lib/ds/Makefile.in b/src/libs/xpcom18a4/nsprpub/lib/ds/Makefile.in
new file mode 100644
index 00000000..516e1a37
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/ds/Makefile.in
@@ -0,0 +1,202 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# 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 MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#! gmake
+
+MOD_DEPTH = ../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/config.mk
+
+INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include
+
+CSRCS = \
+ plarena.c \
+ plhash.c \
+ plvrsion.c \
+ $(NULL)
+
+HEADERS = \
+ plarenas.h \
+ plarena.h \
+ plhash.h \
+ $(NULL)
+
+HEADERS := $(addprefix $(srcdir)/, $(HEADERS))
+
+ifeq ($(OS_ARCH), WINNT)
+ifdef NS_USE_GCC
+DLLBASE=-Wl,--image-base -Wl,0x30000000
+else
+DLLBASE=/BASE:0x30000000
+endif # GCC
+RES=$(OBJDIR)/plds.res
+RESNAME=plds.rc
+endif # WINNT
+
+ifeq ($(OS_ARCH), AIX)
+ifeq ($(CLASSIC_NSPR),1)
+OS_LIBS = -lc
+else
+OS_LIBS = -lc_r
+endif
+endif
+
+ifeq ($(OS_ARCH),IRIX)
+OS_LIBS = -lc
+endif
+
+ifeq ($(OS_ARCH),SunOS)
+OS_LIBS = -lc
+MAPFILE = $(OBJDIR)/pldsmap.sun
+GARBAGE += $(MAPFILE)
+ifdef NS_USE_GCC
+ifdef GCC_USE_GNU_LD
+MKSHLIB += -Wl,--version-script,$(MAPFILE)
+else
+MKSHLIB += -Wl,-M,$(MAPFILE)
+endif
+else
+MKSHLIB += -M $(MAPFILE)
+endif
+# The -R '$ORIGIN' linker option instructs this library to search for its
+# dependencies in the same directory where it resides.
+MKSHLIB += -R '$$ORIGIN'
+endif
+
+ifeq ($(OS_ARCH),OS2)
+MAPFILE = $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).def
+GARBAGE += $(MAPFILE)
+MKSHLIB += $(MAPFILE)
+endif
+
+EXTRA_LIBS = $(LIBNSPR)
+
+# On NCR and SCOOS, we can't link with extra libraries when
+# we build a shared library. If we do so, the linker doesn't
+# complain, but we would run into weird problems at run-time.
+# Therefore on these platforms, we link just the .o files.
+ifeq ($(OS_ARCH),NCR)
+EXTRA_LIBS =
+endif
+ifeq ($(OS_ARCH),SCOOS)
+EXTRA_LIBS =
+endif
+
+ifdef RESOLVE_LINK_SYMBOLS
+EXTRA_LIBS += $(OS_LIBS)
+endif
+
+LIBRARY_NAME = plds
+LIBRARY_VERSION = $(MOD_MAJOR_VERSION)
+
+RELEASE_HEADERS = $(HEADERS)
+RELEASE_HEADERS_DEST = $(RELEASE_INCLUDE_DIR)
+RELEASE_LIBS = $(TARGETS)
+
+include $(topsrcdir)/config/rules.mk
+
+#
+# Version information generation (begin)
+#
+ECHO = echo
+TINC = $(OBJDIR)/_pl_bld.h
+PROD = $(notdir $(SHARED_LIBRARY))
+NOW = $(MOD_DEPTH)/config/$(OBJDIR)/now
+SH_DATE = $(shell date "+%Y-%m-%d %T")
+SH_NOW = $(shell $(NOW))
+
+ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT)
+ SUF = i64
+else
+ SUF = LL
+endif
+
+GARBAGE += $(TINC)
+
+$(TINC):
+ @$(MAKE_OBJDIR)
+ @$(ECHO) '#define _BUILD_STRING "$(SH_DATE)"' > $(TINC)
+ @if test ! -z "$(SH_NOW)"; then \
+ $(ECHO) '#define _BUILD_TIME $(SH_NOW)$(SUF)' >> $(TINC); \
+ else \
+ true; \
+ fi
+ @$(ECHO) '#define _PRODUCTION "$(PROD)"' >> $(TINC)
+
+
+$(OBJDIR)/plvrsion.$(OBJ_SUFFIX): plvrsion.c $(TINC)
+ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT)
+ $(CC) -Fo$@ -c $(CFLAGS) -I$(OBJDIR) $<
+else
+ifeq ($(MOZ_OS2_TOOLS), VACPP)
+ $(CC) -Fo$@ -c $(CFLAGS) -I$(OBJDIR) $<
+else
+ $(CC) -o $@ -c $(CFLAGS) -I$(OBJDIR) $<
+endif
+endif
+#
+# Version information generation (end)
+#
+
+#
+# The Client build wants the shared libraries in $(dist_bindir),
+# so we also install them there.
+#
+
+export:: $(TARGETS)
+ $(INSTALL) -m 444 $(HEADERS) $(dist_includedir)
+ $(INSTALL) -m 444 $(TARGETS) $(dist_libdir)
+ifdef SHARED_LIBRARY
+ifeq ($(OS_ARCH),HP-UX)
+ $(INSTALL) -m 755 $(SHARED_LIBRARY) $(dist_libdir)
+ $(INSTALL) -m 755 $(SHARED_LIBRARY) $(dist_bindir)
+else
+ $(INSTALL) -m 444 $(SHARED_LIBRARY) $(dist_bindir)
+endif
+endif
+ifeq ($(MOZ_BITS),16)
+ $(INSTALL) -m 444 $(HEADERS) $(MOZ_INCL)
+ $(INSTALL) -m 444 $(TARGETS) $(MOZ_DIST)/lib
+ $(INSTALL) -m 444 $(TARGETS) $(MOZ_DIST)/bin
+endif
+
+
diff --git a/src/libs/xpcom18a4/nsprpub/lib/ds/plarena.c b/src/libs/xpcom18a4/nsprpub/lib/ds/plarena.c
new file mode 100644
index 00000000..e61efbe2
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/ds/plarena.c
@@ -0,0 +1,442 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1998-2000 Netscape Communications Corporation. 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK *****
+ */
+
+/*
+ * Lifetime-based fast allocation, inspired by much prior art, including
+ * "Fast Allocation and Deallocation of Memory Based on Object Lifetimes"
+ * David R. Hanson, Software -- Practice and Experience, Vol. 20(1).
+ */
+#include <stdlib.h>
+#include <string.h>
+#include "plarena.h"
+#include "prmem.h"
+#include "prbit.h"
+#include "prlog.h"
+#include "prlock.h"
+#include "prinit.h"
+
+static PLArena *arena_freelist;
+
+#ifdef PL_ARENAMETER
+static PLArenaStats *arena_stats_list;
+
+#define COUNT(pool,what) (pool)->stats.what++
+#else
+#define COUNT(pool,what) /* nothing */
+#endif
+
+#define PL_ARENA_DEFAULT_ALIGN sizeof(double)
+
+static PRLock *arenaLock;
+static PRCallOnceType once;
+
+/*
+** InitializeArenas() -- Initialize arena operations.
+**
+** InitializeArenas() is called exactly once and only once from
+** LockArena(). This function creates the arena protection
+** lock: arenaLock.
+**
+** Note: If the arenaLock cannot be created, InitializeArenas()
+** fails quietly, returning only PR_FAILURE. This percolates up
+** to the application using the Arena API. He gets no arena
+** from PL_ArenaAllocate(). It's up to him to fail gracefully
+** or recover.
+**
+*/
+static PRStatus InitializeArenas( void )
+{
+ PR_ASSERT( arenaLock == NULL );
+ arenaLock = PR_NewLock();
+ if ( arenaLock == NULL )
+ return PR_FAILURE;
+ else
+ return PR_SUCCESS;
+} /* end ArenaInitialize() */
+
+static PRStatus LockArena( void )
+{
+ PRStatus rc = PR_CallOnce( &once, InitializeArenas );
+
+ if ( PR_FAILURE != rc )
+ PR_Lock( arenaLock );
+ return(rc);
+} /* end LockArena() */
+
+static void UnlockArena( void )
+{
+ PR_Unlock( arenaLock );
+ return;
+} /* end UnlockArena() */
+
+PR_IMPLEMENT(void) PL_InitArenaPool(
+ PLArenaPool *pool, const char *name, PRUint32 size, PRUint32 align)
+{
+#if defined(XP_MAC)
+#pragma unused (name)
+#endif
+
+ if (align == 0)
+ align = PL_ARENA_DEFAULT_ALIGN;
+ pool->mask = PR_BITMASK(PR_CeilingLog2(align));
+ pool->first.next = NULL;
+ /* Set all three addresses in pool->first to the same dummy value.
+ * These addresses are only compared with each other, but never
+ * dereferenced. */
+ pool->first.base = pool->first.avail = pool->first.limit =
+ (PRUword)PL_ARENA_ALIGN(pool, &pool->first + 1);
+ pool->current = &pool->first;
+ pool->arenasize = size;
+#ifdef PL_ARENAMETER
+ memset(&pool->stats, 0, sizeof pool->stats);
+ pool->stats.name = strdup(name);
+ pool->stats.next = arena_stats_list;
+ arena_stats_list = &pool->stats;
+#endif
+}
+
+
+/*
+** PL_ArenaAllocate() -- allocate space from an arena pool
+**
+** Description: PL_ArenaAllocate() allocates space from an arena
+** pool.
+**
+** First, try to satisfy the request from arenas starting at
+** pool->current.
+**
+** If there is not enough space in the arena pool->current, try
+** to claim an arena, on a first fit basis, from the global
+** freelist (arena_freelist).
+**
+** If no arena in arena_freelist is suitable, then try to
+** allocate a new arena from the heap.
+**
+** Returns: pointer to allocated space or NULL
+**
+** Notes: The original implementation had some difficult to
+** solve bugs; the code was difficult to read. Sometimes it's
+** just easier to rewrite it. I did that. larryh.
+**
+** See also: bugzilla: 45343.
+**
+*/
+
+PR_IMPLEMENT(void *) PL_ArenaAllocate(PLArenaPool *pool, PRUint32 nb)
+{
+ PLArena *a;
+ char *rp; /* returned pointer */
+ PRUint32 nbOld;
+
+ PR_ASSERT((nb & pool->mask) == 0);
+
+ nbOld = nb;
+ nb = (PRUword)PL_ARENA_ALIGN(pool, nb); /* force alignment */
+ if (nb < nbOld)
+ return NULL;
+
+ /* attempt to allocate from arenas at pool->current */
+ {
+ a = pool->current;
+ do {
+ if ( a->avail +nb <= a->limit ) {
+ pool->current = a;
+ rp = (char *)a->avail;
+ a->avail += nb;
+ return rp;
+ }
+ } while( NULL != (a = a->next) );
+ }
+
+ /* attempt to allocate from arena_freelist */
+ {
+ PLArena *p; /* previous pointer, for unlinking from freelist */
+
+ /* lock the arena_freelist. Make access to the freelist MT-Safe */
+ if ( PR_FAILURE == LockArena())
+ return(0);
+
+ for ( a = p = arena_freelist; a != NULL ; p = a, a = a->next ) {
+ if ( a->base +nb <= a->limit ) {
+ if ( p == arena_freelist )
+ arena_freelist = a->next;
+ else
+ p->next = a->next;
+ UnlockArena();
+ a->avail = a->base;
+ rp = (char *)a->avail;
+ a->avail += nb;
+ /* the newly allocated arena is linked after pool->current
+ * and becomes pool->current */
+ a->next = pool->current->next;
+ pool->current->next = a;
+ pool->current = a;
+ if ( NULL == pool->first.next )
+ pool->first.next = a;
+ return(rp);
+ }
+ }
+ UnlockArena();
+ }
+
+ /* attempt to allocate from the heap */
+ {
+ PRUint32 sz = PR_MAX(pool->arenasize, nb);
+ sz += sizeof *a + pool->mask; /* header and alignment slop */
+ a = (PLArena*)PR_MALLOC(sz);
+ if ( NULL != a ) {
+ a->limit = (PRUword)a + sz;
+ a->base = a->avail = (PRUword)PL_ARENA_ALIGN(pool, a + 1);
+ rp = (char *)a->avail;
+ a->avail += nb;
+ PR_ASSERT(a->avail <= a->limit);
+ /* the newly allocated arena is linked after pool->current
+ * and becomes pool->current */
+ a->next = pool->current->next;
+ pool->current->next = a;
+ pool->current = a;
+ if ( NULL == pool->first.next )
+ pool->first.next = a;
+ PL_COUNT_ARENA(pool,++);
+ COUNT(pool, nmallocs);
+ return(rp);
+ }
+ }
+
+ /* we got to here, and there's no memory to allocate */
+ return(NULL);
+} /* --- end PL_ArenaAllocate() --- */
+
+PR_IMPLEMENT(void *) PL_ArenaGrow(
+ PLArenaPool *pool, void *p, PRUint32 size, PRUint32 incr)
+{
+ void *newp;
+
+ if (PR_UINT32_MAX - size < incr)
+ return NULL;
+ PL_ARENA_ALLOCATE(newp, pool, size + incr);
+ if (newp)
+ memcpy(newp, p, size);
+ return newp;
+}
+
+/*
+ * Free tail arenas linked after head, which may not be the true list head.
+ * Reset pool->current to point to head in case it pointed at a tail arena.
+ */
+static void FreeArenaList(PLArenaPool *pool, PLArena *head, PRBool reallyFree)
+{
+ PLArena **ap, *a;
+
+ ap = &head->next;
+ a = *ap;
+ if (!a)
+ return;
+
+#ifdef DEBUG
+ do {
+ PR_ASSERT(a->base <= a->avail && a->avail <= a->limit);
+ a->avail = a->base;
+ PL_CLEAR_UNUSED(a);
+ } while ((a = a->next) != 0);
+ a = *ap;
+#endif
+
+ if (reallyFree) {
+ do {
+ *ap = a->next;
+ PL_CLEAR_ARENA(a);
+ PL_COUNT_ARENA(pool,--);
+ PR_DELETE(a);
+ } while ((a = *ap) != 0);
+ } else {
+ /* Insert the whole arena chain at the front of the freelist. */
+ do {
+ ap = &(*ap)->next;
+ } while (*ap);
+ LockArena();
+ *ap = arena_freelist;
+ arena_freelist = a;
+ head->next = 0;
+ UnlockArena();
+ }
+
+ pool->current = head;
+}
+
+PR_IMPLEMENT(void) PL_ArenaRelease(PLArenaPool *pool, char *mark)
+{
+ PLArena *a;
+
+ for (a = pool->first.next; a; a = a->next) {
+ if (PR_UPTRDIFF(mark, a->base) < PR_UPTRDIFF(a->avail, a->base)) {
+ a->avail = (PRUword)PL_ARENA_ALIGN(pool, mark);
+ FreeArenaList(pool, a, PR_FALSE);
+ return;
+ }
+ }
+}
+
+PR_IMPLEMENT(void) PL_FreeArenaPool(PLArenaPool *pool)
+{
+ FreeArenaList(pool, &pool->first, PR_FALSE);
+ COUNT(pool, ndeallocs);
+}
+
+PR_IMPLEMENT(void) PL_FinishArenaPool(PLArenaPool *pool)
+{
+ FreeArenaList(pool, &pool->first, PR_TRUE);
+#ifdef PL_ARENAMETER
+ {
+ PLArenaStats *stats, **statsp;
+
+ if (pool->stats.name)
+ PR_DELETE(pool->stats.name);
+ for (statsp = &arena_stats_list; (stats = *statsp) != 0;
+ statsp = &stats->next) {
+ if (stats == &pool->stats) {
+ *statsp = stats->next;
+ return;
+ }
+ }
+ }
+#endif
+}
+
+PR_IMPLEMENT(void) PL_CompactArenaPool(PLArenaPool *ap)
+{
+#if XP_MAC
+#pragma unused (ap)
+#if 0
+ PRArena *curr = &(ap->first);
+ while (curr) {
+ reallocSmaller(curr, curr->avail - (uprword_t)curr);
+ curr->limit = curr->avail;
+ curr = curr->next;
+ }
+#endif
+#endif
+}
+
+PR_IMPLEMENT(void) PL_ArenaFinish(void)
+{
+ PLArena *a, *next;
+
+ for (a = arena_freelist; a; a = next) {
+ next = a->next;
+ PR_DELETE(a);
+ }
+ arena_freelist = NULL;
+
+ if (arenaLock) {
+ PR_DestroyLock(arenaLock);
+ arenaLock = NULL;
+ }
+}
+
+#ifdef PL_ARENAMETER
+PR_IMPLEMENT(void) PL_ArenaCountAllocation(PLArenaPool *pool, PRUint32 nb)
+{
+ pool->stats.nallocs++;
+ pool->stats.nbytes += nb;
+ if (nb > pool->stats.maxalloc)
+ pool->stats.maxalloc = nb;
+ pool->stats.variance += nb * nb;
+}
+
+PR_IMPLEMENT(void) PL_ArenaCountInplaceGrowth(
+ PLArenaPool *pool, PRUint32 size, PRUint32 incr)
+{
+ pool->stats.ninplace++;
+}
+
+PR_IMPLEMENT(void) PL_ArenaCountGrowth(
+ PLArenaPool *pool, PRUint32 size, PRUint32 incr)
+{
+ pool->stats.ngrows++;
+ pool->stats.nbytes += incr;
+ pool->stats.variance -= size * size;
+ size += incr;
+ if (size > pool->stats.maxalloc)
+ pool->stats.maxalloc = size;
+ pool->stats.variance += size * size;
+}
+
+PR_IMPLEMENT(void) PL_ArenaCountRelease(PLArenaPool *pool, char *mark)
+{
+ pool->stats.nreleases++;
+}
+
+PR_IMPLEMENT(void) PL_ArenaCountRetract(PLArenaPool *pool, char *mark)
+{
+ pool->stats.nfastrels++;
+}
+
+#include <math.h>
+#include <stdio.h>
+
+PR_IMPLEMENT(void) PL_DumpArenaStats(FILE *fp)
+{
+ PLArenaStats *stats;
+ double mean, variance;
+
+ for (stats = arena_stats_list; stats; stats = stats->next) {
+ if (stats->nallocs != 0) {
+ mean = (double)stats->nbytes / stats->nallocs;
+ variance = fabs(stats->variance / stats->nallocs - mean * mean);
+ } else {
+ mean = variance = 0;
+ }
+
+ fprintf(fp, "\n%s allocation statistics:\n", stats->name);
+ fprintf(fp, " number of arenas: %u\n", stats->narenas);
+ fprintf(fp, " number of allocations: %u\n", stats->nallocs);
+ fprintf(fp, " number of free arena reclaims: %u\n", stats->nreclaims);
+ fprintf(fp, " number of malloc calls: %u\n", stats->nmallocs);
+ fprintf(fp, " number of deallocations: %u\n", stats->ndeallocs);
+ fprintf(fp, " number of allocation growths: %u\n", stats->ngrows);
+ fprintf(fp, " number of in-place growths: %u\n", stats->ninplace);
+ fprintf(fp, "number of released allocations: %u\n", stats->nreleases);
+ fprintf(fp, " number of fast releases: %u\n", stats->nfastrels);
+ fprintf(fp, " total bytes allocated: %u\n", stats->nbytes);
+ fprintf(fp, " mean allocation size: %g\n", mean);
+ fprintf(fp, " standard deviation: %g\n", sqrt(variance));
+ fprintf(fp, " maximum allocation size: %u\n", stats->maxalloc);
+ }
+}
+#endif /* PL_ARENAMETER */
diff --git a/src/libs/xpcom18a4/nsprpub/lib/ds/plarena.h b/src/libs/xpcom18a4/nsprpub/lib/ds/plarena.h
new file mode 100644
index 00000000..174bd975
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/ds/plarena.h
@@ -0,0 +1,219 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1998-2000 Netscape Communications Corporation. 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK *****
+ */
+
+#ifndef plarena_h___
+#define plarena_h___
+/*
+ * Lifetime-based fast allocation, inspired by much prior art, including
+ * "Fast Allocation and Deallocation of Memory Based on Object Lifetimes"
+ * David R. Hanson, Software -- Practice and Experience, Vol. 20(1).
+ *
+ * Also supports LIFO allocation (PL_ARENA_MARK/PL_ARENA_RELEASE).
+ */
+#include "prtypes.h"
+#include "plarenas.h"
+
+PR_BEGIN_EXTERN_C
+
+typedef struct PLArena PLArena;
+
+struct PLArena {
+ PLArena *next; /* next arena for this lifetime */
+ PRUword base; /* aligned base address, follows this header */
+ PRUword limit; /* one beyond last byte in arena */
+ PRUword avail; /* points to next available byte */
+};
+
+#ifdef PL_ARENAMETER
+typedef struct PLArenaStats PLArenaStats;
+
+struct PLArenaStats {
+ PLArenaStats *next; /* next in arenaStats list */
+ char *name; /* name for debugging */
+ PRUint32 narenas; /* number of arenas in pool */
+ PRUint32 nallocs; /* number of PL_ARENA_ALLOCATE() calls */
+ PRUint32 nreclaims; /* number of reclaims from freeArenas */
+ PRUint32 nmallocs; /* number of malloc() calls */
+ PRUint32 ndeallocs; /* number of lifetime deallocations */
+ PRUint32 ngrows; /* number of PL_ARENA_GROW() calls */
+ PRUint32 ninplace; /* number of in-place growths */
+ PRUint32 nreleases; /* number of PL_ARENA_RELEASE() calls */
+ PRUint32 nfastrels; /* number of "fast path" releases */
+ PRUint32 nbytes; /* total bytes allocated */
+ PRUint32 maxalloc; /* maximum allocation size in bytes */
+ PRFloat64 variance; /* size variance accumulator */
+};
+#endif
+
+struct PLArenaPool {
+ PLArena first; /* first arena in pool list */
+ PLArena *current; /* arena from which to allocate space */
+ PRUint32 arenasize; /* net exact size of a new arena */
+ PRUword mask; /* alignment mask (power-of-2 - 1) */
+#ifdef PL_ARENAMETER
+ PLArenaStats stats;
+#endif
+};
+
+/*
+ * If the including .c file uses only one power-of-2 alignment, it may define
+ * PL_ARENA_CONST_ALIGN_MASK to the alignment mask and save a few instructions
+ * per ALLOCATE and GROW.
+ */
+#ifdef PL_ARENA_CONST_ALIGN_MASK
+#define PL_ARENA_ALIGN(pool, n) (((PRUword)(n) + PL_ARENA_CONST_ALIGN_MASK) \
+ & ~PL_ARENA_CONST_ALIGN_MASK)
+
+#define PL_INIT_ARENA_POOL(pool, name, size) \
+ PL_InitArenaPool(pool, name, size, PL_ARENA_CONST_ALIGN_MASK + 1)
+#else
+#define PL_ARENA_ALIGN(pool, n) (((PRUword)(n) + (pool)->mask) & ~(pool)->mask)
+#endif
+
+#define PL_ARENA_ALLOCATE(p, pool, nb) \
+ PR_BEGIN_MACRO \
+ PLArena *_a = (pool)->current; \
+ PRUint32 _nb = PL_ARENA_ALIGN(pool, (PRUint32)nb); \
+ PRUword _p = _a->avail; \
+ if (_nb < (PRUint32)nb) { \
+ _p = 0; \
+ } else if (_nb > (_a->limit - _a->avail)) { \
+ _p = (PRUword)PL_ArenaAllocate(pool, _nb); \
+ } else { \
+ _a->avail += _nb; \
+ } \
+ p = (void *)_p; \
+ if (p) { \
+ PL_ArenaCountAllocation(pool, nb); \
+ } \
+ PR_END_MACRO
+
+#define PL_ARENA_GROW(p, pool, size, incr) \
+ PR_BEGIN_MACRO \
+ PLArena *_a = (pool)->current; \
+ PRUint32 _incr = PL_ARENA_ALIGN(pool, (PRUint32)incr); \
+ if (_incr < (PRUint32)incr) { \
+ p = NULL; \
+ } else if (_a->avail == (PRUword)(p) + PL_ARENA_ALIGN(pool, size) && \
+ _incr <= (_a->limit - _a->avail)) { \
+ _a->avail = _incr; \
+ PL_ArenaCountInplaceGrowth(pool, size, (RTUint32)incr); \
+ } else { \
+ p = PL_ArenaGrow(pool, p, size, (PRUint32)incr); \
+ } \
+ if (p) { \
+ PL_ArenaCountGrowth(pool, size, (PRUint32)incr); \
+ } \
+ PR_END_MACRO
+
+#define PL_ARENA_MARK(pool) ((void *) (pool)->current->avail)
+#define PR_UPTRDIFF(p,q) ((PRUword)(p) - (PRUword)(q))
+
+#ifdef DEBUG
+#define PL_FREE_PATTERN 0xDA
+#define PL_CLEAR_UNUSED(a) (PR_ASSERT((a)->avail <= (a)->limit), \
+ memset((void*)(a)->avail, PL_FREE_PATTERN, \
+ (a)->limit - (a)->avail))
+#define PL_CLEAR_ARENA(a) memset((void*)(a), PL_FREE_PATTERN, \
+ (a)->limit - (PRUword)(a))
+#else
+#define PL_CLEAR_UNUSED(a)
+#define PL_CLEAR_ARENA(a)
+#endif
+
+#define PL_ARENA_RELEASE(pool, mark) \
+ PR_BEGIN_MACRO \
+ char *_m = (char *)(mark); \
+ PLArena *_a = (pool)->current; \
+ if (PR_UPTRDIFF(_m, _a->base) <= PR_UPTRDIFF(_a->avail, _a->base)) { \
+ _a->avail = (PRUword)PL_ARENA_ALIGN(pool, _m); \
+ PL_CLEAR_UNUSED(_a); \
+ PL_ArenaCountRetract(pool, _m); \
+ } else { \
+ PL_ArenaRelease(pool, _m); \
+ } \
+ PL_ArenaCountRelease(pool, _m); \
+ PR_END_MACRO
+
+#ifdef PL_ARENAMETER
+#define PL_COUNT_ARENA(pool,op) ((pool)->stats.narenas op)
+#else
+#define PL_COUNT_ARENA(pool,op)
+#endif
+
+#define PL_ARENA_DESTROY(pool, a, pnext) \
+ PR_BEGIN_MACRO \
+ PL_COUNT_ARENA(pool,--); \
+ if ((pool)->current == (a)) (pool)->current = &(pool)->first; \
+ *(pnext) = (a)->next; \
+ PL_CLEAR_ARENA(a); \
+ free(a); \
+ (a) = 0; \
+ PR_END_MACRO
+
+#ifdef PL_ARENAMETER
+
+#include <stdio.h>
+
+PR_EXTERN(void) PL_ArenaCountAllocation(PLArenaPool *pool, PRUint32 nb);
+
+PR_EXTERN(void) PL_ArenaCountInplaceGrowth(
+ PLArenaPool *pool, PRUint32 size, PRUint32 incr);
+
+PR_EXTERN(void) PL_ArenaCountGrowth(
+ PLArenaPool *pool, PRUint32 size, PRUint32 incr);
+
+PR_EXTERN(void) PL_ArenaCountRelease(PLArenaPool *pool, char *mark);
+
+PR_EXTERN(void) PL_ArenaCountRetract(PLArenaPool *pool, char *mark);
+
+PR_EXTERN(void) PL_DumpArenaStats(FILE *fp);
+
+#else /* !PL_ARENAMETER */
+
+#define PL_ArenaCountAllocation(ap, nb) /* nothing */
+#define PL_ArenaCountInplaceGrowth(ap, size, incr) /* nothing */
+#define PL_ArenaCountGrowth(ap, size, incr) /* nothing */
+#define PL_ArenaCountRelease(ap, mark) /* nothing */
+#define PL_ArenaCountRetract(ap, mark) /* nothing */
+
+#endif /* !PL_ARENAMETER */
+
+PR_END_EXTERN_C
+
+#endif /* plarena_h___ */
diff --git a/src/libs/xpcom18a4/nsprpub/lib/ds/plarenas.h b/src/libs/xpcom18a4/nsprpub/lib/ds/plarenas.h
new file mode 100644
index 00000000..8e8a1137
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/ds/plarenas.h
@@ -0,0 +1,126 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#if defined(PLARENAS_H)
+#else /* defined(PLARENAS_H) */
+#define PLARENAS_H
+
+#ifdef VBOX_WITH_XPCOM_NAMESPACE_CLEANUP
+#define PL_ArenaAllocate VBoxNsplPL_ArenaAllocate
+#define PL_ArenaFinish VBoxNsplPL_ArenaFinish
+#define PL_ArenaGrow VBoxNsplPL_ArenaGrow
+#define PL_ArenaRelease VBoxNsplPL_ArenaRelease
+#define PL_CompactArenaPool VBoxNsplPL_CompactArenaPool
+#define PL_FinishArenaPool VBoxNsplPL_FinishArenaPool
+#define PL_FreeArenaPool VBoxNsplPL_FreeArenaPool
+#define PL_InitArenaPool VBoxNsplPL_InitArenaPool
+#endif /* VBOX_WITH_XPCOM_NAMESPACE_CLEANUP */
+
+PR_BEGIN_EXTERN_C
+
+typedef struct PLArenaPool PLArenaPool;
+
+/*
+** Allocate an arena pool as specified by the parameters.
+**
+** This is equivelant to allocating the space yourself and then
+** calling PL_InitArenaPool().
+**
+** This function may fail (and return a NULL) for a variety of
+** reasons. The reason for a particular failure can be discovered
+** by calling PR_GetError().
+*/
+#if 0 /* Not implemented */
+PR_EXTERN(PLArenaPool*) PL_AllocArenaPool(
+ const char *name, PRUint32 size, PRUint32 align);
+#endif
+
+/*
+** Destroy an arena pool previously allocated by PL_AllocArenaPool().
+**
+** This function may fail if the arena is not empty and the caller
+** wishes to check for empty upon descruction.
+*/
+#if 0 /* Not implemented */
+PR_EXTERN(PRStatus) PL_DestroyArenaPool(PLArenaPool *pool, PRBool checkEmpty);
+#endif
+
+
+/*
+** Initialize an arena pool with the given name for debugging and metering,
+** with a minimum size per arena of size bytes.
+**/
+PR_EXTERN(void) PL_InitArenaPool(
+ PLArenaPool *pool, const char *name, PRUint32 size, PRUint32 align);
+
+/*
+** Finish using arenas, freeing all memory associated with them.
+**/
+PR_EXTERN(void) PL_ArenaFinish(void);
+
+/*
+** Free the arenas in pool. The user may continue to allocate from pool
+** after calling this function. There is no need to call PL_InitArenaPool()
+** again unless PL_FinishArenaPool(pool) has been called.
+**/
+PR_EXTERN(void) PL_FreeArenaPool(PLArenaPool *pool);
+
+/*
+** Free the arenas in pool and finish using it altogether.
+**/
+PR_EXTERN(void) PL_FinishArenaPool(PLArenaPool *pool);
+
+/*
+** Compact all of the arenas in a pool so that no space is wasted.
+**/
+PR_EXTERN(void) PL_CompactArenaPool(PLArenaPool *pool);
+
+/*
+** Friend functions used by the PL_ARENA_*() macros.
+**/
+PR_EXTERN(void *) PL_ArenaAllocate(PLArenaPool *pool, PRUint32 nb);
+
+PR_EXTERN(void *) PL_ArenaGrow(
+ PLArenaPool *pool, void *p, PRUint32 size, PRUint32 incr);
+
+PR_EXTERN(void) PL_ArenaRelease(PLArenaPool *pool, char *mark);
+
+PR_END_EXTERN_C
+
+#endif /* defined(PLARENAS_H) */
+
+/* plarenas */
diff --git a/src/libs/xpcom18a4/nsprpub/lib/ds/plds.def b/src/libs/xpcom18a4/nsprpub/lib/ds/plds.def
new file mode 100644
index 00000000..9e0b505a
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/ds/plds.def
@@ -0,0 +1,78 @@
+;+#
+;+# 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 the Netscape Portable Runtime (NSPR).
+;+#
+;+# The Initial Developer of the Original Code is Netscape
+;+# Communications Corporation. Portions created by Netscape are
+;+# Copyright (C) 2002-2003 Netscape Communications Corporation. All
+;+# Rights Reserved.
+;+#
+;+# Contributor(s):
+;+#
+;+# Alternatively, the contents of this file may be used under the
+;+# terms of the GNU General Public License Version 2 or later (the
+;+# "GPL"), in which case the provisions of the GPL are applicable
+;+# instead of those above. If you wish to allow use of your
+;+# version of this file only under the terms of the GPL and not to
+;+# allow others to use your version of this file under the MPL,
+;+# indicate your decision by deleting the provisions above and
+;+# replace them with the notice and other provisions required by
+;+# the GPL. If you do not delete the provisions above, a recipient
+;+# may use your version of this file under either the MPL or the
+;+# GPL.
+;+#
+;+# OK, this file is meant to support SUN, LINUX, AIX, OS/2 and WINDOWS
+;+# 1. For all unix platforms, the string ";-" means "remove this line"
+;+# 2. For all unix platforms, the string " DATA " will be removed from any
+;+# line on which it occurs.
+;+# 3. Lines containing ";+" will have ";+" removed on SUN and LINUX.
+;+# On AIX, lines containing ";+" will be removed.
+;+# 4. For all unix platforms, the string ";;" will thave the ";;" removed.
+;+# 5. For all unix platforms, after the above processing has taken place,
+;+# all characters after the first ";" on the line will be removed.
+;+# And for AIX, the first ";" will also be removed.
+;+# This file is passed directly to windows. Since ';' is a comment, all UNIX
+;+# directives are hidden behind ";", ";+", and ";-"
+;+NSPR_4.0 {
+;+ global:
+LIBRARY plds4 ;-
+EXPORTS ;-
+PL_ArenaAllocate;
+PL_ArenaFinish;
+PL_ArenaGrow;
+PL_ArenaRelease;
+PL_CompactArenaPool;
+PL_CompareStrings;
+PL_CompareValues;
+PL_FinishArenaPool;
+PL_FreeArenaPool;
+PL_HashString;
+PL_HashTableAdd;
+PL_HashTableDestroy;
+PL_HashTableDump;
+PL_HashTableEnumerateEntries;
+PL_HashTableLookup;
+PL_HashTableRawAdd;
+PL_HashTableRawLookup;
+PL_HashTableRawRemove;
+PL_HashTableRemove;
+PL_InitArenaPool;
+PL_NewHashTable;
+libVersionPoint;
+;+ local: *;
+;+};
+;+
+;+NSPR_4.1 {
+;+ global:
+PL_HashTableLookupConst;
+PL_HashTableRawLookupConst;
+;+} NSPR_4.0;
diff --git a/src/libs/xpcom18a4/nsprpub/lib/ds/plds.rc b/src/libs/xpcom18a4/nsprpub/lib/ds/plds.rc
new file mode 100644
index 00000000..fa64e192
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/ds/plds.rc
@@ -0,0 +1,102 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "prinit.h"
+#include <winver.h>
+
+#define MY_LIBNAME "plds"
+#define MY_FILEDESCRIPTION "PLDS Library"
+
+#define STRINGIZE(x) #x
+#define STRINGIZE2(x) STRINGIZE(x)
+#define PR_VMAJOR_STR STRINGIZE2(PR_VMAJOR)
+
+#ifdef _DEBUG
+#define MY_DEBUG_STR " (debug)"
+#define MY_FILEFLAGS_1 VS_FF_DEBUG
+#else
+#define MY_DEBUG_STR ""
+#define MY_FILEFLAGS_1 0x0L
+#endif
+#if PR_BETA
+#define MY_FILEFLAGS_2 MY_FILEFLAGS_1|VS_FF_PRERELEASE
+#else
+#define MY_FILEFLAGS_2 MY_FILEFLAGS_1
+#endif
+
+#ifdef WINNT
+#define MY_FILEOS VOS_NT_WINDOWS32
+#define MY_INTERNAL_NAME "lib" MY_LIBNAME PR_VMAJOR_STR
+#else
+#define MY_FILEOS VOS__WINDOWS32
+#define MY_INTERNAL_NAME MY_LIBNAME PR_VMAJOR_STR
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version-information resource
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION PR_VMAJOR,PR_VMINOR,PR_VPATCH,0
+ PRODUCTVERSION PR_VMAJOR,PR_VMINOR,PR_VPATCH,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS MY_FILEFLAGS_2
+ FILEOS MY_FILEOS
+ FILETYPE VFT_DLL
+ FILESUBTYPE 0x0L // not used
+
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904B0" // Lang=US English, CharSet=Unicode
+ BEGIN
+ VALUE "CompanyName", "Netscape Communications Corporation\0"
+ VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0"
+ VALUE "FileVersion", PR_VERSION "\0"
+ VALUE "InternalName", MY_INTERNAL_NAME "\0"
+ VALUE "LegalCopyright", "Copyright \251 1996-2000 Netscape Communications Corporation\0"
+ VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0"
+ VALUE "ProductName", "Netscape Portable Runtime\0"
+ VALUE "ProductVersion", PR_VERSION "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/src/libs/xpcom18a4/nsprpub/lib/ds/plds_symvec.opt b/src/libs/xpcom18a4/nsprpub/lib/ds/plds_symvec.opt
new file mode 100644
index 00000000..71784540
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/ds/plds_symvec.opt
@@ -0,0 +1,37 @@
+! Fixed section of symbol vector for LIBPLDS4
+!
+GSMATCH=LEQUAL,2,2
+case_sensitive=YES
+!
+! --------------------------------------------------------------------------
+! Ident 2,2 introduced for Mozilla 1.3
+! Previously this was empty. Now we include everything that's specified in
+! plds.def.
+! --------------------------------------------------------------------------
+!
+! NSPR 4.0
+SYMBOL_VECTOR=(PL_ArenaAllocate=PROCEDURE)
+SYMBOL_VECTOR=(PL_ArenaFinish=PROCEDURE)
+SYMBOL_VECTOR=(PL_ArenaGrow=PROCEDURE)
+SYMBOL_VECTOR=(PL_ArenaRelease=PROCEDURE)
+SYMBOL_VECTOR=(PL_CompactArenaPool=PROCEDURE)
+SYMBOL_VECTOR=(PL_CompareStrings=PROCEDURE)
+SYMBOL_VECTOR=(PL_CompareValues=PROCEDURE)
+SYMBOL_VECTOR=(PL_FinishArenaPool=PROCEDURE)
+SYMBOL_VECTOR=(PL_FreeArenaPool=PROCEDURE)
+SYMBOL_VECTOR=(PL_HashString=PROCEDURE)
+SYMBOL_VECTOR=(PL_HashTableAdd=PROCEDURE)
+SYMBOL_VECTOR=(PL_HashTableDestroy=PROCEDURE)
+SYMBOL_VECTOR=(PL_HashTableDump=PROCEDURE)
+SYMBOL_VECTOR=(PL_HashTableEnumerateEntries=PROCEDURE)
+SYMBOL_VECTOR=(PL_HashTableLookup=PROCEDURE)
+SYMBOL_VECTOR=(PL_HashTableRawAdd=PROCEDURE)
+SYMBOL_VECTOR=(PL_HashTableRawLookup=PROCEDURE)
+SYMBOL_VECTOR=(PL_HashTableRawRemove=PROCEDURE)
+SYMBOL_VECTOR=(PL_HashTableRemove=PROCEDURE)
+SYMBOL_VECTOR=(PL_InitArenaPool=PROCEDURE)
+SYMBOL_VECTOR=(PL_NewHashTable=PROCEDURE)
+SYMBOL_VECTOR=(libVersionPoint=PROCEDURE)
+! NSPR 4.1
+SYMBOL_VECTOR=(PL_HashTableLookupConst=PROCEDURE)
+SYMBOL_VECTOR=(PL_HashTableRawLookupConst=PROCEDURE)
diff --git a/src/libs/xpcom18a4/nsprpub/lib/ds/plhash.c b/src/libs/xpcom18a4/nsprpub/lib/ds/plhash.c
new file mode 100644
index 00000000..98ce5959
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/ds/plhash.c
@@ -0,0 +1,541 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * PL hash table package.
+ */
+#include "plhash.h"
+#include "prbit.h"
+#include "prlog.h"
+#include "prmem.h"
+#include "prtypes.h"
+#include <stdlib.h>
+#include <string.h>
+
+/* Compute the number of buckets in ht */
+#define NBUCKETS(ht) (1 << (PL_HASH_BITS - (ht)->shift))
+
+/* The smallest table has 16 buckets */
+#define MINBUCKETSLOG2 4
+#define MINBUCKETS (1 << MINBUCKETSLOG2)
+
+/* Compute the maximum entries given n buckets that we will tolerate, ~90% */
+#define OVERLOADED(n) ((n) - ((n) >> 3))
+
+/* Compute the number of entries below which we shrink the table by half */
+#define UNDERLOADED(n) (((n) > MINBUCKETS) ? ((n) >> 2) : 0)
+
+/*
+** Stubs for default hash allocator ops.
+*/
+static void * PR_CALLBACK
+DefaultAllocTable(void *pool, PRSize size)
+{
+#if defined(XP_MAC)
+#pragma unused (pool)
+#endif
+
+ return PR_MALLOC(size);
+}
+
+static void PR_CALLBACK
+DefaultFreeTable(void *pool, void *item)
+{
+#if defined(XP_MAC)
+#pragma unused (pool)
+#endif
+
+ PR_Free(item);
+}
+
+static PLHashEntry * PR_CALLBACK
+DefaultAllocEntry(void *pool, const void *key)
+{
+#if defined(XP_MAC)
+#pragma unused (pool,key)
+#endif
+
+ return PR_NEW(PLHashEntry);
+}
+
+static void PR_CALLBACK
+DefaultFreeEntry(void *pool, PLHashEntry *he, PRUintn flag)
+{
+#if defined(XP_MAC)
+#pragma unused (pool)
+#endif
+
+ if (flag == HT_FREE_ENTRY)
+ PR_Free(he);
+}
+
+static PLHashAllocOps defaultHashAllocOps = {
+ DefaultAllocTable, DefaultFreeTable,
+ DefaultAllocEntry, DefaultFreeEntry
+};
+
+PR_IMPLEMENT(PLHashTable *)
+PL_NewHashTable(PRUint32 n, PLHashFunction keyHash,
+ PLHashComparator keyCompare, PLHashComparator valueCompare,
+ const PLHashAllocOps *allocOps, void *allocPriv)
+{
+ PLHashTable *ht;
+ PRSize nb;
+
+ if (n <= MINBUCKETS) {
+ n = MINBUCKETSLOG2;
+ } else {
+ n = PR_CeilingLog2(n);
+ if ((PRInt32)n < 0)
+ return 0;
+ }
+
+ if (!allocOps) allocOps = &defaultHashAllocOps;
+
+ ht = (PLHashTable*)((*allocOps->allocTable)(allocPriv, sizeof *ht));
+ if (!ht)
+ return 0;
+ memset(ht, 0, sizeof *ht);
+ ht->shift = PL_HASH_BITS - n;
+ n = 1 << n;
+#if defined(WIN16)
+ if (n > 16000) {
+ (*allocOps->freeTable)(allocPriv, ht);
+ return 0;
+ }
+#endif /* WIN16 */
+ nb = n * sizeof(PLHashEntry *);
+ ht->buckets = (PLHashEntry**)((*allocOps->allocTable)(allocPriv, nb));
+ if (!ht->buckets) {
+ (*allocOps->freeTable)(allocPriv, ht);
+ return 0;
+ }
+ memset(ht->buckets, 0, nb);
+
+ ht->keyHash = keyHash;
+ ht->keyCompare = keyCompare;
+ ht->valueCompare = valueCompare;
+ ht->allocOps = allocOps;
+ ht->allocPriv = allocPriv;
+ return ht;
+}
+
+PR_IMPLEMENT(void)
+PL_HashTableDestroy(PLHashTable *ht)
+{
+ PRUint32 i, n;
+ PLHashEntry *he, *next;
+ const PLHashAllocOps *allocOps = ht->allocOps;
+ void *allocPriv = ht->allocPriv;
+
+ n = NBUCKETS(ht);
+ for (i = 0; i < n; i++) {
+ for (he = ht->buckets[i]; he; he = next) {
+ next = he->next;
+ (*allocOps->freeEntry)(allocPriv, he, HT_FREE_ENTRY);
+ }
+ }
+#ifdef DEBUG
+ memset(ht->buckets, 0xDB, n * sizeof ht->buckets[0]);
+#endif
+ (*allocOps->freeTable)(allocPriv, ht->buckets);
+#ifdef DEBUG
+ memset(ht, 0xDB, sizeof *ht);
+#endif
+ (*allocOps->freeTable)(allocPriv, ht);
+}
+
+/*
+** Multiplicative hash, from Knuth 6.4.
+*/
+#define GOLDEN_RATIO 0x9E3779B9U /* 2/(1+sqrt(5))*(2^32) */
+
+PR_IMPLEMENT(PLHashEntry **)
+PL_HashTableRawLookup(PLHashTable *ht, PLHashNumber keyHash, const void *key)
+{
+ PLHashEntry *he, **hep, **hep0;
+ PLHashNumber h;
+
+#ifdef HASHMETER
+ ht->nlookups++;
+#endif
+ h = keyHash * GOLDEN_RATIO;
+ h >>= ht->shift;
+ hep = hep0 = &ht->buckets[h];
+ while ((he = *hep) != 0) {
+ if (he->keyHash == keyHash && (*ht->keyCompare)(key, he->key)) {
+ /* Move to front of chain if not already there */
+ if (hep != hep0) {
+ *hep = he->next;
+ he->next = *hep0;
+ *hep0 = he;
+ }
+ return hep0;
+ }
+ hep = &he->next;
+#ifdef HASHMETER
+ ht->nsteps++;
+#endif
+ }
+ return hep;
+}
+
+/*
+** Same as PL_HashTableRawLookup but doesn't reorder the hash entries.
+*/
+PR_IMPLEMENT(PLHashEntry **)
+PL_HashTableRawLookupConst(PLHashTable *ht, PLHashNumber keyHash,
+ const void *key)
+{
+ PLHashEntry *he, **hep;
+ PLHashNumber h;
+
+#ifdef HASHMETER
+ ht->nlookups++;
+#endif
+ h = keyHash * GOLDEN_RATIO;
+ h >>= ht->shift;
+ hep = &ht->buckets[h];
+ while ((he = *hep) != 0) {
+ if (he->keyHash == keyHash && (*ht->keyCompare)(key, he->key)) {
+ break;
+ }
+ hep = &he->next;
+#ifdef HASHMETER
+ ht->nsteps++;
+#endif
+ }
+ return hep;
+}
+
+PR_IMPLEMENT(PLHashEntry *)
+PL_HashTableRawAdd(PLHashTable *ht, PLHashEntry **hep,
+ PLHashNumber keyHash, const void *key, void *value)
+{
+ PRUint32 i, n;
+ PLHashEntry *he, *next, **oldbuckets;
+ PRSize nb;
+
+ /* Grow the table if it is overloaded */
+ n = NBUCKETS(ht);
+ if (ht->nentries >= OVERLOADED(n)) {
+ oldbuckets = ht->buckets;
+#if defined(WIN16)
+ if (2 * n > 16000)
+ return 0;
+#endif /* WIN16 */
+ nb = 2 * n * sizeof(PLHashEntry *);
+ ht->buckets = (PLHashEntry**)
+ ((*ht->allocOps->allocTable)(ht->allocPriv, nb));
+ if (!ht->buckets) {
+ ht->buckets = oldbuckets;
+ return 0;
+ }
+ memset(ht->buckets, 0, nb);
+#ifdef HASHMETER
+ ht->ngrows++;
+#endif
+ ht->shift--;
+
+ for (i = 0; i < n; i++) {
+ for (he = oldbuckets[i]; he; he = next) {
+ next = he->next;
+ hep = PL_HashTableRawLookup(ht, he->keyHash, he->key);
+ PR_ASSERT(*hep == 0);
+ he->next = 0;
+ *hep = he;
+ }
+ }
+#ifdef DEBUG
+ memset(oldbuckets, 0xDB, n * sizeof oldbuckets[0]);
+#endif
+ (*ht->allocOps->freeTable)(ht->allocPriv, oldbuckets);
+ hep = PL_HashTableRawLookup(ht, keyHash, key);
+ }
+
+ /* Make a new key value entry */
+ he = (*ht->allocOps->allocEntry)(ht->allocPriv, key);
+ if (!he)
+ return 0;
+ he->keyHash = keyHash;
+ he->key = key;
+ he->value = value;
+ he->next = *hep;
+ *hep = he;
+ ht->nentries++;
+ return he;
+}
+
+PR_IMPLEMENT(PLHashEntry *)
+PL_HashTableAdd(PLHashTable *ht, const void *key, void *value)
+{
+ PLHashNumber keyHash;
+ PLHashEntry *he, **hep;
+
+ keyHash = (*ht->keyHash)(key);
+ hep = PL_HashTableRawLookup(ht, keyHash, key);
+ if ((he = *hep) != 0) {
+ /* Hit; see if values match */
+ if ((*ht->valueCompare)(he->value, value)) {
+ /* key,value pair is already present in table */
+ return he;
+ }
+ if (he->value)
+ (*ht->allocOps->freeEntry)(ht->allocPriv, he, HT_FREE_VALUE);
+ he->value = value;
+ return he;
+ }
+ return PL_HashTableRawAdd(ht, hep, keyHash, key, value);
+}
+
+PR_IMPLEMENT(void)
+PL_HashTableRawRemove(PLHashTable *ht, PLHashEntry **hep, PLHashEntry *he)
+{
+ PRUint32 i, n;
+ PLHashEntry *next, **oldbuckets;
+ PRSize nb;
+
+ *hep = he->next;
+ (*ht->allocOps->freeEntry)(ht->allocPriv, he, HT_FREE_ENTRY);
+
+ /* Shrink table if it's underloaded */
+ n = NBUCKETS(ht);
+ if (--ht->nentries < UNDERLOADED(n)) {
+ oldbuckets = ht->buckets;
+ nb = n * sizeof(PLHashEntry*) / 2;
+ ht->buckets = (PLHashEntry**)(
+ (*ht->allocOps->allocTable)(ht->allocPriv, nb));
+ if (!ht->buckets) {
+ ht->buckets = oldbuckets;
+ return;
+ }
+ memset(ht->buckets, 0, nb);
+#ifdef HASHMETER
+ ht->nshrinks++;
+#endif
+ ht->shift++;
+
+ for (i = 0; i < n; i++) {
+ for (he = oldbuckets[i]; he; he = next) {
+ next = he->next;
+ hep = PL_HashTableRawLookup(ht, he->keyHash, he->key);
+ PR_ASSERT(*hep == 0);
+ he->next = 0;
+ *hep = he;
+ }
+ }
+#ifdef DEBUG
+ memset(oldbuckets, 0xDB, n * sizeof oldbuckets[0]);
+#endif
+ (*ht->allocOps->freeTable)(ht->allocPriv, oldbuckets);
+ }
+}
+
+PR_IMPLEMENT(PRBool)
+PL_HashTableRemove(PLHashTable *ht, const void *key)
+{
+ PLHashNumber keyHash;
+ PLHashEntry *he, **hep;
+
+ keyHash = (*ht->keyHash)(key);
+ hep = PL_HashTableRawLookup(ht, keyHash, key);
+ if ((he = *hep) == 0)
+ return PR_FALSE;
+
+ /* Hit; remove element */
+ PL_HashTableRawRemove(ht, hep, he);
+ return PR_TRUE;
+}
+
+PR_IMPLEMENT(void *)
+PL_HashTableLookup(PLHashTable *ht, const void *key)
+{
+ PLHashNumber keyHash;
+ PLHashEntry *he, **hep;
+
+ keyHash = (*ht->keyHash)(key);
+ hep = PL_HashTableRawLookup(ht, keyHash, key);
+ if ((he = *hep) != 0) {
+ return he->value;
+ }
+ return 0;
+}
+
+/*
+** Same as PL_HashTableLookup but doesn't reorder the hash entries.
+*/
+PR_IMPLEMENT(void *)
+PL_HashTableLookupConst(PLHashTable *ht, const void *key)
+{
+ PLHashNumber keyHash;
+ PLHashEntry *he, **hep;
+
+ keyHash = (*ht->keyHash)(key);
+ hep = PL_HashTableRawLookupConst(ht, keyHash, key);
+ if ((he = *hep) != 0) {
+ return he->value;
+ }
+ return 0;
+}
+
+/*
+** Iterate over the entries in the hash table calling func for each
+** entry found. Stop if "f" says to (return value & PR_ENUMERATE_STOP).
+** Return a count of the number of elements scanned.
+*/
+PR_IMPLEMENT(int)
+PL_HashTableEnumerateEntries(PLHashTable *ht, PLHashEnumerator f, void *arg)
+{
+ PLHashEntry *he, **hep;
+ PRUint32 i, nbuckets;
+ int rv, n = 0;
+ PLHashEntry *todo = 0;
+
+ nbuckets = NBUCKETS(ht);
+ for (i = 0; i < nbuckets; i++) {
+ hep = &ht->buckets[i];
+ while ((he = *hep) != 0) {
+ rv = (*f)(he, n, arg);
+ n++;
+ if (rv & (HT_ENUMERATE_REMOVE | HT_ENUMERATE_UNHASH)) {
+ *hep = he->next;
+ if (rv & HT_ENUMERATE_REMOVE) {
+ he->next = todo;
+ todo = he;
+ }
+ } else {
+ hep = &he->next;
+ }
+ if (rv & HT_ENUMERATE_STOP) {
+ goto out;
+ }
+ }
+ }
+
+out:
+ hep = &todo;
+ while ((he = *hep) != 0) {
+ PL_HashTableRawRemove(ht, hep, he);
+ }
+ return n;
+}
+
+#ifdef HASHMETER
+#include <math.h>
+#include <stdio.h>
+
+PR_IMPLEMENT(void)
+PL_HashTableDumpMeter(PLHashTable *ht, PLHashEnumerator dump, FILE *fp)
+{
+ double mean, variance;
+ PRUint32 nchains, nbuckets;
+ PRUint32 i, n, maxChain, maxChainLen;
+ PLHashEntry *he;
+
+ variance = 0;
+ nchains = 0;
+ maxChainLen = 0;
+ nbuckets = NBUCKETS(ht);
+ for (i = 0; i < nbuckets; i++) {
+ he = ht->buckets[i];
+ if (!he)
+ continue;
+ nchains++;
+ for (n = 0; he; he = he->next)
+ n++;
+ variance += n * n;
+ if (n > maxChainLen) {
+ maxChainLen = n;
+ maxChain = i;
+ }
+ }
+ mean = (double)ht->nentries / nchains;
+ variance = fabs(variance / nchains - mean * mean);
+
+ fprintf(fp, "\nHash table statistics:\n");
+ fprintf(fp, " number of lookups: %u\n", ht->nlookups);
+ fprintf(fp, " number of entries: %u\n", ht->nentries);
+ fprintf(fp, " number of grows: %u\n", ht->ngrows);
+ fprintf(fp, " number of shrinks: %u\n", ht->nshrinks);
+ fprintf(fp, " mean steps per hash: %g\n", (double)ht->nsteps
+ / ht->nlookups);
+ fprintf(fp, "mean hash chain length: %g\n", mean);
+ fprintf(fp, " standard deviation: %g\n", sqrt(variance));
+ fprintf(fp, " max hash chain length: %u\n", maxChainLen);
+ fprintf(fp, " max hash chain: [%u]\n", maxChain);
+
+ for (he = ht->buckets[maxChain], i = 0; he; he = he->next, i++)
+ if ((*dump)(he, i, fp) != HT_ENUMERATE_NEXT)
+ break;
+}
+#endif /* HASHMETER */
+
+PR_IMPLEMENT(int)
+PL_HashTableDump(PLHashTable *ht, PLHashEnumerator dump, FILE *fp)
+{
+ int count;
+
+ count = PL_HashTableEnumerateEntries(ht, dump, fp);
+#ifdef HASHMETER
+ PL_HashTableDumpMeter(ht, dump, fp);
+#endif
+ return count;
+}
+
+PR_IMPLEMENT(PLHashNumber)
+PL_HashString(const void *key)
+{
+ PLHashNumber h;
+ const PRUint8 *s;
+
+ h = 0;
+ for (s = (const PRUint8*)key; *s; s++)
+ h = (h >> 28) ^ (h << 4) ^ *s;
+ return h;
+}
+
+PR_IMPLEMENT(int)
+PL_CompareStrings(const void *v1, const void *v2)
+{
+ return strcmp((const char*)v1, (const char*)v2) == 0;
+}
+
+PR_IMPLEMENT(int)
+PL_CompareValues(const void *v1, const void *v2)
+{
+ return v1 == v2;
+}
diff --git a/src/libs/xpcom18a4/nsprpub/lib/ds/plhash.h b/src/libs/xpcom18a4/nsprpub/lib/ds/plhash.h
new file mode 100644
index 00000000..e899c0dc
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/ds/plhash.h
@@ -0,0 +1,183 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef plhash_h___
+#define plhash_h___
+/*
+ * API to portable hash table code.
+ */
+#include <stdio.h>
+#include "prtypes.h"
+
+#ifdef VBOX_WITH_XPCOM_NAMESPACE_CLEANUP
+#define PL_CompareStrings VBoxNsplPL_CompareStrings
+#define PL_CompareValues VBoxNsplPL_CompareValues
+#define PL_HashString VBoxNsplPL_HashString
+#define PL_HashTableAdd VBoxNsplPL_HashTableAdd
+#define PL_HashTableDestroy VBoxNsplPL_HashTableDestroy
+#define PL_HashTableLookup VBoxNsplPL_HashTableLookup
+#define PL_HashTableRemove VBoxNsplPL_HashTableRemove
+#define PL_NewHashTable VBoxNsplPL_NewHashTable
+#define PL_HashTableDump VBoxNsplPL_HashTableDump
+#define PL_HashTableEnumerateEntries VBoxNsplPL_HashTableEnumerateEntries
+#define PL_HashTableLookupConst VBoxNsplPL_HashTableLookupConst
+#define PL_HashTableRawAdd VBoxNsplPL_HashTableRawAdd
+#define PL_HashTableRawLookup VBoxNsplPL_HashTableRawLookup
+#define PL_HashTableRawLookupConst VBoxNsplPL_HashTableRawLookupConst
+#define PL_HashTableRawRemove VBoxNsplPL_HashTableRawRemove
+#endif /* VBOX_WITH_XPCOM_NAMESPACE_CLEANUP */
+
+PR_BEGIN_EXTERN_C
+
+typedef struct PLHashEntry PLHashEntry;
+typedef struct PLHashTable PLHashTable;
+typedef PRUint32 PLHashNumber;
+#define PL_HASH_BITS 32 /* Number of bits in PLHashNumber */
+typedef PLHashNumber (PR_CALLBACK *PLHashFunction)(const void *key);
+typedef PRIntn (PR_CALLBACK *PLHashComparator)(const void *v1, const void *v2);
+
+#if defined(XP_OS2_VACPP) && defined(VACPP_FLIP) /* for nsSpaceManager.cpp */
+PR_END_EXTERN_C /* and nsHTMLDocument.cpp */
+#endif
+typedef PRIntn (PR_CALLBACK *PLHashEnumerator)(PLHashEntry *he, PRIntn i, void *arg);
+
+#if defined(XP_OS2_VACPP) && defined(VACPP_FLIP)
+PR_BEGIN_EXTERN_C
+#endif
+
+/* Flag bits in PLHashEnumerator's return value */
+#define HT_ENUMERATE_NEXT 0 /* continue enumerating entries */
+#define HT_ENUMERATE_STOP 1 /* stop enumerating entries */
+#define HT_ENUMERATE_REMOVE 2 /* remove and free the current entry */
+#define HT_ENUMERATE_UNHASH 4 /* just unhash the current entry */
+
+typedef struct PLHashAllocOps {
+ void * (PR_CALLBACK *allocTable)(void *pool, PRSize size);
+ void (PR_CALLBACK *freeTable)(void *pool, void *item);
+ PLHashEntry * (PR_CALLBACK *allocEntry)(void *pool, const void *key);
+ void (PR_CALLBACK *freeEntry)(void *pool, PLHashEntry *he, PRUintn flag);
+} PLHashAllocOps;
+
+#define HT_FREE_VALUE 0 /* just free the entry's value */
+#define HT_FREE_ENTRY 1 /* free value and entire entry */
+
+struct PLHashEntry {
+ PLHashEntry *next; /* hash chain linkage */
+ PLHashNumber keyHash; /* key hash function result */
+ const void *key; /* ptr to opaque key */
+ void *value; /* ptr to opaque value */
+};
+
+struct PLHashTable {
+ PLHashEntry **buckets; /* vector of hash buckets */
+ PRUint32 nentries; /* number of entries in table */
+ PRUint32 shift; /* multiplicative hash shift */
+ PLHashFunction keyHash; /* key hash function */
+ PLHashComparator keyCompare; /* key comparison function */
+ PLHashComparator valueCompare; /* value comparison function */
+ const PLHashAllocOps *allocOps; /* allocation operations */
+ void *allocPriv; /* allocation private data */
+#ifdef HASHMETER
+ PRUint32 nlookups; /* total number of lookups */
+ PRUint32 nsteps; /* number of hash chains traversed */
+ PRUint32 ngrows; /* number of table expansions */
+ PRUint32 nshrinks; /* number of table contractions */
+#endif
+};
+
+/*
+ * Create a new hash table.
+ * If allocOps is null, use default allocator ops built on top of malloc().
+ */
+PR_EXTERN(PLHashTable *)
+PL_NewHashTable(PRUint32 numBuckets, PLHashFunction keyHash,
+ PLHashComparator keyCompare, PLHashComparator valueCompare,
+ const PLHashAllocOps *allocOps, void *allocPriv);
+
+PR_EXTERN(void)
+PL_HashTableDestroy(PLHashTable *ht);
+
+/* Higher level access methods */
+PR_EXTERN(PLHashEntry *)
+PL_HashTableAdd(PLHashTable *ht, const void *key, void *value);
+
+PR_EXTERN(PRBool)
+PL_HashTableRemove(PLHashTable *ht, const void *key);
+
+PR_EXTERN(void *)
+PL_HashTableLookup(PLHashTable *ht, const void *key);
+
+PR_EXTERN(void *)
+PL_HashTableLookupConst(PLHashTable *ht, const void *key);
+
+PR_EXTERN(PRIntn)
+PL_HashTableEnumerateEntries(PLHashTable *ht, PLHashEnumerator f, void *arg);
+
+/* General-purpose C string hash function. */
+PR_EXTERN(PLHashNumber)
+PL_HashString(const void *key);
+
+/* Compare strings using strcmp(), return true if equal. */
+PR_EXTERN(PRIntn)
+PL_CompareStrings(const void *v1, const void *v2);
+
+/* Stub function just returns v1 == v2 */
+PR_EXTERN(PRIntn)
+PL_CompareValues(const void *v1, const void *v2);
+
+/* Low level access methods */
+PR_EXTERN(PLHashEntry **)
+PL_HashTableRawLookup(PLHashTable *ht, PLHashNumber keyHash, const void *key);
+
+PR_EXTERN(PLHashEntry **)
+PL_HashTableRawLookupConst(PLHashTable *ht, PLHashNumber keyHash,
+ const void *key);
+
+PR_EXTERN(PLHashEntry *)
+PL_HashTableRawAdd(PLHashTable *ht, PLHashEntry **hep, PLHashNumber keyHash,
+ const void *key, void *value);
+
+PR_EXTERN(void)
+PL_HashTableRawRemove(PLHashTable *ht, PLHashEntry **hep, PLHashEntry *he);
+
+/* This can be trivially implemented using PL_HashTableEnumerateEntries. */
+PR_EXTERN(PRIntn)
+PL_HashTableDump(PLHashTable *ht, PLHashEnumerator dump, FILE *fp);
+
+PR_END_EXTERN_C
+
+#endif /* plhash_h___ */
diff --git a/src/libs/xpcom18a4/nsprpub/lib/ds/plvrsion.c b/src/libs/xpcom18a4/nsprpub/lib/ds/plvrsion.c
new file mode 100644
index 00000000..486a6cb1
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/ds/plvrsion.c
@@ -0,0 +1,125 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "prinit.h"
+#include "prvrsion.h"
+
+/************************************************************************/
+/**************************IDENTITY AND VERSIONING***********************/
+/************************************************************************/
+#include "_pl_bld.h"
+#if !defined(_BUILD_TIME)
+#ifdef HAVE_LONG_LONG
+#define _BUILD_TIME 0
+#else
+#define _BUILD_TIME {0, 0}
+#endif
+#endif
+#if !defined(_BUILD_STRING)
+#define _BUILD_STRING ""
+#endif
+#if !defined(_PRODUCTION)
+#define _PRODUCTION ""
+#endif
+#if defined(DEBUG)
+#define _DEBUG_STRING " (debug)"
+#else
+#define _DEBUG_STRING ""
+#endif
+
+/*
+ * A trick to expand the PR_VMAJOR macro before concatenation.
+ */
+#define CONCAT(x, y) x ## y
+#define CONCAT2(x, y) CONCAT(x, y)
+#define VERSION_DESC_NAME CONCAT2(prVersionDescription_libplds, PR_VMAJOR)
+
+PRVersionDescription VERSION_DESC_NAME =
+{
+ /* version */ 2, /* this is the only one supported */
+ /* buildTime */ _BUILD_TIME, /* usecs since midnight 1/1/1970 GMT */
+ /* buildTimeString */ _BUILD_STRING, /* ditto, but human readable */
+ /* vMajor */ PR_VMAJOR, /* NSPR's version number */
+ /* vMinor */ PR_VMINOR, /* and minor version */
+ /* vPatch */ PR_VPATCH, /* and patch */
+ /* beta */ PR_BETA, /* beta build boolean */
+#if defined(DEBUG)
+ /* debug */ PR_TRUE, /* a debug build */
+#else
+ /* debug */ PR_FALSE, /* an optomized build */
+#endif
+ /* special */ PR_FALSE, /* they're all special, but ... */
+ /* filename */ _PRODUCTION, /* the produced library name */
+ /* description */ "Portable runtime", /* what we are */
+ /* security */ "N/A", /* not applicable here */
+ /* copywrite */ "Copyright (c) 1998 Netscape Communications Corporation. All Rights Reserved",
+ /* comment */ "http://www.mozilla.org/MPL/",
+ /* specialString */ ""
+};
+
+#ifdef XP_UNIX
+
+/*
+ * Version information for the 'ident' and 'what commands
+ *
+ * NOTE: the first component of the concatenated rcsid string
+ * must not end in a '$' to prevent rcs keyword substitution.
+ */
+static char rcsid[] = "$Header: NSPR " PR_VERSION _DEBUG_STRING
+ " " _BUILD_STRING " $";
+static char sccsid[] = "@(#)NSPR " PR_VERSION _DEBUG_STRING
+ " " _BUILD_STRING;
+
+#endif /* XP_UNIX */
+
+PR_IMPLEMENT(const PRVersionDescription*) libVersionPoint()
+{
+#ifdef XP_UNIX
+ /*
+ * Add dummy references to rcsid and sccsid to prevent them
+ * from being optimized away as unused variables.
+ */
+ const char *dummy;
+
+ dummy = rcsid;
+ dummy = sccsid;
+#endif
+ return &VERSION_DESC_NAME;
+} /* versionEntryPointType */
+
+/* plvrsion.c */
+
diff --git a/src/libs/xpcom18a4/nsprpub/lib/libc/.cvsignore b/src/libs/xpcom18a4/nsprpub/lib/libc/.cvsignore
new file mode 100644
index 00000000..f3c7a7c5
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/libc/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/src/libs/xpcom18a4/nsprpub/lib/libc/Makefile.in b/src/libs/xpcom18a4/nsprpub/lib/libc/Makefile.in
new file mode 100644
index 00000000..9755225a
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/libc/Makefile.in
@@ -0,0 +1,56 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# 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 MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#! gmake
+
+MOD_DEPTH = ../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+export NSPR20=1
+
+include $(topsrcdir)/config/config.mk
+
+DIRS = include src
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(TARGETS)
+
diff --git a/src/libs/xpcom18a4/nsprpub/lib/libc/README b/src/libs/xpcom18a4/nsprpub/lib/libc/README
new file mode 100644
index 00000000..74f24690
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/libc/README
@@ -0,0 +1,20 @@
+NSPR 2.0 libc functions
+-----------------------
+
+Last edited: AOF 04 March 1997
+
+This directory contains various libc-types of functions. All functions in
+this directory are platform independent, thread friendly (both safe and
+efficient). They are contributed from various sources, though the contri-
+butions are monitored by the NSPR group (mailto:freier).
+
+All API items exported by these functions will contain the same three
+character prefix, "PL_" (Portable Library). Internal function names
+that are not exported (static) are of little concern, though some caution
+must be used on those elements that are 'extern' but not really intended
+to be part of the API. Those should all have a prefix of "_PL_" (is that
+legal?).
+
+The responsibility for contributions in this area are distributed among
+all interested parties.
+
diff --git a/src/libs/xpcom18a4/nsprpub/lib/libc/include/.cvsignore b/src/libs/xpcom18a4/nsprpub/lib/libc/include/.cvsignore
new file mode 100644
index 00000000..f3c7a7c5
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/libc/include/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/src/libs/xpcom18a4/nsprpub/lib/libc/include/MANIFEST b/src/libs/xpcom18a4/nsprpub/lib/libc/include/MANIFEST
new file mode 100644
index 00000000..63e8861d
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/libc/include/MANIFEST
@@ -0,0 +1,9 @@
+#
+# This is a list of local files which get copied to the mozilla:dist directory
+#
+
+plbase64.h
+plerror.h
+plgetopt.h
+plresolv.h
+plstr.h
diff --git a/src/libs/xpcom18a4/nsprpub/lib/libc/include/Makefile.in b/src/libs/xpcom18a4/nsprpub/lib/libc/include/Makefile.in
new file mode 100644
index 00000000..9d5e2e18
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/libc/include/Makefile.in
@@ -0,0 +1,61 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# 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 MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#! gmake
+
+MOD_DEPTH = ../../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+include $(topsrcdir)/config/config.mk
+
+HEADERS = $(wildcard $(srcdir)/*.h)
+
+RELEASE_HEADERS = $(HEADERS)
+RELEASE_HEADERS_DEST = $(RELEASE_INCLUDE_DIR)
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(HEADERS)
+ $(INSTALL) -m 444 $(HEADERS) $(dist_includedir)
+ifeq ($(MOZ_BITS),16)
+ $(INSTALL) -m 444 $(HEADERS) $(MOZ_INCL)
+endif
+
+
diff --git a/src/libs/xpcom18a4/nsprpub/lib/libc/include/README b/src/libs/xpcom18a4/nsprpub/lib/libc/include/README
new file mode 100644
index 00000000..2b852189
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/libc/include/README
@@ -0,0 +1,7 @@
+NSPR 2.0 libc functions
+-----------------------
+
+Last edited: AOF 04 March 1997
+
+This directory contains the API for various libc-types of functions.
+
diff --git a/src/libs/xpcom18a4/nsprpub/lib/libc/include/plbase64.h b/src/libs/xpcom18a4/nsprpub/lib/libc/include/plbase64.h
new file mode 100644
index 00000000..d6c7ec7b
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/libc/include/plbase64.h
@@ -0,0 +1,103 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef _plbase64_h
+#define _plbase64_h
+
+#include "prtypes.h"
+
+#ifdef VBOX_WITH_XPCOM_NAMESPACE_CLEANUP
+#define PL_Base64Decode VBoxNsplPL_Base64Decode
+#define PL_Base64Encode VBoxNsplPL_Base64Encode
+#endif /* VBOX_WITH_XPCOM_NAMESPACE_CLEANUP */
+
+PR_BEGIN_EXTERN_C
+
+/*
+ * PL_Base64Encode
+ *
+ * This routine encodes the data pointed to by the "src" parameter using the
+ * base64 algorithm, and returns a pointer to the result. If the "srclen"
+ * parameter is not zero, it specifies the length of the source data. If it
+ * is zero, the source data is assumed to be null-terminated, and PL_strlen
+ * is used to determine the source length. If the "dest" parameter is not
+ * null, it is assumed to point to a buffer of sufficient size (which may be
+ * calculated: ((srclen + 2)/3)*4) into which the encoded data is placed
+ * (without any termination). If the "dest" parameter is null, a buffer is
+ * allocated from the heap to hold the encoded data, and the result *will*
+ * be terminated with an extra null character. It is the caller's
+ * responsibility to free the result when it is allocated. A null is returned
+ * if the allocation fails.
+ */
+
+PR_EXTERN(char *)
+PL_Base64Encode
+(
+ const char *src,
+ PRUint32 srclen,
+ char *dest
+);
+
+/*
+ * PL_Base64Decode
+ *
+ * This routine decodes the data pointed to by the "src" parameter using
+ * the base64 algorithm, and returns a pointer to the result. The source
+ * may either include or exclude any trailing '=' characters. If the
+ * "srclen" parameter is not zero, it specifies the length of the source
+ * data. If it is zero, PL_strlen will be used to determine the source
+ * length. If the "dest" parameter is not null, it is assumed to point to
+ * a buffer of sufficient size (which may be calculated: (srclen * 3)/4
+ * when srclen includes the '=' characters) into which the decoded data
+ * is placed (without any termination). If the "dest" parameter is null,
+ * a buffer is allocated from the heap to hold the decoded data, and the
+ * result *will* be terminated with an extra null character. It is the
+ * caller's responsibility to free the result when it is allocated. A null
+ * is retuned if the allocation fails, or if the source is not well-coded.
+ */
+
+PR_EXTERN(char *)
+PL_Base64Decode
+(
+ const char *src,
+ PRUint32 srclen,
+ char *dest
+);
+
+PR_END_EXTERN_C
+
+#endif /* _plbase64_h */
diff --git a/src/libs/xpcom18a4/nsprpub/lib/libc/include/plerror.h b/src/libs/xpcom18a4/nsprpub/lib/libc/include/plerror.h
new file mode 100644
index 00000000..534acf2a
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/libc/include/plerror.h
@@ -0,0 +1,71 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File: plerror.h
+** Description: Simple routine to print translate the calling thread's
+** error numbers and print them.
+*/
+
+#if defined(PLERROR_H)
+#else
+#define PLERROR_H
+
+#include "prio.h"
+#include "prtypes.h"
+
+#ifdef VBOX_WITH_XPCOM_NAMESPACE_CLEANUP
+#define PL_FPrintError VBoxNsplPL_FPrintError
+#define PL_PrintError VBoxNsplPL_PrintError
+#endif /* VBOX_WITH_XPCOM_NAMESPACE_CLEANUP */
+
+PR_BEGIN_EXTERN_C
+/*
+** Print the messages to "syserr" prepending 'msg' if not NULL.
+*/
+PR_EXTERN(void) PL_PrintError(const char *msg);
+
+/*
+** Print the messages to specified output file prepending 'msg' if not NULL.
+*/
+PR_EXTERN(void) PL_FPrintError(PRFileDesc *output, const char *msg);
+
+PR_END_EXTERN_C
+
+#endif /* defined(PLERROR_H) */
+
+/* plerror.h */
diff --git a/src/libs/xpcom18a4/nsprpub/lib/libc/include/plgetopt.h b/src/libs/xpcom18a4/nsprpub/lib/libc/include/plgetopt.h
new file mode 100644
index 00000000..0f794fb0
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/libc/include/plgetopt.h
@@ -0,0 +1,87 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File: plgetopt.h
+** Description: utilities to parse argc/argv
+*/
+
+#if defined(PLGETOPT_H_)
+#else
+#define PLGETOPT_H_
+
+#include "prtypes.h"
+
+#ifdef VBOX_WITH_XPCOM_NAMESPACE_CLEANUP
+#define PL_CreateOptState VBoxNsplPL_CreateOptState
+#define PL_DestroyOptState VBoxNsplPL_DestroyOptState
+#define PL_GetNextOpt VBoxNsplPL_GetNextOpt
+#endif /* VBOX_WITH_XPCOM_NAMESPACE_CLEANUP */
+
+PR_BEGIN_EXTERN_C
+
+typedef struct PLOptionInternal PLOptionInternal;
+
+typedef enum
+{
+ PL_OPT_OK, /* all's well with the option */
+ PL_OPT_EOL, /* end of options list */
+ PL_OPT_BAD /* invalid option (and value) */
+} PLOptStatus;
+
+typedef struct PLOptState
+{
+ char option; /* the name of the option */
+ const char *value; /* the value of that option | NULL */
+
+ PLOptionInternal *internal; /* private processing state */
+
+} PLOptState;
+
+PR_EXTERN(PLOptState*) PL_CreateOptState(
+ PRIntn argc, char **argv, const char *options);
+
+PR_EXTERN(void) PL_DestroyOptState(PLOptState *opt);
+
+PR_EXTERN(PLOptStatus) PL_GetNextOpt(PLOptState *opt);
+
+PR_END_EXTERN_C
+
+#endif /* defined(PLGETOPT_H_) */
+
+/* plgetopt.h */
+
diff --git a/src/libs/xpcom18a4/nsprpub/lib/libc/include/plresolv.h b/src/libs/xpcom18a4/nsprpub/lib/libc/include/plresolv.h
new file mode 100644
index 00000000..45d4e5e6
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/libc/include/plresolv.h
@@ -0,0 +1,108 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * plresolv.h - asynchronous name resolution using DNS
+ */
+
+#ifndef _PLRESOLV_H_
+#define _PLRESOLV_H_
+
+/*
+** THIS IS WORK IN PROGRESS. DO NOT ATTEMPT TO USE ANY PORTION OF THIS
+** API UNTIL THIS MESSAGE NO LONGER EXISTS. IF YOU DO, THEN YOU SURRENDER
+** THE RIGHT TO COMPLAIN ABOUT ANY CONTENT.
+*/
+
+#if defined(XP_UNIX)
+
+#include <prtypes.h>
+#include <prnetdb.h>
+
+NSPR_BEGIN_EXTERN_C
+
+#define PL_RESOLVE_MAXHOSTENTBUF 1024
+#define PL_RESOLVE_DEFAULT_TIMEOUT 0
+
+/* Error return codes */
+#define PL_RESOLVE_OK 0
+#define PL_RESOLVE_EWINIT 1 /* Failed to initialize window */
+#define PL_RESOLVE_EMAKE 2 /* Failed to create request */
+#define PL_RESOLVE_ELAUNCH 3 /* Error launching Async request */
+#define PL_RESOLVE_ETIMEDOUT 4 /* Request timed-out */
+#define PL_RESOLVE_EINVAL 5 /* Invalid argument */
+#define PL_RESOLVE_EOVERFLOW 6 /* Buffer Overflow */
+#define PL_RESOLVE_EUNKNOWN 7 /* berzerk error */
+
+/* ----------- Function Prototypes ----------------*/
+
+PR_EXTERN(PRStatus) PL_ResolveName(
+ const char *name, unsigned char *buf,
+ PRIntn bufsize, PRIntervalTime timeout,
+ PRHostEnt *hostentry, PRIntervalTime *ttl);
+
+PR_EXTERN(PRStatus) PL_ResolveAddr(
+ const PRNetAddr *address, unsigned char *buf,
+ PRIntn bufsize, PRIntervalTime timeout,
+ PRHostEnt *hostentry, PRIntervalTime *ttl);
+
+typedef struct PLResolveStats {
+ int re_errors;
+ int re_nu_look;
+ int re_na_look;
+ int re_replies;
+ int re_requests;
+ int re_resends;
+ int re_sent;
+ int re_timeouts;
+} PLResolveStats;
+
+typedef struct PLResoveInfo {
+ PRBool enabled;
+ PRUint32 numNameLookups;
+ PRUint32 numAddrLookups;
+ PRUint32 numLookupsInProgress;
+ PLResolveStats stats;
+} PLResoveInfo;
+
+PR_EXTERN(void) PL_ResolveInfo(PLResoveInfo *info);
+
+NSPR_END_EXTERN_C
+
+#endif /* defined(XP_UNIX) */
+
+#endif /* _PLRESOLV_H_ */
diff --git a/src/libs/xpcom18a4/nsprpub/lib/libc/include/plstr.h b/src/libs/xpcom18a4/nsprpub/lib/libc/include/plstr.h
new file mode 100644
index 00000000..443da300
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/libc/include/plstr.h
@@ -0,0 +1,505 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Roland Mainz <roland mainz@informatik.med.uni-giessen.de>
+ *
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef _plstr_h
+#define _plstr_h
+
+/*
+ * plstr.h
+ *
+ * This header file exports the API to the NSPR portable library or string-
+ * handling functions.
+ *
+ * This API was not designed as an "optimal" or "ideal" string library; it
+ * was based on the good ol' unix string.3 functions, and was written to
+ *
+ * 1) replace the libc functions, for cross-platform consistancy,
+ * 2) complete the API on platforms lacking common functions (e.g.,
+ * strcase*), and
+ * 3) to implement some obvious "closure" functions that I've seen
+ * people hacking around in our code.
+ *
+ * Point number three largely means that most functions have an "strn"
+ * limited-length version, and all comparison routines have a non-case-
+ * sensitive version available.
+ */
+
+#include "prtypes.h"
+
+#ifdef VBOX_WITH_XPCOM_NAMESPACE_CLEANUP
+#define PL_strlen VBoxNsplPL_strlen
+#define PL_strcmp VBoxNsplPL_strcmp
+#define PL_strncmp VBoxNsplPL_strncmp
+#define PL_strcasecmp VBoxNsplPL_strcasecmp
+#define PL_strncasecmp VBoxNsplPL_strncasecmp
+#define PL_strdup VBoxNsplPL_strdup
+#define PL_strfree VBoxNsplPL_strfree
+#define PL_strncpy VBoxNsplPL_strncpy
+#define PL_strncpyz VBoxNsplPL_strncpyz
+#define PL_strrchr VBoxNsplPL_strrchr
+#define PL_strcaserstr VBoxNsplPL_strcaserstr
+#define PL_strcasestr VBoxNsplPL_strcasestr
+#define PL_strcat VBoxNsplPL_strcat
+#define PL_strcatn VBoxNsplPL_strcatn
+#define PL_strchr VBoxNsplPL_strchr
+#define PL_strcpy VBoxNsplPL_strcpy
+#define PL_strncaserstr VBoxNsplPL_strncaserstr
+#define PL_strncasestr VBoxNsplPL_strncasestr
+#define PL_strncat VBoxNsplPL_strncat
+#define PL_strnchr VBoxNsplPL_strnchr
+#define PL_strndup VBoxNsplPL_strndup
+#define PL_strnlen VBoxNsplPL_strnlen
+#define PL_strnpbrk VBoxNsplPL_strnpbrk
+#define PL_strnprbrk VBoxNsplPL_strnprbrk
+#define PL_strnrchr VBoxNsplPL_strnrchr
+#define PL_strnrstr VBoxNsplPL_strnrstr
+#define PL_strnstr VBoxNsplPL_strnstr
+#define PL_strpbrk VBoxNsplPL_strpbrk
+#define PL_strprbrk VBoxNsplPL_strprbrk
+#define PL_strrstr VBoxNsplPL_strrstr
+#define PL_strstr VBoxNsplPL_strstr
+#define PL_strtok_r VBoxNsplPL_strtok_r
+#endif /* VBOX_WITH_XPCOM_NAMESPACE_CLEANUP */
+
+PR_BEGIN_EXTERN_C
+/*
+ * PL_strlen
+ *
+ * Returns the length of the provided string, not including the trailing '\0'.
+ */
+
+PR_EXTERN(PRUint32)
+PL_strlen(const char *str);
+
+/*
+ * PL_strnlen
+ *
+ * Returns the length of the provided string, not including the trailing '\0',
+ * up to the indicated maximum. The string will not be examined beyond the
+ * maximum; if no terminating '\0' is found, the maximum will be returned.
+ */
+
+PR_EXTERN(PRUint32)
+PL_strnlen(const char *str, PRUint32 max);
+
+/*
+ * PL_strcpy
+ *
+ * Copies the source string, up to and including the trailing '\0', into the
+ * destination buffer. It does not (can not) verify that the destination
+ * buffer is large enough. It returns the "dest" argument.
+ */
+
+PR_EXTERN(char *)
+PL_strcpy(char *dest, const char *src);
+
+/*
+ * PL_strncpy
+ *
+ * Copies the source string into the destination buffer, up to and including
+ * the trailing '\0' or up to and including the max'th character, whichever
+ * comes first. It does not (can not) verify that the destination buffer is
+ * large enough. If the source string is longer than the maximum length,
+ * the result will *not* be null-terminated (JLRU).
+ */
+
+PR_EXTERN(char *)
+PL_strncpy(char *dest, const char *src, PRUint32 max);
+
+/*
+ * PL_strncpyz
+ *
+ * Copies the source string into the destination buffer, up to and including
+ * the trailing '\0' or up but not including the max'th character, whichever
+ * comes first. It does not (can not) verify that the destination buffer is
+ * large enough. The destination string is always terminated with a '\0',
+ * unlike the traditional libc implementation. It returns the "dest" argument.
+ *
+ * NOTE: If you call this with a source "abcdefg" and a max of 5, the
+ * destination will end up with "abcd\0" (i.e., it's strlen length will be 4)!
+ *
+ * This means you can do this:
+ *
+ * char buffer[ SOME_SIZE ];
+ * PL_strncpyz(buffer, src, sizeof(buffer));
+ *
+ * and the result will be properly terminated.
+ */
+
+PR_EXTERN(char *)
+PL_strncpyz(char *dest, const char *src, PRUint32 max);
+
+/*
+ * PL_strdup
+ *
+ * Returns a pointer to a malloc'd extent of memory containing a duplicate
+ * of the argument string. The size of the allocated extent is one greater
+ * than the length of the argument string, because of the terminator. A
+ * null argument, like a zero-length argument, will result in a pointer to
+ * a one-byte extent containing the null value. This routine returns null
+ * upon malloc failure.
+ */
+
+PR_EXTERN(char *)
+PL_strdup(const char *s);
+
+/*
+ * PL_strfree
+ *
+ * Free memory allocated by PL_strdup
+ */
+
+PR_EXTERN(void)
+PL_strfree(char *s);
+
+/*
+ * PL_strndup
+ *
+ * Returns a pointer to a malloc'd extent of memory containing a duplicate
+ * of the argument string, up to the maximum specified. If the argument
+ * string has a length greater than the value of the specified maximum, the
+ * return value will be a pointer to an extent of memory of length one
+ * greater than the maximum specified. A null string, a zero-length string,
+ * or a zero maximum will all result in a pointer to a one-byte extent
+ * containing the null value. This routine returns null upon malloc failure.
+ */
+
+PR_EXTERN(char *)
+PL_strndup(const char *s, PRUint32 max);
+
+/*
+ * PL_strcat
+ *
+ * Appends a copy of the string pointed to by the second argument to the
+ * end of the string pointed to by the first. The destination buffer is
+ * not (can not be) checked for sufficient size. A null destination
+ * argument returns null; otherwise, the first argument is returned.
+ */
+
+PR_EXTERN(char *)
+PL_strcat(char *dst, const char *src);
+
+/*
+ * PL_strncat
+ *
+ * Appends a copy of the string pointed to by the second argument, up to
+ * the maximum size specified, to the end of the string pointed to by the
+ * first. The destination buffer is not (can not be) checked for sufficient
+ * size. A null destination argument returns null; otherwise, the first
+ * argument is returned. If the maximum size limits the copy, then the
+ * result will *not* be null-terminated (JLRU). A null destination
+ * returns null; otherwise, the destination argument is returned.
+ */
+
+PR_EXTERN(char *)
+PL_strncat(char *dst, const char *src, PRUint32 max);
+
+/*
+ * PL_strcatn
+ *
+ * Appends a copy of the string pointed to by the third argument, to the
+ * end of the string pointed to by the first. The second argument specifies
+ * the maximum size of the destination buffer, including the null termination.
+ * If the existing string in dst is longer than the max, no action is taken.
+ * The resulting string will be null-terminated. A null destination returns
+ * null; otherwise, the destination argument is returned.
+ */
+
+PR_EXTERN(char *)
+PL_strcatn(char *dst, PRUint32 max, const char *src);
+
+/*
+ * PL_strcmp
+ *
+ * Returns an integer, the sign of which -- positive, zero, or negative --
+ * reflects the lexical sorting order of the two strings indicated. The
+ * result is positive if the first string comes after the second. The
+ * NSPR implementation is not i18n.
+ */
+
+PR_EXTERN(PRIntn)
+PL_strcmp(const char *a, const char *b);
+
+/*
+ * PL_strncmp
+ *
+ * Returns an integer, the sign of which -- positive, zero, or negative --
+ * reflects the lexical sorting order of the two strings indicated, up to
+ * the maximum specified. The result is positive if the first string comes
+ * after the second. The NSPR implementation is not i18n. If the maximum
+ * is zero, only the existance or non-existance (pointer is null) of the
+ * strings is compared.
+ */
+
+PR_EXTERN(PRIntn)
+PL_strncmp(const char *a, const char *b, PRUint32 max);
+
+/*
+ * PL_strcasecmp
+ *
+ * Returns an integer, the sign of which -- positive, zero or negative --
+ * reflects the case-insensitive lexical sorting order of the two strings
+ * indicated. The result is positive if the first string comes after the
+ * second. The NSPR implementation is not i18n.
+ */
+
+PR_EXTERN(PRIntn)
+PL_strcasecmp(const char *a, const char *b);
+
+/*
+ * PL_strncasecmp
+ *
+ * Returns an integer, the sign of which -- positive, zero or negative --
+ * reflects the case-insensitive lexical sorting order of the first n characters
+ * of the two strings indicated. The result is positive if the first string comes
+ * after the second. The NSPR implementation is not i18n.
+ */
+
+PR_EXTERN(PRIntn)
+PL_strncasecmp(const char *a, const char *b, PRUint32 max);
+
+/*
+ * PL_strchr
+ *
+ * Returns a pointer to the first instance of the specified character in the
+ * provided string. It returns null if the character is not found, or if the
+ * provided string is null. The character may be the null character.
+ */
+
+PR_EXTERN(char *)
+PL_strchr(const char *s, char c);
+
+/*
+ * PL_strrchr
+ *
+ * Returns a pointer to the last instance of the specified character in the
+ * provided string. It returns null if the character is not found, or if the
+ * provided string is null. The character may be the null character.
+ */
+
+PR_EXTERN(char *)
+PL_strrchr(const char *s, char c);
+
+/*
+ * PL_strnchr
+ *
+ * Returns a pointer to the first instance of the specified character within the
+ * first n characters of the provided string. It returns null if the character
+ * is not found, or if the provided string is null. The character may be the
+ * null character.
+ */
+
+PR_EXTERN(char *)
+PL_strnchr(const char *s, char c, PRUint32 n);
+
+/*
+ * PL_strnrchr
+ *
+ * Returns a pointer to the last instance of the specified character within the
+ * first n characters of the provided string. It returns null if the character is
+ * not found, or if the provided string is null. The character may be the null
+ * character.
+ */
+
+PR_EXTERN(char *)
+PL_strnrchr(const char *s, char c, PRUint32 n);
+
+/*
+ * NOTE: Looking for strcasechr, strcaserchr, strncasechr, or strncaserchr?
+ * Use strpbrk, strprbrk, strnpbrk or strnprbrk.
+ */
+
+/*
+ * PL_strpbrk
+ *
+ * Returns a pointer to the first instance in the first string of any character
+ * (not including the terminating null character) of the second string. It returns
+ * null if either string is null.
+ */
+
+PR_EXTERN(char *)
+PL_strpbrk(const char *s, const char *list);
+
+/*
+ * PL_strprbrk
+ *
+ * Returns a pointer to the last instance in the first string of any character
+ * (not including the terminating null character) of the second string. It returns
+ * null if either string is null.
+ */
+
+PR_EXTERN(char *)
+PL_strprbrk(const char *s, const char *list);
+
+/*
+ * PL_strnpbrk
+ *
+ * Returns a pointer to the first instance (within the first n characters) of any
+ * character (not including the terminating null character) of the second string.
+ * It returns null if either string is null.
+ */
+
+PR_EXTERN(char *)
+PL_strnpbrk(const char *s, const char *list, PRUint32 n);
+
+/*
+ * PL_strnprbrk
+ *
+ * Returns a pointer to the last instance (within the first n characters) of any
+ * character (not including the terminating null character) of the second string.
+ * It returns null if either string is null.
+ */
+
+PR_EXTERN(char *)
+PL_strnprbrk(const char *s, const char *list, PRUint32 n);
+
+/*
+ * PL_strstr
+ *
+ * Returns a pointer to the first instance of the little string within the
+ * big one. It returns null if either string is null.
+ */
+
+PR_EXTERN(char *)
+PL_strstr(const char *big, const char *little);
+
+/*
+ * PL_strrstr
+ *
+ * Returns a pointer to the last instance of the little string within the big one.
+ * It returns null if either string is null.
+ */
+
+PR_EXTERN(char *)
+PL_strrstr(const char *big, const char *little);
+
+/*
+ * PL_strnstr
+ *
+ * Returns a pointer to the first instance of the little string within the first
+ * n characters of the big one. It returns null if either string is null. It
+ * returns null if the length of the little string is greater than n.
+ */
+
+PR_EXTERN(char *)
+PL_strnstr(const char *big, const char *little, PRUint32 n);
+
+/*
+ * PL_strnrstr
+ *
+ * Returns a pointer to the last instance of the little string within the first
+ * n characters of the big one. It returns null if either string is null. It
+ * returns null if the length of the little string is greater than n.
+ */
+
+PR_EXTERN(char *)
+PL_strnrstr(const char *big, const char *little, PRUint32 max);
+
+/*
+ * PL_strcasestr
+ *
+ * Returns a pointer to the first instance of the little string within the big one,
+ * ignoring case. It returns null if either string is null.
+ */
+
+PR_EXTERN(char *)
+PL_strcasestr(const char *big, const char *little);
+
+/*
+ * PL_strcaserstr
+ *
+ * Returns a pointer to the last instance of the little string within the big one,
+ * ignoring case. It returns null if either string is null.
+ */
+
+PR_EXTERN(char *)
+PL_strcaserstr(const char *big, const char *little);
+
+/*
+ * PL_strncasestr
+ *
+ * Returns a pointer to the first instance of the listtle string within the first
+ * n characters of the big one, ignoring case. It returns null if either string is
+ * null. It returns null if the length of the little string is greater than n.
+ */
+
+PR_EXTERN(char *)
+PL_strncasestr(const char *big, const char *little, PRUint32 max);
+
+/*
+ * PL_strncaserstr
+ *
+ * Returns a pointer to the last instance of the little string within the first
+ * n characters of the big one, ignoring case. It returns null if either string is
+ * null. It returns null if the length of the little string is greater than n.
+ */
+
+PR_EXTERN(char *)
+PL_strncaserstr(const char *big, const char *little, PRUint32 max);
+
+/*
+ * PL_strtok_r
+ *
+ * Splits the string s1 into tokens, separated by one or more characters
+ * from the separator string s2. The argument lasts points to a
+ * user-supplied char * pointer in which PL_strtok_r stores information
+ * for it to continue scanning the same string.
+ *
+ * In the first call to PL_strtok_r, s1 points to a string and the value
+ * of *lasts is ignored. PL_strtok_r returns a pointer to the first
+ * token, writes '\0' into the character following the first token, and
+ * updates *lasts.
+ *
+ * In subsequent calls, s1 is null and lasts must stay unchanged from the
+ * previous call. The separator string s2 may be different from call to
+ * call. PL_strtok_r returns a pointer to the next token in s1. When no
+ * token remains in s1, PL_strtok_r returns null.
+ */
+
+PR_EXTERN(char *)
+PL_strtok_r(char *s1, const char *s2, char **lasts);
+
+/*
+ * Things not (yet?) included: strspn/strcspn, strsep.
+ * memchr, memcmp, memcpy, memccpy, index, rindex, bcmp, bcopy, bzero.
+ * Any and all i18n/l10n stuff.
+ */
+
+PR_END_EXTERN_C
+
+#endif /* _plstr_h */
diff --git a/src/libs/xpcom18a4/nsprpub/lib/libc/src/.cvsignore b/src/libs/xpcom18a4/nsprpub/lib/libc/src/.cvsignore
new file mode 100644
index 00000000..bcab60f5
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/libc/src/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+_pl_bld.h
diff --git a/src/libs/xpcom18a4/nsprpub/lib/libc/src/Makefile.in b/src/libs/xpcom18a4/nsprpub/lib/libc/src/Makefile.in
new file mode 100644
index 00000000..162b3ed9
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/libc/src/Makefile.in
@@ -0,0 +1,202 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# 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 MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+
+#! gmake
+
+MOD_DEPTH = ../../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/config.mk
+
+INCLUDES = -I$(dist_includedir)
+
+CSRCS =\
+ plvrsion.c \
+ strlen.c \
+ strcpy.c \
+ strdup.c \
+ strcat.c \
+ strcmp.c \
+ strccmp.c \
+ strchr.c \
+ strpbrk.c \
+ strstr.c \
+ strcstr.c \
+ strtok.c \
+ base64.c \
+ plerror.c \
+ plgetopt.c \
+ $(NULL)
+
+LIBRARY_NAME = plc
+LIBRARY_VERSION = $(MOD_MAJOR_VERSION)
+
+RELEASE_LIBS = $(TARGETS)
+
+ifeq ($(OS_ARCH),WINNT)
+ifdef NS_USE_GCC
+DLLBASE=-Wl,--image-base -Wl,0x30000000
+else
+DLLBASE=/BASE:0x30000000
+endif
+RES=$(OBJDIR)/plc.res
+RESNAME=plc.rc
+endif # WINNT
+
+ifeq ($(OS_ARCH), AIX)
+ifeq ($(CLASSIC_NSPR),1)
+OS_LIBS = -lc
+else
+OS_LIBS = -lc_r
+endif
+endif
+
+ifeq ($(OS_ARCH),IRIX)
+OS_LIBS = -lc
+endif
+
+ifeq ($(OS_ARCH),SunOS)
+OS_LIBS = -lc
+MAPFILE = $(OBJDIR)/plcmap.sun
+GARBAGE += $(MAPFILE)
+ifdef NS_USE_GCC
+ifdef GCC_USE_GNU_LD
+MKSHLIB += -Wl,--version-script,$(MAPFILE)
+else
+MKSHLIB += -Wl,-M,$(MAPFILE)
+endif
+else
+MKSHLIB += -M $(MAPFILE)
+endif
+# The -R '$ORIGIN' linker option instructs this library to search for its
+# dependencies in the same directory where it resides.
+MKSHLIB += -R '$$ORIGIN'
+endif
+
+ifeq ($(OS_ARCH),OS2)
+MAPFILE = $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).def
+GARBAGE += $(MAPFILE)
+MKSHLIB += $(MAPFILE)
+endif
+
+EXTRA_LIBS = $(LIBNSPR)
+
+# On NCR and SCOOS, we can't link with extra libraries when
+# we build a shared library. If we do so, the linker doesn't
+# complain, but we would run into weird problems at run-time.
+# Therefore on these platforms, we link just the .o files.
+ifeq ($(OS_ARCH),NCR)
+EXTRA_LIBS =
+endif
+ifeq ($(OS_ARCH),SCOOS)
+EXTRA_LIBS =
+endif
+
+ifdef RESOLVE_LINK_SYMBOLS
+EXTRA_LIBS += $(OS_LIBS)
+endif
+
+include $(topsrcdir)/config/rules.mk
+
+#
+# Version information generation (begin)
+#
+ECHO = echo
+TINC = $(OBJDIR)/_pl_bld.h
+PROD = $(notdir $(SHARED_LIBRARY))
+NOW = $(MOD_DEPTH)/config/$(OBJDIR)/now
+SH_DATE = $(shell date "+%Y-%m-%d %T")
+SH_NOW = $(shell $(NOW))
+
+ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT)
+ SUF = i64
+else
+ SUF = LL
+endif
+
+GARBAGE += $(TINC)
+
+$(TINC):
+ @$(MAKE_OBJDIR)
+ @$(ECHO) '#define _BUILD_STRING "$(SH_DATE)"' > $(TINC)
+ @if test ! -z "$(SH_NOW)"; then \
+ $(ECHO) '#define _BUILD_TIME $(SH_NOW)$(SUF)' >> $(TINC); \
+ else \
+ true; \
+ fi
+ @$(ECHO) '#define _PRODUCTION "$(PROD)"' >> $(TINC)
+
+
+$(OBJDIR)/plvrsion.$(OBJ_SUFFIX): plvrsion.c $(TINC)
+ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT)
+ $(CC) -Fo$@ -c $(CFLAGS) -I$(OBJDIR) $<
+else
+ifeq ($(MOZ_OS2_TOOLS), VACPP)
+ $(CC) -Fo$@ -c $(CFLAGS) -I$(OBJDIR) $<
+else
+ $(CC) -o $@ -c $(CFLAGS) -I$(OBJDIR) $<
+endif
+endif
+#
+# Version information generation (end)
+#
+
+#
+# The Client build wants the shared libraries in $(dist_bindir),
+# so we also install them there.
+#
+
+export:: $(TARGETS)
+ $(INSTALL) -m 444 $(TARGETS) $(dist_libdir)
+ifdef SHARED_LIBRARY
+ifeq ($(OS_ARCH),HP-UX)
+ $(INSTALL) -m 755 $(SHARED_LIBRARY) $(dist_libdir)
+ $(INSTALL) -m 755 $(SHARED_LIBRARY) $(dist_bindir)
+else
+ $(INSTALL) -m 444 $(SHARED_LIBRARY) $(dist_bindir)
+endif
+endif
+ifeq ($(MOZ_BITS),16)
+ $(INSTALL) -m 444 $(TARGETS) $(MOZ_DIST)/lib
+ $(INSTALL) -m 444 $(TARGETS) $(MOZ_DIST)/bin
+endif
+
diff --git a/src/libs/xpcom18a4/nsprpub/lib/libc/src/README b/src/libs/xpcom18a4/nsprpub/lib/libc/src/README
new file mode 100644
index 00000000..74f24690
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/libc/src/README
@@ -0,0 +1,20 @@
+NSPR 2.0 libc functions
+-----------------------
+
+Last edited: AOF 04 March 1997
+
+This directory contains various libc-types of functions. All functions in
+this directory are platform independent, thread friendly (both safe and
+efficient). They are contributed from various sources, though the contri-
+butions are monitored by the NSPR group (mailto:freier).
+
+All API items exported by these functions will contain the same three
+character prefix, "PL_" (Portable Library). Internal function names
+that are not exported (static) are of little concern, though some caution
+must be used on those elements that are 'extern' but not really intended
+to be part of the API. Those should all have a prefix of "_PL_" (is that
+legal?).
+
+The responsibility for contributions in this area are distributed among
+all interested parties.
+
diff --git a/src/libs/xpcom18a4/nsprpub/lib/libc/src/base64.c b/src/libs/xpcom18a4/nsprpub/lib/libc/src/base64.c
new file mode 100644
index 00000000..234d60d8
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/libc/src/base64.c
@@ -0,0 +1,428 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "plbase64.h"
+#include "prlog.h" /* For PR_NOT_REACHED */
+#include "prmem.h" /* for malloc / PR_MALLOC */
+#include "plstr.h" /* for PL_strlen */
+
+static unsigned char *base = (unsigned char *)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+static void
+encode3to4
+(
+ const unsigned char *src,
+ unsigned char *dest
+)
+{
+ PRUint32 b32 = (PRUint32)0;
+ PRIntn i, j = 18;
+
+ for( i = 0; i < 3; i++ )
+ {
+ b32 <<= 8;
+ b32 |= (PRUint32)src[i];
+ }
+
+ for( i = 0; i < 4; i++ )
+ {
+ dest[i] = base[ (PRUint32)((b32>>j) & 0x3F) ];
+ j -= 6;
+ }
+
+ return;
+}
+
+static void
+encode2to4
+(
+ const unsigned char *src,
+ unsigned char *dest
+)
+{
+ dest[0] = base[ (PRUint32)((src[0]>>2) & 0x3F) ];
+ dest[1] = base[ (PRUint32)(((src[0] & 0x03) << 4) | ((src[1] >> 4) & 0x0F)) ];
+ dest[2] = base[ (PRUint32)((src[1] & 0x0F) << 2) ];
+ dest[3] = (unsigned char)'=';
+ return;
+}
+
+static void
+encode1to4
+(
+ const unsigned char *src,
+ unsigned char *dest
+)
+{
+ dest[0] = base[ (PRUint32)((src[0]>>2) & 0x3F) ];
+ dest[1] = base[ (PRUint32)((src[0] & 0x03) << 4) ];
+ dest[2] = (unsigned char)'=';
+ dest[3] = (unsigned char)'=';
+ return;
+}
+
+static void
+encode
+(
+ const unsigned char *src,
+ PRUint32 srclen,
+ unsigned char *dest
+)
+{
+ while( srclen >= 3 )
+ {
+ encode3to4(src, dest);
+ src += 3;
+ dest += 4;
+ srclen -= 3;
+ }
+
+ switch( srclen )
+ {
+ case 2:
+ encode2to4(src, dest);
+ break;
+ case 1:
+ encode1to4(src, dest);
+ break;
+ case 0:
+ break;
+ default:
+ PR_NOT_REACHED("coding error");
+ }
+
+ return;
+}
+
+/*
+ * PL_Base64Encode
+ *
+ * If the destination argument is NULL, a return buffer is
+ * allocated, and the data therein will be null-terminated.
+ * If the destination argument is not NULL, it is assumed to
+ * be of sufficient size, and the contents will not be null-
+ * terminated by this routine.
+ *
+ * Returns null if the allocation fails.
+ */
+
+PR_IMPLEMENT(char *)
+PL_Base64Encode
+(
+ const char *src,
+ PRUint32 srclen,
+ char *dest
+)
+{
+ if( 0 == srclen )
+ {
+ srclen = PL_strlen(src);
+ }
+
+ if( (char *)0 == dest )
+ {
+ PRUint32 destlen = ((srclen + 2)/3) * 4;
+ dest = (char *)PR_MALLOC(destlen + 1);
+ if( (char *)0 == dest )
+ {
+ return (char *)0;
+ }
+ dest[ destlen ] = (char)0; /* null terminate */
+ }
+
+ encode((const unsigned char *)src, srclen, (unsigned char *)dest);
+ return dest;
+}
+
+static PRInt32
+codetovalue
+(
+ unsigned char c
+)
+{
+ if( (c >= (unsigned char)'A') && (c <= (unsigned char)'Z') )
+ {
+ return (PRInt32)(c - (unsigned char)'A');
+ }
+ else if( (c >= (unsigned char)'a') && (c <= (unsigned char)'z') )
+ {
+ return ((PRInt32)(c - (unsigned char)'a') +26);
+ }
+ else if( (c >= (unsigned char)'0') && (c <= (unsigned char)'9') )
+ {
+ return ((PRInt32)(c - (unsigned char)'0') +52);
+ }
+ else if( (unsigned char)'+' == c )
+ {
+ return (PRInt32)62;
+ }
+ else if( (unsigned char)'/' == c )
+ {
+ return (PRInt32)63;
+ }
+ else
+ {
+ return -1;
+ }
+}
+
+static PRStatus
+decode4to3
+(
+ const unsigned char *src,
+ unsigned char *dest
+)
+{
+ PRUint32 b32 = (PRUint32)0;
+ PRInt32 bits;
+ PRIntn i;
+
+ for( i = 0; i < 4; i++ )
+ {
+ bits = codetovalue(src[i]);
+ if( bits < 0 )
+ {
+ return PR_FAILURE;
+ }
+
+ b32 <<= 6;
+ b32 |= bits;
+ }
+
+ dest[0] = (unsigned char)((b32 >> 16) & 0xFF);
+ dest[1] = (unsigned char)((b32 >> 8) & 0xFF);
+ dest[2] = (unsigned char)((b32 ) & 0xFF);
+
+ return PR_SUCCESS;
+}
+
+static PRStatus
+decode3to2
+(
+ const unsigned char *src,
+ unsigned char *dest
+)
+{
+ PRUint32 b32 = (PRUint32)0;
+ PRInt32 bits;
+ PRUint32 ubits;
+
+ bits = codetovalue(src[0]);
+ if( bits < 0 )
+ {
+ return PR_FAILURE;
+ }
+
+ b32 = (PRUint32)bits;
+ b32 <<= 6;
+
+ bits = codetovalue(src[1]);
+ if( bits < 0 )
+ {
+ return PR_FAILURE;
+ }
+
+ b32 |= (PRUint32)bits;
+ b32 <<= 4;
+
+ bits = codetovalue(src[2]);
+ if( bits < 0 )
+ {
+ return PR_FAILURE;
+ }
+
+ ubits = (PRUint32)bits;
+ b32 |= (ubits >> 2);
+
+ dest[0] = (unsigned char)((b32 >> 8) & 0xFF);
+ dest[1] = (unsigned char)((b32 ) & 0xFF);
+
+ return PR_SUCCESS;
+}
+
+static PRStatus
+decode2to1
+(
+ const unsigned char *src,
+ unsigned char *dest
+)
+{
+ PRUint32 b32;
+ PRUint32 ubits;
+ PRInt32 bits;
+
+ bits = codetovalue(src[0]);
+ if( bits < 0 )
+ {
+ return PR_FAILURE;
+ }
+
+ ubits = (PRUint32)bits;
+ b32 = (ubits << 2);
+
+ bits = codetovalue(src[1]);
+ if( bits < 0 )
+ {
+ return PR_FAILURE;
+ }
+
+ ubits = (PRUint32)bits;
+ b32 |= (ubits >> 4);
+
+ dest[0] = (unsigned char)b32;
+
+ return PR_SUCCESS;
+}
+
+static PRStatus
+decode
+(
+ const unsigned char *src,
+ PRUint32 srclen,
+ unsigned char *dest
+)
+{
+ PRStatus rv;
+
+ while( srclen >= 4 )
+ {
+ rv = decode4to3(src, dest);
+ if( PR_SUCCESS != rv )
+ {
+ return PR_FAILURE;
+ }
+
+ src += 4;
+ dest += 3;
+ srclen -= 4;
+ }
+
+ switch( srclen )
+ {
+ case 3:
+ rv = decode3to2(src, dest);
+ break;
+ case 2:
+ rv = decode2to1(src, dest);
+ break;
+ case 1:
+ rv = PR_FAILURE;
+ break;
+ case 0:
+ rv = PR_SUCCESS;
+ break;
+ default:
+ PR_NOT_REACHED("coding error");
+ }
+
+ return rv;
+}
+
+/*
+ * PL_Base64Decode
+ *
+ * If the destination argument is NULL, a return buffer is
+ * allocated and the data therein will be null-terminated.
+ * If the destination argument is not null, it is assumed
+ * to be of sufficient size, and the data will not be null-
+ * terminated by this routine.
+ *
+ * Returns null if the allocation fails, or if the source string is
+ * not well-formed.
+ */
+
+PR_IMPLEMENT(char *)
+PL_Base64Decode
+(
+ const char *src,
+ PRUint32 srclen,
+ char *dest
+)
+{
+ PRStatus status;
+ PRBool allocated = PR_FALSE;
+
+ if( (char *)0 == src )
+ {
+ return (char *)0;
+ }
+
+ if( 0 == srclen )
+ {
+ srclen = PL_strlen(src);
+ }
+
+ if( srclen && (0 == (srclen & 3)) )
+ {
+ if( (char)'=' == src[ srclen-1 ] )
+ {
+ if( (char)'=' == src[ srclen-2 ] )
+ {
+ srclen -= 2;
+ }
+ else
+ {
+ srclen -= 1;
+ }
+ }
+ }
+
+ if( (char *)0 == dest )
+ {
+ PRUint32 destlen = ((srclen * 3) / 4);
+ dest = (char *)PR_MALLOC(destlen + 1);
+ if( (char *)0 == dest )
+ {
+ return (char *)0;
+ }
+ dest[ destlen ] = (char)0; /* null terminate */
+ allocated = PR_TRUE;
+ }
+
+ status = decode((const unsigned char *)src, srclen, (unsigned char *)dest);
+ if( PR_SUCCESS != status )
+ {
+ if( PR_TRUE == allocated )
+ {
+ PR_DELETE(dest);
+ }
+
+ return (char *)0;
+ }
+
+ return dest;
+}
diff --git a/src/libs/xpcom18a4/nsprpub/lib/libc/src/plc.def b/src/libs/xpcom18a4/nsprpub/lib/libc/src/plc.def
new file mode 100644
index 00000000..39eba5b7
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/libc/src/plc.def
@@ -0,0 +1,94 @@
+;+#
+;+# 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 the Netscape Portable Runtime (NSPR).
+;+#
+;+# The Initial Developer of the Original Code is Netscape
+;+# Communications Corporation. Portions created by Netscape are
+;+# Copyright (C) 2002-2003 Netscape Communications Corporation. All
+;+# Rights Reserved.
+;+#
+;+# Contributor(s):
+;+#
+;+# Alternatively, the contents of this file may be used under the
+;+# terms of the GNU General Public License Version 2 or later (the
+;+# "GPL"), in which case the provisions of the GPL are applicable
+;+# instead of those above. If you wish to allow use of your
+;+# version of this file only under the terms of the GPL and not to
+;+# allow others to use your version of this file under the MPL,
+;+# indicate your decision by deleting the provisions above and
+;+# replace them with the notice and other provisions required by
+;+# the GPL. If you do not delete the provisions above, a recipient
+;+# may use your version of this file under either the MPL or the
+;+# GPL.
+;+#
+;+# OK, this file is meant to support SUN, LINUX, AIX, OS/2 and WINDOWS
+;+# 1. For all unix platforms, the string ";-" means "remove this line"
+;+# 2. For all unix platforms, the string " DATA " will be removed from any
+;+# line on which it occurs.
+;+# 3. Lines containing ";+" will have ";+" removed on SUN and LINUX.
+;+# On AIX, lines containing ";+" will be removed.
+;+# 4. For all unix platforms, the string ";;" will thave the ";;" removed.
+;+# 5. For all unix platforms, after the above processing has taken place,
+;+# all characters after the first ";" on the line will be removed.
+;+# And for AIX, the first ";" will also be removed.
+;+# This file is passed directly to windows. Since ';' is a comment, all UNIX
+;+# directives are hidden behind ";", ";+", and ";-"
+;+NSPR_4.0 {
+;+ global:
+LIBRARY plc4 ;-
+EXPORTS ;-
+PL_Base64Decode;
+PL_Base64Encode;
+PL_CreateOptState;
+PL_DestroyOptState;
+PL_FPrintError;
+PL_GetNextOpt;
+PL_PrintError;
+PL_strcasecmp;
+PL_strcaserstr;
+PL_strcasestr;
+PL_strcat;
+PL_strcatn;
+PL_strchr;
+PL_strcmp;
+PL_strcpy;
+PL_strdup;
+PL_strfree;
+PL_strlen;
+PL_strncasecmp;
+PL_strncaserstr;
+PL_strncasestr;
+PL_strncat;
+PL_strnchr;
+PL_strncmp;
+PL_strncpy;
+PL_strncpyz;
+PL_strndup;
+PL_strnlen;
+PL_strnpbrk;
+PL_strnprbrk;
+PL_strnrchr;
+PL_strnrstr;
+PL_strnstr;
+PL_strpbrk;
+PL_strprbrk;
+PL_strrchr;
+PL_strrstr;
+PL_strstr;
+libVersionPoint;
+;+ local: *;
+;+};
+;+
+;+NSPR_4.2 {
+;+ global:
+PL_strtok_r;
+;+} NSPR_4.0;
diff --git a/src/libs/xpcom18a4/nsprpub/lib/libc/src/plc.rc b/src/libs/xpcom18a4/nsprpub/lib/libc/src/plc.rc
new file mode 100644
index 00000000..15ca10f2
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/libc/src/plc.rc
@@ -0,0 +1,103 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+#include "prinit.h"
+#include <winver.h>
+
+#define MY_LIBNAME "plc"
+#define MY_FILEDESCRIPTION "PLC Library"
+
+#define STRINGIZE(x) #x
+#define STRINGIZE2(x) STRINGIZE(x)
+#define PR_VMAJOR_STR STRINGIZE2(PR_VMAJOR)
+
+#ifdef _DEBUG
+#define MY_DEBUG_STR " (debug)"
+#define MY_FILEFLAGS_1 VS_FF_DEBUG
+#else
+#define MY_DEBUG_STR ""
+#define MY_FILEFLAGS_1 0x0L
+#endif
+#if PR_BETA
+#define MY_FILEFLAGS_2 MY_FILEFLAGS_1|VS_FF_PRERELEASE
+#else
+#define MY_FILEFLAGS_2 MY_FILEFLAGS_1
+#endif
+
+#ifdef WINNT
+#define MY_FILEOS VOS_NT_WINDOWS32
+#define MY_INTERNAL_NAME "lib" MY_LIBNAME PR_VMAJOR_STR
+#else
+#define MY_FILEOS VOS__WINDOWS32
+#define MY_INTERNAL_NAME MY_LIBNAME PR_VMAJOR_STR
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version-information resource
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION PR_VMAJOR,PR_VMINOR,PR_VPATCH,0
+ PRODUCTVERSION PR_VMAJOR,PR_VMINOR,PR_VPATCH,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS MY_FILEFLAGS_2
+ FILEOS MY_FILEOS
+ FILETYPE VFT_DLL
+ FILESUBTYPE 0x0L // not used
+
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904B0" // Lang=US English, CharSet=Unicode
+ BEGIN
+ VALUE "CompanyName", "Netscape Communications Corporation\0"
+ VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0"
+ VALUE "FileVersion", PR_VERSION "\0"
+ VALUE "InternalName", MY_INTERNAL_NAME "\0"
+ VALUE "LegalCopyright", "Copyright \251 1996-2000 Netscape Communications Corporation\0"
+ VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0"
+ VALUE "ProductName", "Netscape Portable Runtime\0"
+ VALUE "ProductVersion", PR_VERSION "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/src/libs/xpcom18a4/nsprpub/lib/libc/src/plc_symvec.opt b/src/libs/xpcom18a4/nsprpub/lib/libc/src/plc_symvec.opt
new file mode 100644
index 00000000..8bc769e0
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/libc/src/plc_symvec.opt
@@ -0,0 +1,53 @@
+! Fixed section of symbol vector for LIBPLC4
+!
+GSMATCH=LEQUAL,2,2
+case_sensitive=YES
+!
+! --------------------------------------------------------------------------
+! Ident 2,2 introduced for Mozilla 1.3
+! Previously this was empty. Now we include everything that's specified in
+! plc.def.
+! --------------------------------------------------------------------------
+!
+! NSPR 4.0
+SYMBOL_VECTOR=(PL_Base64Decode=PROCEDURE)
+SYMBOL_VECTOR=(PL_Base64Encode=PROCEDURE)
+SYMBOL_VECTOR=(PL_CreateOptState=PROCEDURE)
+SYMBOL_VECTOR=(PL_DestroyOptState=PROCEDURE)
+SYMBOL_VECTOR=(PL_FPrintError=PROCEDURE)
+SYMBOL_VECTOR=(PL_GetNextOpt=PROCEDURE)
+SYMBOL_VECTOR=(PL_PrintError=PROCEDURE)
+SYMBOL_VECTOR=(PL_strcasecmp=PROCEDURE)
+SYMBOL_VECTOR=(PL_strcaserstr=PROCEDURE)
+SYMBOL_VECTOR=(PL_strcasestr=PROCEDURE)
+SYMBOL_VECTOR=(PL_strcat=PROCEDURE)
+SYMBOL_VECTOR=(PL_strcatn=PROCEDURE)
+SYMBOL_VECTOR=(PL_strchr=PROCEDURE)
+SYMBOL_VECTOR=(PL_strcmp=PROCEDURE)
+SYMBOL_VECTOR=(PL_strcpy=PROCEDURE)
+SYMBOL_VECTOR=(PL_strdup=PROCEDURE)
+SYMBOL_VECTOR=(PL_strfree=PROCEDURE)
+SYMBOL_VECTOR=(PL_strlen=PROCEDURE)
+SYMBOL_VECTOR=(PL_strncasecmp=PROCEDURE)
+SYMBOL_VECTOR=(PL_strncaserstr=PROCEDURE)
+SYMBOL_VECTOR=(PL_strncasestr=PROCEDURE)
+SYMBOL_VECTOR=(PL_strncat=PROCEDURE)
+SYMBOL_VECTOR=(PL_strnchr=PROCEDURE)
+SYMBOL_VECTOR=(PL_strncmp=PROCEDURE)
+SYMBOL_VECTOR=(PL_strncpy=PROCEDURE)
+SYMBOL_VECTOR=(PL_strncpyz=PROCEDURE)
+SYMBOL_VECTOR=(PL_strndup=PROCEDURE)
+SYMBOL_VECTOR=(PL_strnlen=PROCEDURE)
+SYMBOL_VECTOR=(PL_strnpbrk=PROCEDURE)
+SYMBOL_VECTOR=(PL_strnprbrk=PROCEDURE)
+SYMBOL_VECTOR=(PL_strnrchr=PROCEDURE)
+SYMBOL_VECTOR=(PL_strnrstr=PROCEDURE)
+SYMBOL_VECTOR=(PL_strnstr=PROCEDURE)
+SYMBOL_VECTOR=(PL_strpbrk=PROCEDURE)
+SYMBOL_VECTOR=(PL_strprbrk=PROCEDURE)
+SYMBOL_VECTOR=(PL_strrchr=PROCEDURE)
+SYMBOL_VECTOR=(PL_strrstr=PROCEDURE)
+SYMBOL_VECTOR=(PL_strstr=PROCEDURE)
+SYMBOL_VECTOR=(libVersionPoint=PROCEDURE)
+! NSPR 4.2
+SYMBOL_VECTOR=(PL_strtok_r=PROCEDURE)
diff --git a/src/libs/xpcom18a4/nsprpub/lib/libc/src/plerror.c b/src/libs/xpcom18a4/nsprpub/lib/libc/src/plerror.c
new file mode 100644
index 00000000..4e38ee6d
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/libc/src/plerror.c
@@ -0,0 +1,168 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File:plerror.c
+** Description: Simple routine to print translate the calling thread's
+** error numbers and print them to "syserr".
+*/
+
+#include "plerror.h"
+
+#include "prprf.h"
+#include "prerror.h"
+
+PR_IMPLEMENT(void) PL_FPrintError(PRFileDesc *fd, const char *msg)
+{
+static const char *tags[] =
+{
+ "PR_OUT_OF_MEMORY_ERROR",
+ "PR_BAD_DESCRIPTOR_ERROR",
+ "PR_WOULD_BLOCK_ERROR",
+ "PR_ACCESS_FAULT_ERROR",
+ "PR_INVALID_METHOD_ERROR",
+ "PR_ILLEGAL_ACCESS_ERROR",
+ "PR_UNKNOWN_ERROR",
+ "PR_PENDING_INTERRUPT_ERROR",
+ "PR_NOT_IMPLEMENTED_ERROR",
+ "PR_IO_ERROR",
+ "PR_IO_TIMEOUT_ERROR",
+ "PR_IO_PENDING_ERROR",
+ "PR_DIRECTORY_OPEN_ERROR",
+ "PR_INVALID_ARGUMENT_ERROR",
+ "PR_ADDRESS_NOT_AVAILABLE_ERROR",
+ "PR_ADDRESS_NOT_SUPPORTED_ERROR",
+ "PR_IS_CONNECTED_ERROR",
+ "PR_BAD_ADDRESS_ERROR",
+ "PR_ADDRESS_IN_USE_ERROR",
+ "PR_CONNECT_REFUSED_ERROR",
+ "PR_NETWORK_UNREACHABLE_ERROR",
+ "PR_CONNECT_TIMEOUT_ERROR",
+ "PR_NOT_CONNECTED_ERROR",
+ "PR_LOAD_LIBRARY_ERROR",
+ "PR_UNLOAD_LIBRARY_ERROR",
+ "PR_FIND_SYMBOL_ERROR",
+ "PR_INSUFFICIENT_RESOURCES_ERROR",
+ "PR_DIRECTORY_LOOKUP_ERROR",
+ "PR_TPD_RANGE_ERROR",
+ "PR_PROC_DESC_TABLE_FULL_ERROR",
+ "PR_SYS_DESC_TABLE_FULL_ERROR",
+ "PR_NOT_SOCKET_ERROR",
+ "PR_NOT_TCP_SOCKET_ERROR",
+ "PR_SOCKET_ADDRESS_IS_BOUND_ERROR",
+ "PR_NO_ACCESS_RIGHTS_ERROR",
+ "PR_OPERATION_NOT_SUPPORTED_ERROR",
+ "PR_PROTOCOL_NOT_SUPPORTED_ERROR",
+ "PR_REMOTE_FILE_ERROR",
+ "PR_BUFFER_OVERFLOW_ERROR",
+ "PR_CONNECT_RESET_ERROR",
+ "PR_RANGE_ERROR",
+ "PR_DEADLOCK_ERROR",
+ "PR_FILE_IS_LOCKED_ERROR",
+ "PR_FILE_TOO_BIG_ERROR",
+ "PR_NO_DEVICE_SPACE_ERROR",
+ "PR_PIPE_ERROR",
+ "PR_NO_SEEK_DEVICE_ERROR",
+ "PR_IS_DIRECTORY_ERROR",
+ "PR_LOOP_ERROR",
+ "PR_NAME_TOO_LONG_ERROR",
+ "PR_FILE_NOT_FOUND_ERROR",
+ "PR_NOT_DIRECTORY_ERROR",
+ "PR_READ_ONLY_FILESYSTEM_ERROR",
+ "PR_DIRECTORY_NOT_EMPTY_ERROR",
+ "PR_FILESYSTEM_MOUNTED_ERROR",
+ "PR_NOT_SAME_DEVICE_ERROR",
+ "PR_DIRECTORY_CORRUPTED_ERROR",
+ "PR_FILE_EXISTS_ERROR",
+ "PR_MAX_DIRECTORY_ENTRIES_ERROR",
+ "PR_INVALID_DEVICE_STATE_ERROR",
+ "PR_DEVICE_IS_LOCKED_ERROR",
+ "PR_NO_MORE_FILES_ERROR",
+ "PR_END_OF_FILE_ERROR",
+ "PR_FILE_SEEK_ERROR",
+ "PR_FILE_IS_BUSY_ERROR",
+ "<unused error code>",
+ "PR_IN_PROGRESS_ERROR",
+ "PR_ALREADY_INITIATED_ERROR",
+ "PR_GROUP_EMPTY_ERROR",
+ "PR_INVALID_STATE_ERROR",
+ "PR_NETWORK_DOWN_ERROR",
+ "PR_SOCKET_SHUTDOWN_ERROR",
+ "PR_CONNECT_ABORTED_ERROR",
+ "PR_HOST_UNREACHABLE_ERROR",
+ "PR_MAX_ERROR"
+};
+
+PRErrorCode error = PR_GetError();
+PRInt32 oserror = PR_GetOSError();
+PRIntn thoseIKnowAbout = sizeof(tags) / sizeof(char*);
+PRIntn lastError = PR_NSPR_ERROR_BASE + thoseIKnowAbout;
+
+ if (NULL != msg) PR_fprintf(fd, "%s: ", msg);
+ if ((error < PR_NSPR_ERROR_BASE) || (error >= lastError))
+ PR_fprintf(
+ fd, " (%d)OUT OF RANGE, oserror = %d\n", error, oserror);
+ else
+ PR_fprintf(
+ fd, "%s(%d), oserror = %d\n",
+ tags[error - PR_NSPR_ERROR_BASE], error, oserror);
+} /* PL_FPrintError */
+
+PR_IMPLEMENT(void) PL_PrintError(const char *msg)
+{
+ static PRFileDesc *fd = NULL;
+ if (NULL == fd) fd = PR_GetSpecialFD(PR_StandardError);
+ PL_FPrintError(fd, msg);
+} /* PL_PrintError */
+
+#if defined(WIN16)
+/*
+** libmain() is a required function for win16
+**
+*/
+int CALLBACK LibMain( HINSTANCE hInst, WORD wDataSeg,
+ WORD cbHeapSize, LPSTR lpszCmdLine )
+{
+return TRUE;
+}
+#endif /* WIN16 */
+
+
+
+
+
+/* plerror.c */
diff --git a/src/libs/xpcom18a4/nsprpub/lib/libc/src/plgetopt.c b/src/libs/xpcom18a4/nsprpub/lib/libc/src/plgetopt.c
new file mode 100644
index 00000000..e2ccfa1b
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/libc/src/plgetopt.c
@@ -0,0 +1,184 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File: plgetopt.c
+** Description: utilities to parse argc/argv
+*/
+
+#include "prmem.h"
+#include "prlog.h"
+#include "prerror.h"
+#include "plstr.h"
+#include "plgetopt.h"
+
+#include <string.h>
+
+static char static_Nul = 0;
+
+struct PLOptionInternal
+{
+ const char *options; /* client options list specification */
+ PRIntn argc; /* original number of arguments */
+ char **argv; /* vector of pointers to arguments */
+ PRIntn xargc; /* which one we're processing now */
+ const char *xargv; /* where within *argv[xargc] */
+ PRBool minus; /* do we already have the '-'? */
+};
+
+/*
+** Create the state in which to parse the tokens.
+**
+** argc the sum of the number of options and their values
+** argv the options and their values
+** options vector of single character options w/ | w/o ':
+*/
+PR_IMPLEMENT(PLOptState*) PL_CreateOptState(
+ PRIntn argc, char **argv, const char *options)
+{
+ PLOptState *opt = NULL;
+ if (NULL == options)
+ PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+ else
+ {
+ opt = PR_NEWZAP(PLOptState);
+ if (NULL == opt)
+ PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+ else
+ {
+ PLOptionInternal *internal = PR_NEW(PLOptionInternal);
+ if (NULL == internal)
+ {
+ PR_DELETE(opt);
+ PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+ }
+ else
+ {
+ opt->option = 0;
+ opt->value = NULL;
+ opt->internal = internal;
+
+ internal->argc = argc;
+ internal->argv = argv;
+ internal->xargc = 0;
+ internal->xargv = &static_Nul;
+ internal->minus = PR_FALSE;
+ internal->options = options;
+ }
+ }
+ }
+ return opt;
+} /* PL_CreateOptState */
+
+/*
+** Destroy object created by CreateOptState()
+*/
+PR_IMPLEMENT(void) PL_DestroyOptState(PLOptState *opt)
+{
+ PR_DELETE(opt->internal);
+ PR_DELETE(opt);
+} /* PL_DestroyOptState */
+
+PR_IMPLEMENT(PLOptStatus) PL_GetNextOpt(PLOptState *opt)
+{
+ PLOptionInternal *internal = opt->internal;
+ PRIntn cop, eoo = PL_strlen(internal->options);
+
+ /*
+ ** If the current xarg points to nul, advance to the next
+ ** element of the argv vector. If the vector index is equal
+ ** to argc, we're out of arguments, so return an EOL.
+ ** Note whether the first character of the new argument is
+ ** a '-' and skip by it if it is.
+ */
+ while (0 == *internal->xargv)
+ {
+ internal->xargc += 1;
+ if (internal->xargc >= internal->argc)
+ {
+ opt->option = 0;
+ opt->value = NULL;
+ return PL_OPT_EOL;
+ }
+ internal->xargv = internal->argv[internal->xargc];
+ internal->minus = ('-' == *internal->xargv ? PR_TRUE : PR_FALSE); /* not it */
+ if (internal->minus) internal->xargv += 1; /* and consume */
+ }
+
+ /*
+ ** If we already have a '-' in hand, xargv points to the next
+ ** option. See if we can find a match in the list of possible
+ ** options supplied.
+ */
+
+ if (internal->minus)
+ {
+ for (cop = 0; cop < eoo; ++cop)
+ {
+ if (internal->options[cop] == *internal->xargv)
+ {
+ opt->option = *internal->xargv;
+ internal->xargv += 1;
+ /*
+ ** if options indicates that there's an associated
+ ** value, this argv is finished and the next is the
+ ** option's value.
+ */
+ if (':' == internal->options[cop + 1])
+ {
+ if (0 != *internal->xargv) return PL_OPT_BAD;
+ opt->value = internal->argv[++(internal->xargc)];
+ internal->xargv = &static_Nul;
+ internal->minus = PR_FALSE;
+ }
+ else opt->value = NULL;
+ return PL_OPT_OK;
+ }
+ }
+ internal->xargv += 1; /* consume that option */
+ return PL_OPT_BAD;
+ }
+ /*
+ ** No '-', so it must be a standalone value. The option is nul.
+ */
+ opt->value = internal->argv[internal->xargc];
+ internal->xargv = &static_Nul;
+ opt->option = 0;
+ return PL_OPT_OK;
+} /* PL_GetNextOpt */
+
+/* plgetopt.c */
diff --git a/src/libs/xpcom18a4/nsprpub/lib/libc/src/plvrsion.c b/src/libs/xpcom18a4/nsprpub/lib/libc/src/plvrsion.c
new file mode 100644
index 00000000..e9903cb7
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/libc/src/plvrsion.c
@@ -0,0 +1,125 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "prinit.h"
+#include "prvrsion.h"
+
+/************************************************************************/
+/**************************IDENTITY AND VERSIONING***********************/
+/************************************************************************/
+#include "_pl_bld.h"
+#if !defined(_BUILD_TIME)
+#ifdef HAVE_LONG_LONG
+#define _BUILD_TIME 0
+#else
+#define _BUILD_TIME {0, 0}
+#endif
+#endif
+#if !defined(_BUILD_STRING)
+#define _BUILD_STRING ""
+#endif
+#if !defined(_PRODUCTION)
+#define _PRODUCTION ""
+#endif
+#if defined(DEBUG)
+#define _DEBUG_STRING " (debug)"
+#else
+#define _DEBUG_STRING ""
+#endif
+
+/*
+ * A trick to expand the PR_VMAJOR macro before concatenation.
+ */
+#define CONCAT(x, y) x ## y
+#define CONCAT2(x, y) CONCAT(x, y)
+#define VERSION_DESC_NAME CONCAT2(prVersionDescription_libplc, PR_VMAJOR)
+
+PRVersionDescription VERSION_DESC_NAME =
+{
+ /* version */ 2, /* this is the only one supported */
+ /* buildTime */ _BUILD_TIME, /* usecs since midnight 1/1/1970 GMT */
+ /* buildTimeString */ _BUILD_STRING, /* ditto, but human readable */
+ /* vMajor */ PR_VMAJOR, /* NSPR's version number */
+ /* vMinor */ PR_VMINOR, /* and minor version */
+ /* vPatch */ PR_VPATCH, /* and patch */
+ /* beta */ PR_BETA, /* beta build boolean */
+#if defined(DEBUG)
+ /* debug */ PR_TRUE, /* a debug build */
+#else
+ /* debug */ PR_FALSE, /* an optomized build */
+#endif
+ /* special */ PR_FALSE, /* they're all special, but ... */
+ /* filename */ _PRODUCTION, /* the produced library name */
+ /* description */ "Portable runtime", /* what we are */
+ /* security */ "N/A", /* not applicable here */
+ /* copywrite */ "Copyright (c) 1998 Netscape Communications Corporation. All Rights Reserved",
+ /* comment */ "http://www.mozilla.org/MPL/",
+ /* specialString */ ""
+};
+
+#ifdef XP_UNIX
+
+/*
+ * Version information for the 'ident' and 'what commands
+ *
+ * NOTE: the first component of the concatenated rcsid string
+ * must not end in a '$' to prevent rcs keyword substitution.
+ */
+static char rcsid[] = "$Header: NSPR " PR_VERSION _DEBUG_STRING
+ " " _BUILD_STRING " $";
+static char sccsid[] = "@(#)NSPR " PR_VERSION _DEBUG_STRING
+ " " _BUILD_STRING;
+
+#endif /* XP_UNIX */
+
+PR_IMPLEMENT(const PRVersionDescription*) libVersionPoint()
+{
+#ifdef XP_UNIX
+ /*
+ * Add dummy references to rcsid and sccsid to prevent them
+ * from being optimized away as unused variables.
+ */
+ const char *dummy;
+
+ dummy = rcsid;
+ dummy = sccsid;
+#endif
+ return &VERSION_DESC_NAME;
+} /* versionEntryPointType */
+
+/* plvrsion.c */
+
diff --git a/src/libs/xpcom18a4/nsprpub/lib/libc/src/strcat.c b/src/libs/xpcom18a4/nsprpub/lib/libc/src/strcat.c
new file mode 100644
index 00000000..f71b0974
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/libc/src/strcat.c
@@ -0,0 +1,81 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "plstr.h"
+#include <string.h>
+
+PR_IMPLEMENT(char *)
+PL_strcat(char *dest, const char *src)
+{
+ if( ((char *)0 == dest) || ((const char *)0 == src) )
+ return dest;
+
+ return strcat(dest, src);
+}
+
+PR_IMPLEMENT(char *)
+PL_strncat(char *dest, const char *src, PRUint32 max)
+{
+ char *rv;
+
+ if( ((char *)0 == dest) || ((const char *)0 == src) || (0 == max) )
+ return dest;
+
+ for( rv = dest; *dest; dest++ )
+ ;
+
+ (void)PL_strncpy(dest, src, max);
+ return rv;
+}
+
+PR_IMPLEMENT(char *)
+PL_strcatn(char *dest, PRUint32 max, const char *src)
+{
+ char *rv;
+ PRUint32 dl;
+
+ if( ((char *)0 == dest) || ((const char *)0 == src) )
+ return dest;
+
+ for( rv = dest, dl = 0; *dest; dest++, dl++ )
+ ;
+
+ if( max <= dl ) return rv;
+ (void)PL_strncpyz(dest, src, max-dl);
+
+ return rv;
+}
diff --git a/src/libs/xpcom18a4/nsprpub/lib/libc/src/strccmp.c b/src/libs/xpcom18a4/nsprpub/lib/libc/src/strccmp.c
new file mode 100644
index 00000000..ec877484
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/libc/src/strccmp.c
@@ -0,0 +1,115 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "plstr.h"
+
+static const unsigned char uc[] =
+{
+ '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
+ '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
+ '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
+ '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
+ ' ', '!', '"', '#', '$', '%', '&', '\'',
+ '(', ')', '*', '+', ',', '-', '.', '/',
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', ':', ';', '<', '=', '>', '?',
+ '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
+ 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
+ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
+ 'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
+ '`', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
+ 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
+ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
+ 'X', 'Y', 'Z', '{', '|', '}', '~', '\177',
+ 0200, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
+ 0210, 0211, 0212, 0213, 0214, 0215, 0216, 0217,
+ 0220, 0221, 0222, 0223, 0224, 0225, 0226, 0227,
+ 0230, 0231, 0232, 0233, 0234, 0235, 0236, 0237,
+ 0240, 0241, 0242, 0243, 0244, 0245, 0246, 0247,
+ 0250, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
+ 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
+ 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
+ 0300, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
+ 0310, 0311, 0312, 0313, 0314, 0315, 0316, 0317,
+ 0320, 0321, 0322, 0323, 0324, 0325, 0326, 0327,
+ 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
+ 0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
+ 0350, 0351, 0352, 0353, 0354, 0355, 0356, 0357,
+ 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
+ 0370, 0371, 0372, 0373, 0374, 0375, 0376, 0377
+};
+
+PR_IMPLEMENT(PRIntn)
+PL_strcasecmp(const char *a, const char *b)
+{
+ const unsigned char *ua = (const unsigned char *)a;
+ const unsigned char *ub = (const unsigned char *)b;
+
+ if( ((const char *)0 == a) || (const char *)0 == b )
+ return (PRIntn)(a-b);
+
+ while( (uc[*ua] == uc[*ub]) && ('\0' != *a) )
+ {
+ a++;
+ ua++;
+ ub++;
+ }
+
+ return (PRIntn)(uc[*ua] - uc[*ub]);
+}
+
+PR_IMPLEMENT(PRIntn)
+PL_strncasecmp(const char *a, const char *b, PRUint32 max)
+{
+ const unsigned char *ua = (const unsigned char *)a;
+ const unsigned char *ub = (const unsigned char *)b;
+
+ if( ((const char *)0 == a) || (const char *)0 == b )
+ return (PRIntn)(a-b);
+
+ while( max && (uc[*ua] == uc[*ub]) && ('\0' != *a) )
+ {
+ a++;
+ ua++;
+ ub++;
+ max--;
+ }
+
+ if( 0 == max ) return (PRIntn)0;
+
+ return (PRIntn)(uc[*ua] - uc[*ub]);
+}
diff --git a/src/libs/xpcom18a4/nsprpub/lib/libc/src/strchr.c b/src/libs/xpcom18a4/nsprpub/lib/libc/src/strchr.c
new file mode 100644
index 00000000..35ccedcc
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/libc/src/strchr.c
@@ -0,0 +1,88 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "plstr.h"
+#include <string.h>
+
+PR_IMPLEMENT(char *)
+PL_strchr(const char *s, char c)
+{
+ if( (const char *)0 == s ) return (char *)0;
+
+ return strchr(s, c);
+}
+
+PR_IMPLEMENT(char *)
+PL_strrchr(const char *s, char c)
+{
+ if( (const char *)0 == s ) return (char *)0;
+
+ return strrchr(s, c);
+}
+
+PR_IMPLEMENT(char *)
+PL_strnchr(const char *s, char c, PRUint32 n)
+{
+ if( (const char *)0 == s ) return (char *)0;
+
+ for( ; n && *s; s++, n-- )
+ if( *s == c )
+ return (char *)s;
+
+ if( ((char)0 == c) && (n > 0) && ((char)0 == *s) ) return (char *)s;
+
+ return (char *)0;
+}
+
+PR_IMPLEMENT(char *)
+PL_strnrchr(const char *s, char c, PRUint32 n)
+{
+ const char *p;
+
+ if( (const char *)0 == s ) return (char *)0;
+
+ for( p = s; n && *p; p++, n-- )
+ ;
+
+ if( ((char)0 == c) && (n > 0) && ((char)0 == *p) ) return (char *)p;
+
+ for( p--; p >= s; p-- )
+ if( *p == c )
+ return (char *)p;
+
+ return (char *)0;
+}
diff --git a/src/libs/xpcom18a4/nsprpub/lib/libc/src/strcmp.c b/src/libs/xpcom18a4/nsprpub/lib/libc/src/strcmp.c
new file mode 100644
index 00000000..095e1784
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/libc/src/strcmp.c
@@ -0,0 +1,57 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "plstr.h"
+#include <string.h>
+
+PR_IMPLEMENT(PRIntn)
+PL_strcmp(const char *a, const char *b)
+{
+ if( ((const char *)0 == a) || (const char *)0 == b )
+ return (PRIntn)(a-b);
+
+ return (PRIntn)strcmp(a, b);
+}
+
+PR_IMPLEMENT(PRIntn)
+PL_strncmp(const char *a, const char *b, PRUint32 max)
+{
+ if( ((const char *)0 == a) || (const char *)0 == b )
+ return (PRIntn)(a-b);
+
+ return (PRIntn)strncmp(a, b, (size_t)max);
+}
diff --git a/src/libs/xpcom18a4/nsprpub/lib/libc/src/strcpy.c b/src/libs/xpcom18a4/nsprpub/lib/libc/src/strcpy.c
new file mode 100644
index 00000000..b576b677
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/libc/src/strcpy.c
@@ -0,0 +1,84 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "plstr.h"
+#include <string.h>
+
+PR_IMPLEMENT(char *)
+PL_strcpy(char *dest, const char *src)
+{
+ if( ((char *)0 == dest) || ((const char *)0 == src) ) return (char *)0;
+
+ return strcpy(dest, src);
+}
+
+PR_IMPLEMENT(char *)
+PL_strncpy(char *dest, const char *src, PRUint32 max)
+{
+ char *rv;
+
+ if( (char *)0 == dest ) return (char *)0;
+ if( (const char *)0 == src ) return (char *)0;
+
+ for( rv = dest; max && ((*dest = *src) != 0); dest++, src++, max-- )
+ ;
+
+#ifdef JLRU
+ /* XXX I (wtc) think the -- and ++ operators should be postfix. */
+ while( --max )
+ *++dest = '\0';
+#endif /* JLRU */
+
+ return rv;
+}
+
+PR_IMPLEMENT(char *)
+PL_strncpyz(char *dest, const char *src, PRUint32 max)
+{
+ char *rv;
+
+ if( (char *)0 == dest ) return (char *)0;
+ if( (const char *)0 == src ) return (char *)0;
+ if( 0 == max ) return (char *)0;
+
+ for( rv = dest, max--; max && ((*dest = *src) != 0); dest++, src++, max-- )
+ ;
+
+ *dest = '\0';
+
+ return rv;
+}
diff --git a/src/libs/xpcom18a4/nsprpub/lib/libc/src/strcstr.c b/src/libs/xpcom18a4/nsprpub/lib/libc/src/strcstr.c
new file mode 100644
index 00000000..cb587788
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/libc/src/strcstr.c
@@ -0,0 +1,123 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "plstr.h"
+
+PR_IMPLEMENT(char *)
+PL_strcasestr(const char *big, const char *little)
+{
+ PRUint32 ll;
+
+ if( ((const char *)0 == big) || ((const char *)0 == little) ) return (char *)0;
+ if( ((char)0 == *big) || ((char)0 == *little) ) return (char *)0;
+
+ ll = PL_strlen(little);
+
+ for( ; *big; big++ )
+ /* obvious improvement available here */
+ if( 0 == PL_strncasecmp(big, little, ll) )
+ return (char *)big;
+
+ return (char *)0;
+}
+
+PR_IMPLEMENT(char *)
+PL_strcaserstr(const char *big, const char *little)
+{
+ const char *p;
+ PRUint32 ll;
+
+ if( ((const char *)0 == big) || ((const char *)0 == little) ) return (char *)0;
+ if( ((char)0 == *big) || ((char)0 == *little) ) return (char *)0;
+
+ ll = PL_strlen(little);
+ p = &big[ PL_strlen(big) - ll ];
+ if( p < big ) return (char *)0;
+
+ for( ; p >= big; p-- )
+ /* obvious improvement available here */
+ if( 0 == PL_strncasecmp(p, little, ll) )
+ return (char *)p;
+
+ return (char *)0;
+}
+
+PR_IMPLEMENT(char *)
+PL_strncasestr(const char *big, const char *little, PRUint32 max)
+{
+ PRUint32 ll;
+
+ if( ((const char *)0 == big) || ((const char *)0 == little) ) return (char *)0;
+ if( ((char)0 == *big) || ((char)0 == *little) ) return (char *)0;
+
+ ll = PL_strlen(little);
+ if( ll > max ) return (char *)0;
+ max -= ll;
+ max++;
+
+ for( ; max && *big; big++, max-- )
+ /* obvious improvement available here */
+ if( 0 == PL_strncasecmp(big, little, ll) )
+ return (char *)big;
+
+ return (char *)0;
+}
+
+PR_IMPLEMENT(char *)
+PL_strncaserstr(const char *big, const char *little, PRUint32 max)
+{
+ const char *p;
+ PRUint32 ll;
+
+ if( ((const char *)0 == big) || ((const char *)0 == little) ) return (char *)0;
+ if( ((char)0 == *big) || ((char)0 == *little) ) return (char *)0;
+
+ ll = PL_strlen(little);
+
+ for( p = big; max && *p; p++, max-- )
+ ;
+
+ p -= ll;
+ if( p < big ) return (char *)0;
+
+ for( ; p >= big; p-- )
+ /* obvious improvement available here */
+ if( 0 == PL_strncasecmp(p, little, ll) )
+ return (char *)p;
+
+ return (char *)0;
+}
diff --git a/src/libs/xpcom18a4/nsprpub/lib/libc/src/strdup.c b/src/libs/xpcom18a4/nsprpub/lib/libc/src/strdup.c
new file mode 100644
index 00000000..f5fe61ad
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/libc/src/strdup.c
@@ -0,0 +1,100 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "plstr.h"
+#include "prmem.h"
+#include <string.h>
+#ifdef VBOX_USE_IPRT_IN_NSPR
+#include <iprt/mem.h>
+#endif
+
+PR_IMPLEMENT(char *)
+PL_strdup(const char *s)
+{
+ char *rv;
+ size_t n;
+
+ if( (const char *)0 == s )
+ s = "";
+
+ n = strlen(s) + 1;
+
+#ifdef VBOX_USE_IPRT_IN_NSPR
+ rv = (char *)RTMemAlloc(n);
+#else
+ rv = (char *)malloc(n);
+#endif
+ if( (char *)0 == rv ) return rv;
+
+ (void)memcpy(rv, s, n);
+
+ return rv;
+}
+
+PR_IMPLEMENT(void)
+PL_strfree(char *s)
+{
+#ifdef VBOX_USE_IPRT_IN_NSPR
+ RTMemFree(s);
+#else
+ free(s);
+#endif
+}
+
+PR_IMPLEMENT(char *)
+PL_strndup(const char *s, PRUint32 max)
+{
+ char *rv;
+ size_t l;
+
+ if( (const char *)0 == s )
+ s = "";
+
+ l = PL_strnlen(s, max);
+
+#ifdef VBOX_USE_IPRT_IN_NSPR
+ rv = (char *)RTMemAlloc(l+1);
+#else
+ rv = (char *)malloc(l+1);
+#endif
+ if( (char *)0 == rv ) return rv;
+
+ (void)memcpy(rv, s, l);
+ rv[l] = '\0';
+
+ return rv;
+}
diff --git a/src/libs/xpcom18a4/nsprpub/lib/libc/src/strlen.c b/src/libs/xpcom18a4/nsprpub/lib/libc/src/strlen.c
new file mode 100644
index 00000000..6c476777
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/libc/src/strlen.c
@@ -0,0 +1,71 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "plstr.h"
+#include "prtypes.h"
+#include "prlog.h"
+#include <string.h>
+
+PR_IMPLEMENT(PRUint32)
+PL_strlen(const char *str)
+{
+ size_t l;
+
+ if( (const char *)0 == str ) return 0;
+
+ l = strlen(str);
+
+ /* error checking in case we have a 64-bit platform -- make sure
+ * we don't have ultra long strings that overflow an int32
+ */
+ if( sizeof(PRUint32) < sizeof(size_t) )
+ PR_ASSERT(l < 2147483647);
+
+ return (PRUint32)l;
+}
+
+PR_IMPLEMENT(PRUint32)
+PL_strnlen(const char *str, PRUint32 max)
+{
+ register const char *s;
+
+ if( (const char *)0 == str ) return 0;
+ for( s = str; max && *s; s++, max-- )
+ ;
+
+ return (PRUint32)(s - str);
+}
diff --git a/src/libs/xpcom18a4/nsprpub/lib/libc/src/strpbrk.c b/src/libs/xpcom18a4/nsprpub/lib/libc/src/strpbrk.c
new file mode 100644
index 00000000..afcb4f51
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/libc/src/strpbrk.c
@@ -0,0 +1,100 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "plstr.h"
+#include <string.h>
+
+PR_IMPLEMENT(char *)
+PL_strpbrk(const char *s, const char *list)
+{
+ if( ((const char *)0 == s) || ((const char *)0 == list) ) return (char *)0;
+
+ return strpbrk(s, list);
+}
+
+PR_IMPLEMENT(char *)
+PL_strprbrk(const char *s, const char *list)
+{
+ const char *p;
+ const char *r;
+
+ if( ((const char *)0 == s) || ((const char *)0 == list) ) return (char *)0;
+
+ for( r = s; *r; r++ )
+ ;
+
+ for( r--; r >= s; r-- )
+ for( p = list; *p; p++ )
+ if( *r == *p )
+ return (char *)r;
+
+ return (char *)0;
+}
+
+PR_IMPLEMENT(char *)
+PL_strnpbrk(const char *s, const char *list, PRUint32 max)
+{
+ const char *p;
+
+ if( ((const char *)0 == s) || ((const char *)0 == list) ) return (char *)0;
+
+ for( ; max && *s; s++, max-- )
+ for( p = list; *p; p++ )
+ if( *s == *p )
+ return (char *)s;
+
+ return (char *)0;
+}
+
+PR_IMPLEMENT(char *)
+PL_strnprbrk(const char *s, const char *list, PRUint32 max)
+{
+ const char *p;
+ const char *r;
+
+ if( ((const char *)0 == s) || ((const char *)0 == list) ) return (char *)0;
+
+ for( r = s; max && *r; r++, max-- )
+ ;
+
+ for( r--; r >= s; r-- )
+ for( p = list; *p; p++ )
+ if( *r == *p )
+ return (char *)r;
+
+ return (char *)0;
+}
diff --git a/src/libs/xpcom18a4/nsprpub/lib/libc/src/strstr.c b/src/libs/xpcom18a4/nsprpub/lib/libc/src/strstr.c
new file mode 100644
index 00000000..6bc03d37
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/libc/src/strstr.c
@@ -0,0 +1,117 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "plstr.h"
+#include <string.h>
+
+PR_IMPLEMENT(char *)
+PL_strstr(const char *big, const char *little)
+{
+ if( ((const char *)0 == big) || ((const char *)0 == little) ) return (char *)0;
+ if( ((char)0 == *big) || ((char)0 == *little) ) return (char *)0;
+
+ return strstr(big, little);
+}
+
+PR_IMPLEMENT(char *)
+PL_strrstr(const char *big, const char *little)
+{
+ const char *p;
+ size_t ll;
+ size_t bl;
+
+ if( ((const char *)0 == big) || ((const char *)0 == little) ) return (char *)0;
+ if( ((char)0 == *big) || ((char)0 == *little) ) return (char *)0;
+
+ ll = strlen(little);
+ bl = strlen(big);
+ if( bl < ll ) return (char *)0;
+ p = &big[ bl - ll ];
+
+ for( ; p >= big; p-- )
+ if( *little == *p )
+ if( 0 == strncmp(p, little, ll) )
+ return (char *)p;
+
+ return (char *)0;
+}
+
+PR_IMPLEMENT(char *)
+PL_strnstr(const char *big, const char *little, PRUint32 max)
+{
+ size_t ll;
+
+ if( ((const char *)0 == big) || ((const char *)0 == little) ) return (char *)0;
+ if( ((char)0 == *big) || ((char)0 == *little) ) return (char *)0;
+
+ ll = strlen(little);
+ if( ll > (size_t)max ) return (char *)0;
+ max -= (PRUint32)ll;
+ max++;
+
+ for( ; max && *big; big++, max-- )
+ if( *little == *big )
+ if( 0 == strncmp(big, little, ll) )
+ return (char *)big;
+
+ return (char *)0;
+}
+
+PR_IMPLEMENT(char *)
+PL_strnrstr(const char *big, const char *little, PRUint32 max)
+{
+ const char *p;
+ size_t ll;
+
+ if( ((const char *)0 == big) || ((const char *)0 == little) ) return (char *)0;
+ if( ((char)0 == *big) || ((char)0 == *little) ) return (char *)0;
+
+ ll = strlen(little);
+
+ for( p = big; max && *p; p++, max-- )
+ ;
+
+ p -= ll;
+ if( p < big ) return (char *)0;
+
+ for( ; p >= big; p-- )
+ if( *little == *p )
+ if( 0 == strncmp(p, little, ll) )
+ return (char *)p;
+
+ return (char *)0;
+}
diff --git a/src/libs/xpcom18a4/nsprpub/lib/libc/src/strtok.c b/src/libs/xpcom18a4/nsprpub/lib/libc/src/strtok.c
new file mode 100644
index 00000000..400e9a4c
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/libc/src/strtok.c
@@ -0,0 +1,89 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2001
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Roland Mainz <roland mainz@informatik.med.uni-giessen.de>
+ *
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "plstr.h"
+
+PR_IMPLEMENT(char *)
+PL_strtok_r(char *s1, const char *s2, char **lasts)
+{
+ const char *sepp;
+ int c, sc;
+ char *tok;
+
+ if( s1 == NULL )
+ {
+ if( *lasts == NULL )
+ return NULL;
+
+ s1 = *lasts;
+ }
+
+ for( ; (c = *s1) != 0; s1++ )
+ {
+ for( sepp = s2 ; (sc = *sepp) != 0 ; sepp++ )
+ {
+ if( c == sc )
+ break;
+ }
+ if( sc == 0 )
+ break;
+ }
+
+ if( c == 0 )
+ {
+ *lasts = NULL;
+ return NULL;
+ }
+
+ tok = s1++;
+
+ for( ; (c = *s1) != 0; s1++ )
+ {
+ for( sepp = s2; (sc = *sepp) != 0; sepp++ )
+ {
+ if( c == sc )
+ {
+ *s1++ = '\0';
+ *lasts = s1;
+ return tok;
+ }
+ }
+ }
+ *lasts = NULL;
+ return tok;
+}
diff --git a/src/libs/xpcom18a4/nsprpub/lib/msgc/.cvsignore b/src/libs/xpcom18a4/nsprpub/lib/msgc/.cvsignore
new file mode 100644
index 00000000..f3c7a7c5
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/msgc/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/src/libs/xpcom18a4/nsprpub/lib/msgc/Makefile.in b/src/libs/xpcom18a4/nsprpub/lib/msgc/Makefile.in
new file mode 100644
index 00000000..d7299b2b
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/msgc/Makefile.in
@@ -0,0 +1,52 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# 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 MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+MOD_DEPTH = ../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/config.mk
+
+DIRS = include src tests
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(TARGETS)
+
diff --git a/src/libs/xpcom18a4/nsprpub/lib/msgc/include/.cvsignore b/src/libs/xpcom18a4/nsprpub/lib/msgc/include/.cvsignore
new file mode 100644
index 00000000..f3c7a7c5
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/msgc/include/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/src/libs/xpcom18a4/nsprpub/lib/msgc/include/MANIFEST b/src/libs/xpcom18a4/nsprpub/lib/msgc/include/MANIFEST
new file mode 100644
index 00000000..a45ec20e
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/msgc/include/MANIFEST
@@ -0,0 +1,5 @@
+#
+# This is a list of local files which get copied to the mozilla:dist directory
+#
+
+prgc.h
diff --git a/src/libs/xpcom18a4/nsprpub/lib/msgc/include/Makefile.in b/src/libs/xpcom18a4/nsprpub/lib/msgc/include/Makefile.in
new file mode 100644
index 00000000..60803a02
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/msgc/include/Makefile.in
@@ -0,0 +1,61 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# 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 MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#! gmake
+
+MOD_DEPTH = ../../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+include $(topsrcdir)/config/config.mk
+
+EXPORT_HEADERS = prgc.h
+HEADERS = $(EXPORT_HEADERS) gcint.h
+
+RELEASE_HEADERS = $(EXPORT_HEADERS)
+RELEASE_HEADERS_DEST = $(RELEASE_INCLUDE_DIR)
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(EXPORT_HEADERS)
+ $(INSTALL) -m 444 $(EXPORT_HEADERS) $(dist_includedir)
+ifeq ($(MOZ_BITS),16)
+ $(INSTALL) -m 444 $(EXPORT_HEADERS) $(MOZ_INCL)
+endif
+
diff --git a/src/libs/xpcom18a4/nsprpub/lib/msgc/include/gcint.h b/src/libs/xpcom18a4/nsprpub/lib/msgc/include/gcint.h
new file mode 100644
index 00000000..10048f06
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/msgc/include/gcint.h
@@ -0,0 +1,129 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef gcint_h___
+#define gcint_h___
+
+#include "prmon.h"
+#include "prgc.h"
+
+extern PRLogModuleInfo *_pr_msgc_lm;
+extern GCInfo _pr_gcData;
+
+#if defined(_WIN32) && !defined(DEBUG)
+#undef INLINE_LOCK
+#endif
+
+#ifdef INLINE_LOCK
+#define LOCK_GC() EnterCriticalSection(&_pr_gcData.lock->mutexHandle)
+#define UNLOCK_GC() LeaveCriticalSection(&_pr_gcData.lock->mutexHandle)
+#else
+#define LOCK_GC() PR_EnterMonitor(_pr_gcData.lock)
+#define UNLOCK_GC() PR_ExitMonitor (_pr_gcData.lock)
+#define GC_IS_LOCKED() (PR_GetMonitorEntryCount(_pr_gcData.lock)!=0)
+#endif
+
+#ifdef DEBUG
+#define _GCTRACE(x, y) if (_pr_gcData.flags & x) GCTrace y
+#else
+#define _GCTRACE(x, y)
+#endif
+
+extern GCBeginGCHook *_pr_beginGCHook;
+extern void *_pr_beginGCHookArg;
+extern GCBeginGCHook *_pr_endGCHook;
+extern void *_pr_endGCHookArg;
+
+extern GCBeginFinalizeHook *_pr_beginFinalizeHook;
+extern void *_pr_beginFinalizeHookArg;
+extern GCBeginFinalizeHook *_pr_endFinalizeHook;
+extern void *_pr_endFinalizeHookArg;
+
+extern int _pr_do_a_dump;
+extern FILE *_pr_dump_file;
+
+extern PRLogModuleInfo *_pr_gc_lm;
+
+/*
+** Root finders. Root finders are used by the GC to find pointers into
+** the GC heap that are not contained in the GC heap.
+*/
+typedef struct RootFinderStr RootFinder;
+
+struct RootFinderStr {
+ RootFinder *next;
+ GCRootFinder *func;
+ char *name;
+ void *arg;
+};
+extern RootFinder *_pr_rootFinders;
+
+typedef struct CollectorTypeStr {
+ GCType gctype;
+ PRUint32 flags;
+} CollectorType;
+
+#define GC_MAX_TYPES 256
+extern CollectorType *_pr_collectorTypes;
+
+#define _GC_TYPE_BUSY 0x1
+#define _GC_TYPE_FINAL 0x2
+#define _GC_TYPE_WEAK 0x4
+
+/* Slot in _pr_gcTypes used for free memory */
+#define FREE_MEMORY_TYPEIX 255
+
+extern void _PR_InitGC(PRWord flags);
+extern void _MD_InitGC(void);
+extern void PR_CALLBACK _PR_ScanFinalQueue(void *notused);
+
+/*
+** Grow the GC Heap.
+*/
+extern void *_MD_GrowGCHeap(PRUint32 *sizep);
+
+/*
+** Extend the GC Heap.
+*/
+extern PRBool _MD_ExtendGCHeap(char *base, PRInt32 oldSize, PRInt32 newSize);
+
+/*
+** Free a GC segment.
+*/
+extern void _MD_FreeGCSegment(void *base, PRInt32 len);
+
+#endif /* gcint_h___ */
diff --git a/src/libs/xpcom18a4/nsprpub/lib/msgc/include/prgc.h b/src/libs/xpcom18a4/nsprpub/lib/msgc/include/prgc.h
new file mode 100644
index 00000000..add30213
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/msgc/include/prgc.h
@@ -0,0 +1,419 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef prgc_h___
+#define prgc_h___
+
+/*
+** API to NSPR gc memory system.
+*/
+#include "prtypes.h"
+#include "prmon.h"
+#include "prthread.h"
+#include <stdio.h>
+
+#if defined(WIN16)
+#define GCPTR __far
+#else
+#define GCPTR
+#endif
+
+
+PR_BEGIN_EXTERN_C
+
+/*
+** Initialize the garbage collector.
+** "flags" is the trace flags (see below).
+** "initialHeapSize" is the initial size of the heap and may be zero
+** if the default is desired.
+** "segmentSize" is the size of each segment of memory added to the
+** heap when the heap is grown.
+*/
+PR_EXTERN(void) PR_InitGC(
+ PRWord flags, PRInt32 initialHeapSize, PRInt32 segmentSize, PRThreadScope scope);
+
+/*
+** Shuts down gc and frees up all memory associated with it.
+*/
+PR_EXTERN(void) PR_ShutdownGC(PRBool finalizeOnExit);
+
+/*
+** This walk function will be called for every gc object in the
+** heap as it is walked. If it returns non-zero, the walk is terminated.
+*/
+typedef PRInt32 (*PRWalkFun)(void GCPTR* obj, void* data);
+
+/*
+** GC Type record. This defines all of the GC operations used on a
+** particular object type. These structures are passed to
+** PR_RegisterType.
+*/
+typedef struct GCType {
+ /*
+ ** Scan an object that is in the GC heap and call GCInfo.livePointer
+ ** on all of the pointers in it. If this slot is null then the object
+ ** won't be scanned (i.e. it has no embedded pointers).
+ */
+ void (PR_CALLBACK *scan)(void GCPTR *obj);
+
+ /*
+ ** Finalize an object that has no references. This is called by the
+ ** GC after it has determined where the object debris is but before
+ ** it has moved the debris to the logical "free list". The object is
+ ** marked alive for this call and removed from the list of objects
+ ** that need finalization (finalization only happens once for an
+ ** object). If this slot is null then the object doesn't need
+ ** finalization.
+ */
+ void (PR_CALLBACK *finalize)(void GCPTR *obj);
+
+ /*
+ ** Dump out an object during a PR_DumpGCHeap(). This is used as a
+ ** debugging tool.
+ */
+ void (PR_CALLBACK *dump)(FILE *out, void GCPTR *obj, PRBool detailed, PRIntn indentLevel);
+
+ /*
+ ** Add object to summary table.
+ */
+ void (PR_CALLBACK *summarize)(void GCPTR *obj, PRUint32 bytes);
+
+ /*
+ ** Free hook called by GC when the object is being freed.
+ */
+ void (PR_CALLBACK *free)(void *obj);
+
+ /* Weak pointer support: If the object has a weak pointer (Note:
+ at most one), this function is used to get the weak link's
+ offset from the start of the body of a gc object */
+ PRUint32 (PR_CALLBACK *getWeakLinkOffset)(void *obj);
+
+ /* Descriptive character for dumping this GCType */
+ char kindChar;
+
+ /*
+ ** Walker routine. This routine should apply fun(obj->ptr, data)
+ ** for every gc pointer within the object.
+ */
+ PRInt32 (PR_CALLBACK *walk)(void GCPTR *obj, PRWalkFun fun, void* data);
+} GCType;
+
+/*
+** This data structure must be added as the hash table passed to
+** the summarize method of GCType.
+*/
+typedef struct PRSummaryEntry {
+ void* clazz;
+ PRInt32 instancesCount;
+ PRInt32 totalSize;
+} PRSummaryEntry;
+
+/*
+** This function pointer must be registered by users of nspr
+** to produce the finally summary after all object in the
+** heap have been visited.
+*/
+typedef void (PR_CALLBACK *PRSummaryPrinter)(FILE *out, void* closure);
+
+PR_EXTERN(void) PR_CALLBACK PR_RegisterSummaryPrinter(PRSummaryPrinter fun, void* closure);
+
+typedef void PR_CALLBACK GCRootFinder(void *arg);
+typedef void PR_CALLBACK GCBeginFinalizeHook(void *arg);
+typedef void PR_CALLBACK GCEndFinalizeHook(void *arg);
+typedef void PR_CALLBACK GCBeginGCHook(void *arg);
+typedef void PR_CALLBACK GCEndGCHook(void *arg);
+
+typedef enum { PR_GCBEGIN, PR_GCEND } GCLockHookArg;
+
+typedef void PR_CALLBACK GCLockHookFunc(GCLockHookArg arg1, void *arg2);
+
+typedef struct GCLockHook GCLockHook;
+
+struct GCLockHook {
+ GCLockHookFunc* func;
+ void* arg;
+ GCLockHook* next;
+ GCLockHook* prev;
+};
+
+
+/*
+** Hooks which are called at the beginning and end of the GC process.
+** The begin hooks are called before the root finding step. The hooks are
+** called with threading disabled, so it is now allowed to re-enter the
+** kernel. The end hooks are called after the gc has finished but before
+** the finalizer has run.
+*/
+PR_EXTERN(void) PR_CALLBACK PR_SetBeginGCHook(GCBeginGCHook *hook, void *arg);
+PR_EXTERN(void) PR_CALLBACK PR_GetBeginGCHook(GCBeginGCHook **hook, void **arg);
+PR_EXTERN(void) PR_CALLBACK PR_SetEndGCHook(GCBeginGCHook *hook, void *arg);
+PR_EXTERN(void) PR_CALLBACK PR_GetEndGCHook(GCEndGCHook **hook, void **arg);
+
+/*
+** Called before SuspendAll is called by dogc, so that GC thread can hold
+** all the locks before hand to avoid any deadlocks
+*/
+
+/*
+PR_EXTERN(void) PR_SetGCLockHook(GCLockHook *hook, void *arg);
+PR_EXTERN(void) PR_GetGCLockHook(GCLockHook **hook, void **arg);
+*/
+
+PR_EXTERN(int) PR_RegisterGCLockHook(GCLockHookFunc *hook, void *arg);
+
+/*
+** Hooks which are called at the beginning and end of the GC finalization
+** process. After the GC has identified all of the dead objects in the
+** heap, it looks for objects that need finalization. Before it calls the
+** first finalization proc (see the GCType structure above) it calls the
+** begin hook. When it has finalized the last object it calls the end
+** hook.
+*/
+PR_EXTERN(void) PR_SetBeginFinalizeHook(GCBeginFinalizeHook *hook, void *arg);
+PR_EXTERN(void) PR_GetBeginFinalizeHook(GCBeginFinalizeHook **hook, void **arg);
+PR_EXTERN(void) PR_SetEndFinalizeHook(GCBeginFinalizeHook *hook, void *arg);
+PR_EXTERN(void) PR_GetEndFinalizeHook(GCEndFinalizeHook **hook, void **arg);
+
+/*
+** Register a GC type. Return's the index into the GC internal type
+** table. The returned value is passed to PR_AllocMemory. After the call,
+** the "type" memory belongs to the GC (the caller must not free it or
+** change it).
+*/
+PR_EXTERN(PRInt32) PR_RegisterType(GCType *type);
+
+/*
+** Register a root finder with the collector. The collector will call
+** these functions to identify all of the roots before collection
+** proceeds. "arg" is passed to the function when it is called.
+*/
+PR_EXTERN(PRStatus) PR_RegisterRootFinder(GCRootFinder func, char *name, void *arg);
+
+/*
+** Allocate some GC'able memory. The object must be at least bytes in
+** size. The type index function for the object is specified. "flags"
+** specifies some control flags. If PR_ALLOC_CLEAN is set then the memory
+** is zero'd before being returned. If PR_ALLOC_DOUBLE is set then the
+** allocated memory is double aligned.
+**
+** Any memory cell that you store a pointer to something allocated by
+** this call must be findable by the GC. Use the PR_RegisterRootFinder to
+** register new places where the GC will look for pointers into the heap.
+** The GC already knows how to scan any NSPR threads or monitors.
+*/
+PR_EXTERN(PRWord GCPTR *)PR_AllocMemory(
+ PRWord bytes, PRInt32 typeIndex, PRWord flags);
+PR_EXTERN(PRWord GCPTR *)PR_AllocSimpleMemory(
+ PRWord bytes, PRInt32 typeIndex);
+
+/*
+** This function can be used to cause PR_AllocMemory to always return
+** NULL. This may be useful in low memory situations when we're trying to
+** shutdown applets.
+*/
+PR_EXTERN(void) PR_EnableAllocation(PRBool yesOrNo);
+
+/* flags bits */
+#define PR_ALLOC_CLEAN 0x1
+#define PR_ALLOC_DOUBLE 0x2
+#define PR_ALLOC_ZERO_HANDLE 0x4 /* XXX yes, it's a hack */
+
+/*
+** Force a garbage collection right now. Return when it completes.
+*/
+PR_EXTERN(void) PR_GC(void);
+
+/*
+** Force a finalization right now. Return when finalization has
+** completed. Finalization completes when there are no more objects
+** pending finalization. This does not mean there are no objects in the
+** gc heap that will need finalization should a collection be done after
+** this call.
+*/
+PR_EXTERN(void) PR_ForceFinalize(void);
+
+/*
+** Dump the GC heap out to the given file. This will stop the system dead
+** in its tracks while it is occuring.
+*/
+PR_EXTERN(void) PR_DumpGCHeap(FILE *out, PRBool detailed);
+
+/*
+** Wrapper for PR_DumpGCHeap
+*/
+PR_EXTERN(void) PR_DumpMemory(PRBool detailed);
+
+/*
+** Dump summary of objects allocated.
+*/
+PR_EXTERN(void) PR_DumpMemorySummary(void);
+
+/*
+** Dump the application heaps.
+*/
+PR_EXTERN(void) PR_DumpApplicationHeaps(void);
+
+/*
+** Helper function used by dump routines to do the indentation in a
+** consistent fashion.
+*/
+PR_EXTERN(void) PR_DumpIndent(FILE *out, PRIntn indent);
+
+/*
+** The GCInfo structure contains all of the GC state...
+**
+** busyMemory:
+** The amount of GC heap memory that is busy at this instant. Busy
+** doesn't mean alive, it just means that it has been
+** allocated. Immediately after a collection busy means how much is
+** alive.
+**
+** freeMemory:
+** The amount of GC heap memory that is as yet unallocated.
+**
+** allocMemory:
+** The sum of free and busy memory in the GC heap.
+**
+** maxMemory:
+** The maximum size that the GC heap is allowed to grow.
+**
+** lowSeg:
+** The lowest segment currently used in the GC heap.
+**
+** highSeg:
+** The highest segment currently used in the GC heap.
+** The lowSeg and highSeg members are used for a "quick test" of whether
+** a pointer falls within the GC heap. [ see GC_IN_HEAP(...) ]
+**
+** lock:
+** Monitor used for syncronization within the GC.
+**
+** finalizer:
+** Thread in which the GC finalizer is running.
+**
+** liveBlock:
+** Object scanning functions call through this function pointer to
+** register a potential block of pointers with the collector. (This is
+** currently not at all different than processRoot.)
+**
+** livePointer:
+** Object scanning functions call through this function pointer to
+** register a single pointer with the collector.
+**
+** processRootBlock:
+** When a root finder identifies a root it should call through this
+** function pointer so that the GC can process the root. The call takes
+** a base address and count which the gc will examine for valid heap
+** pointers.
+**
+** processRootPointer:
+** When a root finder identifies a root it should call through this
+** function pointer so that the GC can process the root. The call takes
+** a single pointer value.
+*/
+typedef struct GCInfoStr {
+ PRWord flags; /* trace flags (see below) */
+ PRWord busyMemory; /* memory in use right now */
+ PRWord freeMemory; /* memory free right now */
+ PRWord allocMemory; /* sum of busy & free memory */
+ PRWord maxMemory; /* max memory we are allowed to allocate */
+ PRWord *lowSeg; /* lowest segment in the GC heap */
+ PRWord *highSeg; /* higest segment in the GC heap */
+
+ PRMonitor *lock;
+ PRThread *finalizer;
+
+ void (PR_CALLBACK *liveBlock)(void **base, PRInt32 count);
+ void (PR_CALLBACK *livePointer)(void *ptr);
+ void (PR_CALLBACK *processRootBlock)(void **base, PRInt32 count);
+ void (PR_CALLBACK *processRootPointer)(void *ptr);
+ FILE* dumpOutput;
+#ifdef GCTIMINGHOOK
+ void (*gcTimingHook)(int32 gcTime);
+#endif
+} GCInfo;
+
+PR_EXTERN(GCInfo *) PR_GetGCInfo(void);
+PR_EXTERN(PRBool) PR_GC_In_Heap(void GCPTR *object);
+
+/*
+** Simple bounds check to see if a pointer is anywhere near the GC heap.
+** Used to avoid calls to PR_ProcessRoot and GCInfo.livePointer by object
+** scanning code.
+*/
+#if !defined(XP_PC) || defined(_WIN32)
+#define GC_IN_HEAP(_info, _p) (((PRWord*)(_p) >= (_info)->lowSeg) && \
+ ((PRWord*)(_p) < (_info)->highSeg))
+#else
+/*
+** The simple bounds check, above, doesn't work in Win16, because we don't
+** maintain: lowSeg == MIN(all segments) and highSeg == MAX(all segments).
+** So we have to do a little better.
+*/
+#define GC_IN_HEAP(_info, _p) PR_GC_In_Heap(_p)
+#endif
+
+PR_EXTERN(PRWord) PR_GetObjectHeader(void *ptr);
+
+PR_EXTERN(PRWord) PR_SetObjectHeader(void *ptr, PRWord newUserBits);
+
+/************************************************************************/
+
+/* Trace flags (passed to PR_InitGC or in environment GCLOG) */
+#define GC_TRACE 0x0001
+#define GC_ROOTS 0x0002
+#define GC_LIVE 0x0004
+#define GC_ALLOC 0x0008
+#define GC_MARK 0x0010
+#define GC_SWEEP 0x0020
+#define GC_DEBUG 0x0040
+#define GC_FINAL 0x0080
+
+#if defined(DEBUG_kipp) || defined(DEBUG_warren)
+#define GC_CHECK 0x0100
+#endif
+
+#ifdef DEBUG
+#define GCTRACE(x, y) if (PR_GetGCInfo()->flags & x) GCTrace y
+PR_EXTERN(void) GCTrace(char *fmt, ...);
+#else
+#define GCTRACE(x, y)
+#endif
+
+PR_END_EXTERN_C
+
+#endif /* prgc_h___ */
diff --git a/src/libs/xpcom18a4/nsprpub/lib/msgc/src/.cvsignore b/src/libs/xpcom18a4/nsprpub/lib/msgc/src/.cvsignore
new file mode 100644
index 00000000..f3c7a7c5
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/msgc/src/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/src/libs/xpcom18a4/nsprpub/lib/msgc/src/Makefile.in b/src/libs/xpcom18a4/nsprpub/lib/msgc/src/Makefile.in
new file mode 100644
index 00000000..e822fc29
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/msgc/src/Makefile.in
@@ -0,0 +1,103 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# 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 MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#! gmake
+
+MOD_DEPTH = ../../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/config.mk
+
+INCLUDES = -I$(dist_includedir) -I../include
+
+CSRCS = prgcapi.c prmsgc.c
+
+ifeq ($(OS_ARCH),WINNT)
+CSRCS += win32gc.c
+else
+ifeq ($(OS_ARCH),OS2)
+CSRCS += os2gc.c
+else
+CSRCS += unixgc.c
+endif
+endif
+
+NSPR_VERSION = $(MOD_MAJOR_VERSION)
+
+EXTRA_LIBS = $(LIBNSPR)
+
+ifdef RESOLVE_LINK_SYMBOLS
+EXTRA_LIBS += $(OS_LIBS)
+endif
+
+ifeq ($(OS_ARCH), WINNT)
+ifdef NS_USE_GCC
+DLLBASE=-Wl,--image-base -Wl,0x30000000
+else
+DLLBASE=/BASE:0x30000000
+endif # GCC
+#RES=$(OBJDIR)/ds.res
+#RESNAME=$(MOD_DEPTH)/pr/src/nspr.rc
+#OS_LIBS = user32.lib
+endif # WINNT
+
+LIBRARY_NAME = msgc
+LIBRARY_VERSION = $(MOD_MAJOR_VERSION)
+
+RELEASE_LIBS = $(TARGETS)
+
+include $(topsrcdir)/config/rules.mk
+
+#
+# The Client build wants the shared libraries in $(dist_bindir),
+# so we also install them there.
+#
+
+export:: $(TARGETS)
+ $(INSTALL) -m 444 $(TARGETS) $(dist_libdir)
+ifdef SHARED_LIBRARY
+ $(INSTALL) -m 444 $(SHARED_LIBRARY) $(dist_bindir)
+endif
+ifeq ($(MOZ_BITS),16)
+ $(INSTALL) -m 444 $(TARGETS) $(MOZ_DIST)/lib
+ $(INSTALL) -m 444 $(TARGETS) $(MOZ_DIST)/bin
+endif
+
diff --git a/src/libs/xpcom18a4/nsprpub/lib/msgc/src/macgc.c b/src/libs/xpcom18a4/nsprpub/lib/msgc/src/macgc.c
new file mode 100644
index 00000000..eafc28e8
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/msgc/src/macgc.c
@@ -0,0 +1,75 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "primpl.h"
+#include "MacMemAllocator.h"
+
+void _MD_InitGC() {}
+
+void *_MD_GrowGCHeap(size_t *sizep)
+{
+ void *heapPtr = NULL;
+ size_t heapSize = *sizep;
+
+ // In previous versions of this code we tried to allocate GC heaps from the application
+ // heap. In the 4.0 application, we try to keep our app heap allications to a minimum
+ // and instead go through our own memory allocation routines.
+ heapPtr = malloc(heapSize);
+
+ if (heapPtr == NULL) {
+ FreeMemoryStats stats;
+
+ memtotal(heapSize, &stats); // How much can we allcoate?
+
+ if (stats.maxBlockSize < heapSize)
+ heapSize = stats.maxBlockSize;
+
+ heapPtr = malloc(heapSize);
+
+ if (heapPtr == NULL) // Now we're hurting
+ heapSize = 0;
+ }
+
+ *sizep = heapSize;
+ return heapPtr;
+}
+
+
+void _MD_FreeGCSegment(void *base, int32 /* len */)
+{
+ free(base);
+}
diff --git a/src/libs/xpcom18a4/nsprpub/lib/msgc/src/os2gc.c b/src/libs/xpcom18a4/nsprpub/lib/msgc/src/os2gc.c
new file mode 100644
index 00000000..f99bb678
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/msgc/src/os2gc.c
@@ -0,0 +1,83 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * GC related routines
+ *
+ */
+#include "prlog.h"
+
+#include <stdlib.h>
+
+/* Leave a bit of room for any malloc header bytes... */
+#define MAX_SEGMENT_SIZE (65536L - 4096L)
+
+/************************************************************************/
+/*
+** Machine dependent GC Heap management routines:
+** _MD_GrowGCHeap
+*/
+/************************************************************************/
+void _MD_InitGC() {}
+
+void *_MD_GrowGCHeap(PRUint32 *sizep)
+{
+ void *addr;
+
+ if ( *sizep > MAX_SEGMENT_SIZE )
+ {
+ *sizep = MAX_SEGMENT_SIZE;
+ }
+
+ addr = malloc((size_t)*sizep);
+ return addr;
+}
+
+
+PRBool _MD_ExtendGCHeap(char *base, PRInt32 oldSize, PRInt32 newSize) {
+ /* Not sure about this. Todd? */
+ return PR_FALSE;
+}
+
+
+void _MD_FreeGCSegment(void *base, PRInt32 len)
+{
+ if (base)
+ {
+ free(base);
+ }
+}
diff --git a/src/libs/xpcom18a4/nsprpub/lib/msgc/src/prgcapi.c b/src/libs/xpcom18a4/nsprpub/lib/msgc/src/prgcapi.c
new file mode 100644
index 00000000..23f7ea51
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/msgc/src/prgcapi.c
@@ -0,0 +1,351 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include <stdarg.h>
+#include <string.h>
+#include <stdio.h>
+#include "prenv.h"
+#include "prmem.h"
+#include "prmon.h"
+#include "prlog.h"
+#include "prthread.h"
+#if defined(XP_MAC)
+#include "pprthred.h"
+#else
+#include "private/pprthred.h"
+#endif
+#include "gcint.h"
+
+/*
+** Generic GC implementation independent code for the NSPR GC
+*/
+
+RootFinder *_pr_rootFinders;
+
+CollectorType *_pr_collectorTypes;
+
+/* GC State information */
+GCInfo _pr_gcData;
+
+GCBeginGCHook *_pr_beginGCHook;
+void *_pr_beginGCHookArg;
+GCBeginGCHook *_pr_endGCHook;
+void *_pr_endGCHookArg;
+
+GCBeginFinalizeHook *_pr_beginFinalizeHook;
+void *_pr_beginFinalizeHookArg;
+GCBeginFinalizeHook *_pr_endFinalizeHook;
+void *_pr_endFinalizeHookArg;
+
+FILE *_pr_dump_file;
+int _pr_do_a_dump;
+GCLockHook *_pr_GCLockHook;
+
+extern PRLogModuleInfo *_pr_msgc_lm;
+
+/************************************************************************/
+
+static PRStatus PR_CALLBACK
+pr_ScanOneThread(PRThread* t, void** addr, PRUword count, void* closure)
+{
+#if defined(XP_MAC)
+#pragma unused (t, closure)
+#endif
+
+ _pr_gcData.processRootBlock(addr, count);
+ return PR_SUCCESS;
+}
+
+/*
+** Scan all of the threads C stack's and registers, looking for "root"
+** pointers into the GC heap. These are the objects that the GC cannot
+** move and are considered "live" by the GC. Caller has stopped all of
+** the threads from running.
+*/
+static void PR_CALLBACK ScanThreads(void *arg)
+{
+ PR_ScanStackPointers(pr_ScanOneThread, arg);
+}
+
+/************************************************************************/
+
+PR_IMPLEMENT(GCInfo *) PR_GetGCInfo(void)
+{
+ return &_pr_gcData;
+}
+
+
+PR_IMPLEMENT(PRInt32) PR_RegisterType(GCType *t)
+{
+ CollectorType *ct, *ect;
+ int rv = -1;
+
+ LOCK_GC();
+ ct = &_pr_collectorTypes[0];
+ ect = &_pr_collectorTypes[FREE_MEMORY_TYPEIX];
+ for (; ct < ect; ct++) {
+ if (ct->flags == 0) {
+ ct->gctype = *t;
+ ct->flags = _GC_TYPE_BUSY;
+ if (0 != ct->gctype.finalize) {
+ ct->flags |= _GC_TYPE_FINAL;
+ }
+ if (0 != ct->gctype.getWeakLinkOffset) {
+ ct->flags |= _GC_TYPE_WEAK;
+ }
+ rv = ct - &_pr_collectorTypes[0];
+ break;
+ }
+ }
+ UNLOCK_GC();
+ return rv;
+}
+
+PR_IMPLEMENT(PRStatus) PR_RegisterRootFinder(
+ GCRootFinder f, char *name, void *arg)
+{
+ RootFinder *rf = PR_NEWZAP(RootFinder);
+ if (rf) {
+ rf->func = f;
+ rf->name = name;
+ rf->arg = arg;
+
+ LOCK_GC();
+ rf->next = _pr_rootFinders;
+ _pr_rootFinders = rf;
+ UNLOCK_GC();
+ return PR_SUCCESS;
+ }
+ return PR_FAILURE;
+}
+
+
+PR_IMPLEMENT(int) PR_RegisterGCLockHook(GCLockHookFunc* f, void *arg)
+{
+
+ GCLockHook *rf = 0;
+
+ rf = (GCLockHook*) calloc(1, sizeof(GCLockHook));
+ if (rf) {
+ rf->func = f;
+ rf->arg = arg;
+
+ LOCK_GC();
+ /* first dummy node */
+ if (! _pr_GCLockHook) {
+ _pr_GCLockHook = (GCLockHook*) calloc(1, sizeof(GCLockHook));
+ _pr_GCLockHook->next = _pr_GCLockHook;
+ _pr_GCLockHook->prev = _pr_GCLockHook;
+ }
+
+ rf->next = _pr_GCLockHook;
+ rf->prev = _pr_GCLockHook->prev;
+ _pr_GCLockHook->prev->next = rf;
+ _pr_GCLockHook->prev = rf;
+ UNLOCK_GC();
+ return 0;
+ }
+ return -1;
+}
+
+/*
+PR_IMPLEMENT(void) PR_SetGCLockHook(GCLockHook *hook, void *arg)
+{
+ LOCK_GC();
+ _pr_GCLockHook = hook;
+ _pr_GCLockHookArg2 = arg;
+ UNLOCK_GC();
+}
+
+PR_IMPLEMENT(void) PR_GetGCLockHook(GCLockHook **hook, void **arg)
+{
+ LOCK_GC();
+ *hook = _pr_GCLockHook;
+ *arg = _pr_GCLockHookArg2;
+ UNLOCK_GC();
+}
+*/
+
+
+PR_IMPLEMENT(void) PR_SetBeginGCHook(GCBeginGCHook *hook, void *arg)
+{
+ LOCK_GC();
+ _pr_beginGCHook = hook;
+ _pr_beginGCHookArg = arg;
+ UNLOCK_GC();
+}
+
+PR_IMPLEMENT(void) PR_GetBeginGCHook(GCBeginGCHook **hook, void **arg)
+{
+ LOCK_GC();
+ *hook = _pr_beginGCHook;
+ *arg = _pr_beginGCHookArg;
+ UNLOCK_GC();
+}
+
+PR_IMPLEMENT(void) PR_SetEndGCHook(GCEndGCHook *hook, void *arg)
+{
+ LOCK_GC();
+ _pr_endGCHook = hook;
+ _pr_endGCHookArg = arg;
+ UNLOCK_GC();
+}
+
+PR_IMPLEMENT(void) PR_GetEndGCHook(GCEndGCHook **hook, void **arg)
+{
+ LOCK_GC();
+ *hook = _pr_endGCHook;
+ *arg = _pr_endGCHookArg;
+ UNLOCK_GC();
+}
+
+PR_IMPLEMENT(void) PR_SetBeginFinalizeHook(GCBeginFinalizeHook *hook, void *arg)
+{
+ LOCK_GC();
+ _pr_beginFinalizeHook = hook;
+ _pr_beginFinalizeHookArg = arg;
+ UNLOCK_GC();
+}
+
+PR_IMPLEMENT(void) PR_GetBeginFinalizeHook(GCBeginFinalizeHook **hook,
+ void **arg)
+{
+ LOCK_GC();
+ *hook = _pr_beginFinalizeHook;
+ *arg = _pr_beginFinalizeHookArg;
+ UNLOCK_GC();
+}
+
+PR_IMPLEMENT(void) PR_SetEndFinalizeHook(GCEndFinalizeHook *hook, void *arg)
+{
+ LOCK_GC();
+ _pr_endFinalizeHook = hook;
+ _pr_endFinalizeHookArg = arg;
+ UNLOCK_GC();
+}
+
+PR_IMPLEMENT(void) PR_GetEndFinalizeHook(GCEndFinalizeHook **hook, void **arg)
+{
+ LOCK_GC();
+ *hook = _pr_endFinalizeHook;
+ *arg = _pr_endFinalizeHookArg;
+ UNLOCK_GC();
+}
+
+#ifdef DEBUG
+#include "prprf.h"
+
+#if defined(WIN16)
+static FILE *tracefile = 0;
+#endif
+
+PR_IMPLEMENT(void) GCTrace(char *fmt, ...)
+{
+ va_list ap;
+ char buf[400];
+
+ va_start(ap, fmt);
+ PR_vsnprintf(buf, sizeof(buf), fmt, ap);
+ va_end(ap);
+#if defined(WIN16)
+ if ( tracefile == 0 )
+ {
+ tracefile = fopen( "xxxGCtr", "w" );
+ }
+ fprintf(tracefile, "%s\n", buf );
+ fflush(tracefile);
+#else
+ PR_LOG(_pr_msgc_lm, PR_LOG_ALWAYS, ("%s", buf));
+#endif
+}
+#endif
+
+void _PR_InitGC(PRWord flags)
+{
+ static char firstTime = 1;
+
+ if (!firstTime) return;
+ firstTime = 0;
+
+ _MD_InitGC();
+
+ if (flags == 0) {
+ char *ev = PR_GetEnv("GCLOG");
+ if (ev && ev[0]) {
+ flags = atoi(ev);
+ }
+ }
+ _pr_gcData.flags = flags;
+
+ _pr_gcData.lock = PR_NewMonitor();
+
+ _pr_collectorTypes = (CollectorType*) PR_CALLOC(256 * sizeof(CollectorType));
+
+ PR_RegisterRootFinder(ScanThreads, "scan threads", 0);
+ PR_RegisterRootFinder(_PR_ScanFinalQueue, "scan final queue", 0);
+}
+
+extern void pr_FinalizeOnExit(void);
+
+#ifdef DEBUG
+#ifdef GC_STATS
+PR_PUBLIC_API(void) PR_PrintGCAllocStats(void);
+#endif
+#endif
+
+PR_IMPLEMENT(void)
+PR_ShutdownGC(PRBool finalizeOnExit)
+{
+ /* first finalize all the objects in the heap */
+ if (finalizeOnExit) {
+ pr_FinalizeOnExit();
+ }
+
+#ifdef DEBUG
+#ifdef GC_STATS
+ PR_PrintGCAllocStats();
+#endif /* GC_STATS */
+#endif /* DEBUG */
+
+ /* then the chance for any future allocations */
+
+ /* finally delete the gc heap */
+
+ /* write me */
+}
+
+/******************************************************************************/
diff --git a/src/libs/xpcom18a4/nsprpub/lib/msgc/src/prmsgc.c b/src/libs/xpcom18a4/nsprpub/lib/msgc/src/prmsgc.c
new file mode 100644
index 00000000..ad0566a4
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/msgc/src/prmsgc.c
@@ -0,0 +1,3514 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include <string.h>
+#include <stddef.h>
+#include <stdarg.h>
+#include <time.h>
+
+#ifdef WIN32
+#include <windef.h>
+#include <winbase.h>
+#endif
+
+#include "prclist.h"
+#include "prbit.h"
+
+#include "prtypes.h"
+#include "prenv.h"
+#include "prgc.h"
+#include "prthread.h"
+#include "prlog.h"
+#include "prlong.h"
+#include "prinrval.h"
+#include "prprf.h"
+#include "gcint.h"
+
+#if defined(XP_MAC)
+#include "pprthred.h"
+#else
+#include "private/pprthred.h"
+#endif
+
+typedef void (*PRFileDumper)(FILE *out, PRBool detailed);
+
+PR_EXTERN(void)
+PR_DumpToFile(char* filename, char* msg, PRFileDumper dump, PRBool detailed);
+
+/*
+** Mark&sweep garbage collector. Supports objects that require
+** finalization, objects that can have a single weak link, and special
+** objects that require care during sweeping.
+*/
+
+PRLogModuleInfo *_pr_msgc_lm;
+PRLogModuleInfo* GC;
+
+static PRInt32 _pr_pageShift;
+static PRInt32 _pr_pageSize;
+
+#ifdef DEBUG
+#define GCMETER
+#endif
+#ifdef DEBUG_jwz
+# undef GCMETER
+#endif /* 1 */
+
+#ifdef GCMETER
+#define METER(x) x
+#else
+#define METER(x)
+#endif
+
+/*
+** Make this constant bigger to reduce the amount of recursion during
+** garbage collection.
+*/
+#define MAX_SCAN_Q 100L
+
+#if defined(XP_PC) && !defined(WIN32)
+#define MAX_SEGS 400L
+#define MAX_SEGMENT_SIZE (65536L - 4096L)
+#define SEGMENT_SIZE (65536L - 4096L)
+#define MAX_ALLOC_SIZE (65536L - 4096L)
+#else
+#define MAX_SEGS 400L
+#define MAX_SEGMENT_SIZE (2L * 256L * 1024L)
+#define SEGMENT_SIZE (1L * 256L * 1024L)
+#define MAX_ALLOC_SIZE (4L * 1024L * 1024L)
+#endif
+
+/*
+ * The highest value that can fit into a signed integer. This
+ * is used to prevent overflow of allocation size in alloc routines.
+ */
+
+#define MAX_INT ((1UL << (PR_BITS_PER_INT - 1)) - 1)
+
+/*
+ * On 32-bit machines, only 22 bits are used in the cibx integer to
+ * store size since 8 bits of the integer are used to store type, and
+ * of the remainder, 2 are user defined. Max allocation size = 2^22 -1
+ */
+
+#define MAX_ALLOC ( (1L << (PR_BYTES_PER_WORD_LOG2 + WORDS_BITS )) -1)
+
+/* The minimum percentage of free heap space after a collection. If
+ the amount of free space doesn't meet this criteria then we will
+ attempt to grow the heap */
+#ifdef XP_MAC
+#define MIN_FREE_THRESHOLD_AFTER_GC 10L
+#else
+#define MIN_FREE_THRESHOLD_AFTER_GC 20L
+#endif
+
+static PRInt32 segmentSize = SEGMENT_SIZE;
+
+static PRInt32 collectorCleanupNeeded;
+
+#ifdef GCMETER
+PRUint32 _pr_gcMeter;
+
+#define _GC_METER_STATS 0x01L
+#define _GC_METER_GROWTH 0x02L
+#define _GC_METER_FREE_LIST 0x04L
+#endif
+
+/************************************************************************/
+
+#define LINEAR_BIN_EXPONENT 5
+#define NUM_LINEAR_BINS ((PRUint32)1 << LINEAR_BIN_EXPONENT)
+#define FIRST_LOG_BIN (NUM_LINEAR_BINS - LINEAR_BIN_EXPONENT)
+
+/* Each free list bin holds a chunk of memory sized from
+ 2^n to (2^(n+1))-1 inclusive. */
+#define NUM_BINS (FIRST_LOG_BIN + 32)
+
+/*
+ * Find the bin number for a given size (in bytes). This does not round up as
+ * values from 2^n to (2^(n+1))-1 share the same bin.
+ */
+#define InlineBinNumber(_bin,_bytes) \
+{ \
+ PRUint32 _t, _n = (PRUint32) _bytes / 4; \
+ if (_n < NUM_LINEAR_BINS) { \
+ _bin = _n; \
+ } else { \
+ _bin = FIRST_LOG_BIN; \
+ if ((_t = (_n >> 16)) != 0) { _bin += 16; _n = _t; } \
+ if ((_t = (_n >> 8)) != 0) { _bin += 8; _n = _t; } \
+ if ((_t = (_n >> 4)) != 0) { _bin += 4; _n = _t; } \
+ if ((_t = (_n >> 2)) != 0) { _bin += 2; _n = _t; } \
+ if ((_n >> 1) != 0) _bin++; \
+ } \
+}
+
+#define BIG_ALLOC 16384L
+
+#define MIN_FREE_CHUNK_BYTES ((PRInt32)sizeof(GCFreeChunk))
+
+/* Note: fix code in PR_AllocMemory if you change the size of GCFreeChunk
+ so that it zeros the right number of words */
+typedef struct GCFreeChunk {
+ struct GCFreeChunk *next;
+ struct GCSeg *segment;
+ PRInt32 chunkSize;
+} GCFreeChunk;
+
+typedef struct GCSegInfo {
+ struct GCSegInfo *next;
+ char *base;
+ char *limit;
+ PRWord *hbits;
+ int fromMalloc;
+} GCSegInfo;
+
+typedef struct GCSeg {
+ char *base;
+ char *limit;
+ PRWord *hbits;
+ GCSegInfo *info;
+} GCSeg;
+
+#ifdef GCMETER
+typedef struct GCMeter {
+ PRInt32 allocBytes;
+ PRInt32 wastedBytes;
+ PRInt32 numFreeChunks;
+ PRInt32 skippedFreeChunks;
+} GCMeter;
+static GCMeter meter;
+#endif
+
+/*
+** There is one of these for each segment of GC'able memory.
+*/
+static GCSeg segs[MAX_SEGS];
+static GCSegInfo *freeSegs;
+static GCSeg* lastInHeap;
+static int nsegs;
+
+static GCFreeChunk *bins[NUM_BINS];
+static PRInt32 minBin;
+static PRInt32 maxBin;
+
+/*
+** Scan Q used to avoid deep recursion when scanning live objects for
+** heap pointers
+*/
+typedef struct GCScanQStr {
+ PRWord *q[MAX_SCAN_Q];
+ int queued;
+} GCScanQ;
+
+static GCScanQ *pScanQ;
+
+#ifdef GCMETER
+PRInt32 _pr_maxScanDepth;
+PRInt32 _pr_scanDepth;
+#endif
+
+/*
+** Keeps track of the number of bytes allocated via the BigAlloc()
+** allocator. When the number of bytes allocated, exceeds the
+** BIG_ALLOC_GC_SIZE, then a GC will occur before the next allocation
+** is done...
+*/
+#define BIG_ALLOC_GC_SIZE (4*SEGMENT_SIZE)
+static PRWord bigAllocBytes = 0;
+
+/*
+** There is one GC header word in front of each GC allocated object. We
+** use it to contain information about the object (what TYPEIX to use for
+** scanning it, how big it is, it's mark status, and if it's a root).
+*/
+#define TYPEIX_BITS 8L
+#define WORDS_BITS 20L
+#define MAX_CBS (1L << GC_TYPEIX_BITS)
+#define MAX_WORDS (1L << GC_WORDS_BITS)
+#define TYPEIX_SHIFT 24L
+#define MAX_TYPEIX ((1L << TYPEIX_BITS) - 1L)
+#define TYPEIX_MASK PR_BITMASK(TYPEIX_BITS)
+#define WORDS_SHIFT 2L
+#define WORDS_MASK PR_BITMASK(WORDS_BITS)
+#define MARK_BIT 1L
+#define FINAL_BIT 2L
+
+/* Two bits per object header are reserved for the user of the memory
+ system to store information into. */
+#define GC_USER_BITS_SHIFT 22L
+#define GC_USER_BITS 0x00c00000L
+
+#define MAKE_HEADER(_cbix,_words) \
+ ((PRWord) (((unsigned long)(_cbix) << TYPEIX_SHIFT) \
+ | ((unsigned long)(_words) << WORDS_SHIFT)))
+
+#define GET_TYPEIX(_h) \
+ (((PRUword)(_h) >> TYPEIX_SHIFT) & 0xff)
+
+#define MARK(_sp,_p) \
+ (((PRWord *)(_p))[0] |= MARK_BIT)
+#define IS_MARKED(_sp,_p) \
+ (((PRWord *)(_p))[0] & MARK_BIT)
+#define OBJ_BYTES(_h) \
+ (((PRInt32) (_h) & 0x003ffffcL) << (PR_BYTES_PER_WORD_LOG2-2L))
+
+#define GC_GET_USER_BITS(_h) (((_h) & GC_USER_BITS) >> GC_USER_BITS_SHIFT)
+
+/************************************************************************/
+
+/*
+** Mark the start of an object in a segment. Note that we mark the header
+** word (which we always have), not the data word (which we may not have
+** for empty objects).
+** XXX tune: put subtract of _sp->base into _sp->hbits pointer?
+*/
+#if !defined(WIN16)
+#define SET_HBIT(_sp,_ph) \
+ SET_BIT((_sp)->hbits, (((PRWord*)(_ph)) - ((PRWord*) (_sp)->base)))
+
+#define CLEAR_HBIT(_sp,_ph) \
+ CLEAR_BIT((_sp)->hbits, (((PRWord*)(_ph)) - ((PRWord*) (_sp)->base)))
+
+#define IS_HBIT(_sp,_ph) \
+ TEST_BIT((_sp)->hbits, (((PRWord*)(_ph)) - ((PRWord*) (_sp)->base)))
+#else
+
+#define SET_HBIT(_sp,_ph) set_hbit(_sp,_ph)
+
+#define CLEAR_HBIT(_sp,_ph) clear_hbit(_sp,_ph)
+
+#define IS_HBIT(_sp,_ph) is_hbit(_sp,_ph)
+
+static void
+set_hbit(GCSeg *sp, PRWord *p)
+{
+ unsigned int distance;
+ unsigned int index;
+ PRWord mask;
+
+ PR_ASSERT( SELECTOROF(p) == SELECTOROF(sp->base) );
+ PR_ASSERT( OFFSETOF(p) >= OFFSETOF(sp->base) );
+
+ distance = (OFFSETOF(p) - OFFSETOF(sp->base)) >> 2;
+ index = distance >> PR_BITS_PER_WORD_LOG2;
+ mask = 1L << (distance&(PR_BITS_PER_WORD-1));
+
+ sp->hbits[index] |= mask;
+}
+
+static void
+clear_hbit(GCSeg *sp, PRWord *p)
+{
+ unsigned int distance;
+ unsigned int index;
+ PRWord mask;
+
+ PR_ASSERT( SELECTOROF(p) == SELECTOROF(sp->base) );
+ PR_ASSERT( OFFSETOF(p) >= OFFSETOF(sp->base) );
+
+ distance = (OFFSETOF(p) - OFFSETOF(sp->base)) >> 2;
+ index = distance >> PR_BITS_PER_WORD_LOG2;
+ mask = 1L << (distance&(PR_BITS_PER_WORD-1));
+
+ sp->hbits[index] &= ~mask;
+}
+
+static int
+is_hbit(GCSeg *sp, PRWord *p)
+{
+ unsigned int distance;
+ unsigned int index;
+ PRWord mask;
+
+ PR_ASSERT( SELECTOROF(p) == SELECTOROF(sp->base) );
+ PR_ASSERT( OFFSETOF(p) >= OFFSETOF(sp->base) );
+
+ distance = (OFFSETOF(p) - OFFSETOF(sp->base)) >> 2;
+ index = distance >> PR_BITS_PER_WORD_LOG2;
+ mask = 1L << (distance&(PR_BITS_PER_WORD-1));
+
+ return ((sp->hbits[index] & mask) != 0);
+}
+
+
+#endif /* WIN16 */
+
+/*
+** Given a pointer into this segment, back it up until we are at the
+** start of the object the pointer points into. Each heap segment has a
+** bitmap that has one bit for each word of the objects it contains. The
+** bit's are set for the firstword of an object, and clear for it's other
+** words.
+*/
+static PRWord *FindObject(GCSeg *sp, PRWord *p)
+{
+ PRWord *base;
+
+ /* Align p to it's proper boundary before we start fiddling with it */
+ p = (PRWord*) ((PRWord)p & ~(PR_BYTES_PER_WORD-1L));
+
+ base = (PRWord *) sp->base;
+#if defined(WIN16)
+ PR_ASSERT( SELECTOROF(p) == SELECTOROF(base));
+#endif
+ do {
+ if (IS_HBIT(sp, p)) {
+ return (p);
+ }
+ p--;
+ } while ( p >= base );
+
+ /* Heap is corrupted! */
+ _GCTRACE(GC_TRACE, ("ERROR: The heap is corrupted!!! aborting now!"));
+ abort();
+ return NULL;
+}
+
+/************************************************************************/
+#if !defined(XP_PC) || defined(XP_OS2)
+#define OutputDebugString(msg)
+#endif
+
+#if !defined(WIN16)
+#define IN_SEGMENT(_sp, _p) \
+ ((((char *)(_p)) >= (_sp)->base) && \
+ (((char *)(_p)) < (_sp)->limit))
+#else
+#define IN_SEGMENT(_sp, _p) \
+ ((((PRWord)(_p)) >= ((PRWord)(_sp)->base)) && \
+ (((PRWord)(_p)) < ((PRWord)(_sp)->limit)))
+#endif
+
+static GCSeg *InHeap(void *p)
+{
+ GCSeg *sp, *esp;
+
+ if (lastInHeap && IN_SEGMENT(lastInHeap, p)) {
+ return lastInHeap;
+ }
+
+ sp = segs;
+ esp = segs + nsegs;
+ for (; sp < esp; sp++) {
+ if (IN_SEGMENT(sp, p)) {
+ lastInHeap = sp;
+ return sp;
+ }
+ }
+ return 0;
+}
+
+/*
+** Grow the heap by allocating another segment. Fudge the requestedSize
+** value to try to pre-account for the HBITS.
+*/
+static GCSeg* DoGrowHeap(PRInt32 requestedSize, PRBool exactly)
+{
+ GCSeg *sp;
+ GCSegInfo *segInfo;
+ GCFreeChunk *cp;
+ char *base;
+ PRWord *hbits;
+ PRInt32 nhbytes, nhbits;
+ PRUint32 allocSize;
+
+ if (nsegs == MAX_SEGS) {
+ /* No room for more segments */
+ return 0;
+ }
+
+ segInfo = (GCSegInfo*) PR_MALLOC(sizeof(GCSegInfo));
+#ifdef DEBUG
+ {
+ char str[256];
+ sprintf(str, "[1] Allocated %ld bytes at %p\n",
+ (long) sizeof(GCSegInfo), segInfo);
+ OutputDebugString(str);
+ }
+#endif
+ if (!segInfo) {
+ return 0;
+ }
+
+#if defined(WIN16)
+ if (requestedSize > segmentSize) {
+ PR_DELETE(segInfo);
+ return 0;
+ }
+#endif
+
+ /* Get more memory from the OS */
+ if (exactly) {
+ allocSize = requestedSize;
+ base = (char *) PR_MALLOC(requestedSize);
+ } else {
+ allocSize = requestedSize;
+ allocSize = (allocSize + _pr_pageSize - 1L) >> _pr_pageShift;
+ allocSize <<= _pr_pageShift;
+ base = (char*)_MD_GrowGCHeap(&allocSize);
+ }
+ if (!base) {
+ PR_DELETE(segInfo);
+ return 0;
+ }
+
+ nhbits = (PRInt32)(
+ (allocSize + PR_BYTES_PER_WORD - 1L) >> PR_BYTES_PER_WORD_LOG2);
+ nhbytes = ((nhbits + PR_BITS_PER_WORD - 1L) >> PR_BITS_PER_WORD_LOG2)
+ * sizeof(PRWord);
+
+ /* Get bitmap memory from malloc heap */
+#if defined(WIN16)
+ PR_ASSERT( nhbytes < MAX_ALLOC_SIZE );
+#endif
+ hbits = (PRWord *) PR_CALLOC((PRUint32)nhbytes);
+ if (!hbits) {
+ /* Loser! */
+ PR_DELETE(segInfo);
+ if (exactly) {
+ PR_DELETE(base);
+ } else {
+ /* XXX do something about this */
+ /* _MD_FreeGCSegment(base, allocSize); */
+ }
+ return 0;
+ }
+
+ /*
+ ** Setup new segment.
+ */
+ sp = &segs[nsegs++];
+ segInfo->base = sp->base = base;
+ segInfo->limit = sp->limit = base + allocSize;
+ segInfo->hbits = sp->hbits = hbits;
+ sp->info = segInfo;
+ segInfo->fromMalloc = exactly;
+ memset(base, 0, allocSize);
+
+#ifdef GCMETER
+ if (_pr_gcMeter & _GC_METER_GROWTH) {
+ fprintf(stderr, "[GC: new segment base=%p size=%ld]\n",
+ sp->base, (long) allocSize);
+ }
+#endif
+
+ _pr_gcData.allocMemory += allocSize;
+ _pr_gcData.freeMemory += allocSize;
+
+ if (!exactly) {
+ PRInt32 bin;
+
+ /* Put free memory into a freelist bin */
+ cp = (GCFreeChunk *) base;
+ cp->segment = sp;
+ cp->chunkSize = allocSize;
+ InlineBinNumber(bin, allocSize)
+ cp->next = bins[bin];
+ bins[bin] = cp;
+ if (bin < minBin) minBin = bin;
+ if (bin > maxBin) maxBin = bin;
+ } else {
+ /*
+ ** When exactly allocating the entire segment is given over to a
+ ** single object to prevent fragmentation
+ */
+ }
+
+ if (!_pr_gcData.lowSeg) {
+ _pr_gcData.lowSeg = (PRWord*) sp->base;
+ _pr_gcData.highSeg = (PRWord*) sp->limit;
+ } else {
+ if ((PRWord*)sp->base < _pr_gcData.lowSeg) {
+ _pr_gcData.lowSeg = (PRWord*) sp->base;
+ }
+ if ((PRWord*)sp->limit > _pr_gcData.highSeg) {
+ _pr_gcData.highSeg = (PRWord*) sp->limit;
+ }
+ }
+
+ /*
+ ** Get rid of the GC pointer in case it shows up in some uninitialized
+ ** local stack variable later (while scanning the C stack looking for
+ ** roots).
+ */
+ memset(&base, 0, sizeof(base)); /* optimizers beware */
+
+ PR_LOG(_pr_msgc_lm, PR_LOG_WARNING, ("grow heap: total gc memory now %d",
+ _pr_gcData.allocMemory));
+
+ return sp;
+}
+
+#ifdef USE_EXTEND_HEAP
+static PRBool ExtendHeap(PRInt32 requestedSize) {
+ GCSeg* sp;
+ PRUint32 allocSize;
+ PRInt32 oldSize, newSize;
+ PRInt32 newHBits, newHBytes;
+ PRInt32 oldHBits, oldHBytes;
+ PRWord* hbits;
+ GCFreeChunk* cp;
+ PRInt32 bin;
+
+ /* Can't extend nothing */
+ if (nsegs == 0) return PR_FALSE;
+
+ /* Round up requested size to the size of a page */
+ allocSize = (PRUint32) requestedSize;
+ allocSize = (allocSize + _pr_pageSize - 1L) >> _pr_pageShift;
+ allocSize <<= _pr_pageShift;
+
+ /* Malloc some memory for the new hbits array */
+ sp = segs;
+ oldSize = sp->limit - sp->base;
+ newSize = oldSize + allocSize;
+ newHBits = (newSize + PR_BYTES_PER_WORD - 1L) >> PR_BYTES_PER_WORD_LOG2;
+ newHBytes = ((newHBits + PR_BITS_PER_WORD - 1L) >> PR_BITS_PER_WORD_LOG2)
+ * sizeof(PRWord);
+ hbits = (PRWord*) PR_MALLOC(newHBytes);
+ if (0 == hbits) return PR_FALSE;
+
+ /* Attempt to extend the last segment by the desired amount */
+ if (_MD_ExtendGCHeap(sp->base, oldSize, newSize)) {
+ oldHBits = (oldSize + PR_BYTES_PER_WORD - 1L) >> PR_BYTES_PER_WORD_LOG2;
+ oldHBytes = ((oldHBits + PR_BITS_PER_WORD - 1L) >> PR_BITS_PER_WORD_LOG2)
+ * sizeof(PRWord);
+
+ /* Copy hbits from old memory into new memory */
+ memset(hbits, 0, newHBytes);
+ memcpy(hbits, sp->hbits, oldHBytes);
+ PR_DELETE(sp->hbits);
+ memset(sp->base + oldSize, 0, allocSize);
+
+ /* Adjust segment state */
+ sp->limit += allocSize;
+ sp->hbits = hbits;
+ sp->info->limit = sp->limit;
+ sp->info->hbits = hbits;
+
+ /* Put free memory into a freelist bin */
+ cp = (GCFreeChunk *) (sp->base + oldSize);
+ cp->segment = sp;
+ cp->chunkSize = allocSize;
+ InlineBinNumber(bin, allocSize)
+ cp->next = bins[bin];
+ bins[bin] = cp;
+ if (bin < minBin) minBin = bin;
+ if (bin > maxBin) maxBin = bin;
+
+ /* Prevent a pointer that points to the free memory from showing
+ up on the call stack later on */
+ memset(&cp, 0, sizeof(cp));
+
+ /* Update heap brackets and counters */
+ if ((PRWord*)sp->limit > _pr_gcData.highSeg) {
+ _pr_gcData.highSeg = (PRWord*) sp->limit;
+ }
+ _pr_gcData.allocMemory += allocSize;
+ _pr_gcData.freeMemory += allocSize;
+
+ return PR_TRUE;
+ }
+ PR_DELETE(hbits);
+ return PR_FALSE;
+}
+#endif /* USE_EXTEND_HEAP */
+
+static GCSeg *GrowHeapExactly(PRInt32 requestedSize)
+{
+ GCSeg *sp = DoGrowHeap(requestedSize, PR_TRUE);
+ return sp;
+}
+
+static PRBool GrowHeap(PRInt32 requestedSize)
+{
+ void *p;
+#ifdef USE_EXTEND_HEAP
+ if (ExtendHeap(requestedSize)) {
+ return PR_TRUE;
+ }
+#endif
+ p = DoGrowHeap(requestedSize, PR_FALSE);
+ return (p != NULL ? PR_TRUE : PR_FALSE);
+}
+
+/*
+** Release a segment when it is entirely free.
+*/
+static void ShrinkGCHeap(GCSeg *sp)
+{
+#ifdef GCMETER
+ if (_pr_gcMeter & _GC_METER_GROWTH) {
+ fprintf(stderr, "[GC: free segment base=%p size=%ld]\n",
+ sp->base, (long) (sp->limit - sp->base));
+ }
+#endif
+
+ /*
+ * Put segment onto free seginfo list (we can't call free right now
+ * because we have the GC lock and all of the other threads are
+ * suspended; if one of them has the malloc lock we would deadlock)
+ */
+ sp->info->next = freeSegs;
+ freeSegs = sp->info;
+ collectorCleanupNeeded = 1;
+ _pr_gcData.allocMemory -= sp->limit - sp->base;
+ if (sp == lastInHeap) lastInHeap = 0;
+
+ /* Squish out disappearing segment from segment table */
+ --nsegs;
+ if ((sp - segs) != nsegs) {
+ *sp = segs[nsegs];
+ } else {
+ sp->base = 0;
+ sp->limit = 0;
+ sp->hbits = 0;
+ sp->info = 0;
+ }
+
+ /* Recalculate the lowSeg and highSeg values */
+ _pr_gcData.lowSeg = (PRWord*) segs[0].base;
+ _pr_gcData.highSeg = (PRWord*) segs[0].limit;
+ for (sp = segs; sp < &segs[nsegs]; sp++) {
+ if ((PRWord*)sp->base < _pr_gcData.lowSeg) {
+ _pr_gcData.lowSeg = (PRWord*) sp->base;
+ }
+ if ((PRWord*)sp->limit > _pr_gcData.highSeg) {
+ _pr_gcData.highSeg = (PRWord*) sp->limit;
+ }
+ }
+}
+
+static void FreeSegments(void)
+{
+ GCSegInfo *si;
+
+ while (0 != freeSegs) {
+ LOCK_GC();
+ si = freeSegs;
+ if (si) {
+ freeSegs = si->next;
+ }
+ UNLOCK_GC();
+
+ if (!si) {
+ break;
+ }
+ PR_DELETE(si->base);
+ PR_DELETE(si->hbits);
+ PR_DELETE(si);
+ }
+}
+
+/************************************************************************/
+
+void ScanScanQ(GCScanQ *iscan)
+{
+ PRWord *p;
+ PRWord **pp;
+ PRWord **epp;
+ GCScanQ nextQ, *scan, *next, *temp;
+ CollectorType *ct;
+
+ if (!iscan->queued) return;
+
+ _GCTRACE(GC_MARK, ("begin scanQ @ 0x%x (%d)", iscan, iscan->queued));
+ scan = iscan;
+ next = &nextQ;
+ while (scan->queued) {
+ _GCTRACE(GC_MARK, ("continue scanQ @ 0x%x (%d)", scan, scan->queued));
+ /*
+ * Set pointer to current scanQ so that _pr_gcData.livePointer
+ * can find it.
+ */
+ pScanQ = next;
+ next->queued = 0;
+
+ /* Now scan the scan Q */
+ pp = scan->q;
+ epp = &scan->q[scan->queued];
+ scan->queued = 0;
+ while (pp < epp) {
+ p = *pp++;
+ ct = &_pr_collectorTypes[GET_TYPEIX(p[0])];
+ PR_ASSERT(0 != ct->gctype.scan);
+ /* Scan object ... */
+ (*ct->gctype.scan)(p + 1);
+ }
+
+ /* Exchange pointers so that we scan next */
+ temp = scan;
+ scan = next;
+ next = temp;
+ }
+
+ pScanQ = iscan;
+ PR_ASSERT(nextQ.queued == 0);
+ PR_ASSERT(iscan->queued == 0);
+}
+
+/*
+** Called during root finding step to identify "root" pointers into the
+** GC heap. First validate if it is a real heap pointer and then mark the
+** object being pointed to and add it to the scan Q for eventual
+** scanning.
+*/
+static void PR_CALLBACK ProcessRootBlock(void **base, PRInt32 count)
+{
+ GCSeg *sp;
+ PRWord *p0, *p, h, tix, *low, *high, *segBase;
+ CollectorType *ct;
+#ifdef DEBUG
+ void **base0 = base;
+#endif
+
+ low = _pr_gcData.lowSeg;
+ high = _pr_gcData.highSeg;
+ while (--count >= 0) {
+ p0 = (PRWord*) *base++;
+ /*
+ ** XXX:
+ ** Until Win16 maintains lowSeg and highSeg correctly,
+ ** (ie. lowSeg=MIN(all segs) and highSeg = MAX(all segs))
+ ** Allways scan through the segment list
+ */
+#if !defined(WIN16)
+ if (p0 < low) continue; /* below gc heap */
+ if (p0 >= high) continue; /* above gc heap */
+#endif
+ /* NOTE: inline expansion of InHeap */
+ /* Find segment */
+ sp = lastInHeap;
+ if (!sp || !IN_SEGMENT(sp,p0)) {
+ GCSeg *esp;
+ sp = segs;
+ esp = segs + nsegs;
+ for (; sp < esp; sp++) {
+ if (IN_SEGMENT(sp, p0)) {
+ lastInHeap = sp;
+ goto find_object;
+ }
+ }
+ continue;
+ }
+
+ find_object:
+ /* NOTE: Inline expansion of FindObject */
+ /* Align p to it's proper boundary before we start fiddling with it */
+ p = (PRWord*) ((PRWord)p0 & ~(PR_BYTES_PER_WORD-1L));
+ segBase = (PRWord *) sp->base;
+ do {
+ if (IS_HBIT(sp, p)) {
+ goto winner;
+ }
+ p--;
+ } while (p >= segBase);
+
+ /*
+ ** We have a pointer into the heap, but it has no header
+ ** bit. This means that somehow the very first object in the heap
+ ** doesn't have a header. This is impossible so when debugging
+ ** lets abort.
+ */
+#ifdef DEBUG
+ PR_Abort();
+#endif
+
+ winner:
+ h = p[0];
+ if ((h & MARK_BIT) == 0) {
+#ifdef DEBUG
+ _GCTRACE(GC_ROOTS,
+ ("root 0x%p (%d) base0=%p off=%d",
+ p, OBJ_BYTES(h), base0, (base-1) - base0));
+#endif
+
+ /* Mark the root we just found */
+ p[0] = h | MARK_BIT;
+
+ /*
+ * See if object we just found needs scanning. It must
+ * have a scan function to be placed on the scanQ.
+ */
+ tix = (PRWord)GET_TYPEIX(h);
+ ct = &_pr_collectorTypes[tix];
+ if (0 == ct->gctype.scan) {
+ continue;
+ }
+
+ /*
+ ** Put a pointer onto the scan Q. We use the scan Q to avoid
+ ** deep recursion on the C call stack. Objects are added to
+ ** the scan Q until the scan Q fills up. At that point we
+ ** make a call to ScanScanQ which proceeds to scan each of
+ ** the objects in the Q. This limits the recursion level by a
+ ** large amount though the stack frames get larger to hold
+ ** the GCScanQ's.
+ */
+ pScanQ->q[pScanQ->queued++] = p;
+ if (pScanQ->queued == MAX_SCAN_Q) {
+ METER(_pr_scanDepth++);
+ ScanScanQ(pScanQ);
+ }
+ }
+ }
+}
+
+static void PR_CALLBACK ProcessRootPointer(void *ptr)
+{
+ PRWord *p0, *p, h, tix, *segBase;
+ GCSeg* sp;
+ CollectorType *ct;
+
+ p0 = (PRWord*) ptr;
+
+ /*
+ ** XXX:
+ ** Until Win16 maintains lowSeg and highSeg correctly,
+ ** (ie. lowSeg=MIN(all segs) and highSeg = MAX(all segs))
+ ** Allways scan through the segment list
+ */
+#if !defined(WIN16)
+ if (p0 < _pr_gcData.lowSeg) return; /* below gc heap */
+ if (p0 >= _pr_gcData.highSeg) return; /* above gc heap */
+#endif
+
+ /* NOTE: inline expansion of InHeap */
+ /* Find segment */
+ sp = lastInHeap;
+ if (!sp || !IN_SEGMENT(sp,p0)) {
+ GCSeg *esp;
+ sp = segs;
+ esp = segs + nsegs;
+ for (; sp < esp; sp++) {
+ if (IN_SEGMENT(sp, p0)) {
+ lastInHeap = sp;
+ goto find_object;
+ }
+ }
+ return;
+ }
+
+ find_object:
+ /* NOTE: Inline expansion of FindObject */
+ /* Align p to it's proper boundary before we start fiddling with it */
+ p = (PRWord*) ((PRWord)p0 & ~(BYTES_PER_WORD-1L));
+ segBase = (PRWord *) sp->base;
+ do {
+ if (IS_HBIT(sp, p)) {
+ goto winner;
+ }
+ p--;
+ } while (p >= segBase);
+
+ /*
+ ** We have a pointer into the heap, but it has no header
+ ** bit. This means that somehow the very first object in the heap
+ ** doesn't have a header. This is impossible so when debugging
+ ** lets abort.
+ */
+#ifdef DEBUG
+ PR_Abort();
+#endif
+
+ winner:
+ h = p[0];
+ if ((h & MARK_BIT) == 0) {
+#ifdef DEBUG
+ _GCTRACE(GC_ROOTS, ("root 0x%p (%d)", p, OBJ_BYTES(h)));
+#endif
+
+ /* Mark the root we just found */
+ p[0] = h | MARK_BIT;
+
+ /*
+ * See if object we just found needs scanning. It must
+ * have a scan function to be placed on the scanQ.
+ */
+ tix = (PRWord)GET_TYPEIX(h);
+ ct = &_pr_collectorTypes[tix];
+ if (0 == ct->gctype.scan) {
+ return;
+ }
+
+ /*
+ ** Put a pointer onto the scan Q. We use the scan Q to avoid
+ ** deep recursion on the C call stack. Objects are added to
+ ** the scan Q until the scan Q fills up. At that point we
+ ** make a call to ScanScanQ which proceeds to scan each of
+ ** the objects in the Q. This limits the recursion level by a
+ ** large amount though the stack frames get larger to hold
+ ** the GCScanQ's.
+ */
+ pScanQ->q[pScanQ->queued++] = p;
+ if (pScanQ->queued == MAX_SCAN_Q) {
+ METER(_pr_scanDepth++);
+ ScanScanQ(pScanQ);
+ }
+ }
+}
+
+/************************************************************************/
+
+/*
+** Empty the freelist for each segment. This is done to make sure that
+** the root finding step works properly (otherwise, if we had a pointer
+** into a free section, we might not find its header word and abort in
+** FindObject)
+*/
+static void EmptyFreelists(void)
+{
+ GCFreeChunk *cp;
+ GCFreeChunk *next;
+ GCSeg *sp;
+ PRWord *p;
+ PRInt32 chunkSize;
+ PRInt32 bin;
+
+ /*
+ ** Run over the freelist and make all of the free chunks look like
+ ** object debris.
+ */
+ for (bin = 0; bin <= NUM_BINS-1; bin++) {
+ cp = bins[bin];
+ while (cp) {
+ next = cp->next;
+ sp = cp->segment;
+ chunkSize = cp->chunkSize >> BYTES_PER_WORD_LOG2;
+ p = (PRWord*) cp;
+ PR_ASSERT(chunkSize != 0);
+ p[0] = MAKE_HEADER(FREE_MEMORY_TYPEIX, chunkSize);
+ SET_HBIT(sp, p);
+ cp = next;
+ }
+ bins[bin] = 0;
+ }
+ minBin = NUM_BINS - 1;
+ maxBin = 0;
+}
+
+typedef struct GCBlockEnd {
+ PRInt32 check;
+#ifdef GC_CHECK
+ PRInt32 requestedBytes;
+#endif
+#ifdef GC_STATS
+ PRInt32 bin;
+ PRInt64 allocTime;
+#endif
+#ifdef GC_TRACEROOTS
+ PRInt32 traceGeneration;
+#endif
+} GCBlockEnd;
+
+#define PR_BLOCK_END 0xDEADBEEF
+
+/************************************************************************/
+
+#ifdef GC_STATS
+
+typedef struct GCStat {
+ PRInt32 nallocs;
+ double allocTime;
+ double allocTimeVariance;
+ PRInt32 nfrees;
+ double lifetime;
+ double lifetimeVariance;
+} GCStat;
+
+#define GCSTAT_BINS NUM_BINS
+
+GCStat gcstats[GCSTAT_BINS];
+
+#define GCLTFREQ_BINS NUM_BINS
+
+PRInt32 gcltfreq[GCSTAT_BINS][GCLTFREQ_BINS];
+
+#include <math.h>
+
+static char*
+pr_GetSizeString(PRUint32 size)
+{
+ char* sizeStr;
+ if (size < 1024)
+ sizeStr = PR_smprintf("<= %ld", size);
+ else if (size < 1024 * 1024)
+ sizeStr = PR_smprintf("<= %ldk", size / 1024);
+ else
+ sizeStr = PR_smprintf("<= %ldM", size / (1024 * 1024));
+ return sizeStr;
+}
+
+static void
+pr_FreeSizeString(char *sizestr)
+{
+ PR_smprintf_free(sizestr);
+}
+
+
+static void
+pr_PrintGCAllocStats(FILE* out)
+{
+ PRInt32 i, j;
+ _PR_DebugPrint(out, "\n--Allocation-Stats-----------------------------------------------------------");
+ _PR_DebugPrint(out, "\n--Obj-Size----Count-----Avg-Alloc-Time-----------Avg-Lifetime---------%%Freed-\n");
+ for (i = 0; i < GCSTAT_BINS; i++) {
+ GCStat stat = gcstats[i];
+ double allocTimeMean = 0.0, allocTimeVariance = 0.0, lifetimeMean = 0.0, lifetimeVariance = 0.0;
+ PRUint32 maxSize = (1 << i);
+ char* sizeStr;
+ if (stat.nallocs != 0.0) {
+ allocTimeMean = stat.allocTime / stat.nallocs;
+ allocTimeVariance = fabs(stat.allocTimeVariance / stat.nallocs - allocTimeMean * allocTimeMean);
+ }
+ if (stat.nfrees != 0.0) {
+ lifetimeMean = stat.lifetime / stat.nfrees;
+ lifetimeVariance = fabs(stat.lifetimeVariance / stat.nfrees - lifetimeMean * lifetimeMean);
+ }
+ sizeStr = pr_GetSizeString(maxSize);
+ _PR_DebugPrint(out, "%10s %8lu %10.3f +- %10.3f %10.3f +- %10.3f (%2ld%%)\n",
+ sizeStr, stat.nallocs,
+ allocTimeMean, sqrt(allocTimeVariance),
+ lifetimeMean, sqrt(lifetimeVariance),
+ (stat.nallocs ? (stat.nfrees * 100 / stat.nallocs) : 0));
+ pr_FreeSizeString(sizeStr);
+ }
+ _PR_DebugPrint(out, "--Lifetime-Frequency-Counts----------------------------------------------------\n");
+ _PR_DebugPrint(out, "size\\cnt");
+ for (j = 0; j < GCLTFREQ_BINS; j++) {
+ _PR_DebugPrint(out, "\t%lu", j);
+ }
+ _PR_DebugPrint(out, "\n");
+ for (i = 0; i < GCSTAT_BINS; i++) {
+ PRInt32* freqs = gcltfreq[i];
+ _PR_DebugPrint(out, "%lu", (1 << i));
+ for (j = 0; j < GCLTFREQ_BINS; j++) {
+ _PR_DebugPrint(out, "\t%lu", freqs[j]);
+ }
+ _PR_DebugPrint(out, "\n");
+ }
+ _PR_DebugPrint(out, "-------------------------------------------------------------------------------\n");
+}
+
+PR_PUBLIC_API(void)
+PR_PrintGCAllocStats(void)
+{
+ pr_PrintGCAllocStats(stderr);
+}
+
+#endif /* GC_STATS */
+
+/************************************************************************/
+
+/*
+** Sweep a segment, cleaning up all of the debris. Coallese the debris
+** into GCFreeChunk's which are added to the freelist bins.
+*/
+static PRBool SweepSegment(GCSeg *sp)
+{
+ PRWord h, tix;
+ PRWord *p;
+ PRWord *np;
+ PRWord *limit;
+ GCFreeChunk *cp;
+ PRInt32 bytes, chunkSize, segmentSize, totalFree;
+ CollectorType *ct;
+ PRInt32 bin;
+
+ /*
+ ** Now scan over the segment's memory in memory order, coallescing
+ ** all of the debris into a FreeChunk list.
+ */
+ totalFree = 0;
+ segmentSize = sp->limit - sp->base;
+ p = (PRWord *) sp->base;
+ limit = (PRWord *) sp->limit;
+ PR_ASSERT(segmentSize > 0);
+ while (p < limit) {
+ chunkSize = 0;
+ cp = (GCFreeChunk *) p;
+
+ /* Attempt to coallesce any neighboring free objects */
+ for (;;) {
+ PR_ASSERT(IS_HBIT(sp, p) != 0);
+ h = p[0];
+ bytes = OBJ_BYTES(h);
+ PR_ASSERT(bytes != 0);
+ np = (PRWord *) ((char *)p + bytes);
+ tix = (PRWord)GET_TYPEIX(h);
+ if ((h & MARK_BIT) && (tix != FREE_MEMORY_TYPEIX)) {
+#ifdef DEBUG
+ if (tix != FREE_MEMORY_TYPEIX) {
+ PR_ASSERT(_pr_collectorTypes[tix].flags != 0);
+ }
+#endif
+ p[0] = h & ~(MARK_BIT|FINAL_BIT);
+ _GCTRACE(GC_SWEEP, ("busy 0x%x (%d)", p, bytes));
+ break;
+ }
+ _GCTRACE(GC_SWEEP, ("free 0x%x (%d)", p, bytes));
+
+ /* Found a free object */
+#ifdef GC_STATS
+ {
+ PRInt32 userSize = bytes - sizeof(GCBlockEnd);
+ GCBlockEnd* end = (GCBlockEnd*)((char*)p + userSize);
+ if (userSize >= 0 && end->check == PR_BLOCK_END) {
+ PRInt64 now = PR_Now();
+ double nowd, delta;
+ PRInt32 freq;
+ LL_L2D(nowd, now);
+ delta = nowd - end->allocTime;
+ gcstats[end->bin].nfrees++;
+ gcstats[end->bin].lifetime += delta;
+ gcstats[end->bin].lifetimeVariance += delta * delta;
+
+ InlineBinNumber(freq, delta);
+ gcltfreq[end->bin][freq]++;
+
+ end->check = 0;
+ }
+ }
+#endif
+ CLEAR_HBIT(sp, p);
+ ct = &_pr_collectorTypes[tix];
+ if (0 != ct->gctype.free) {
+ (*ct->gctype.free)(p + 1);
+ }
+ chunkSize = chunkSize + bytes;
+ if (np == limit) {
+ /* Found the end of heap */
+ break;
+ }
+ PR_ASSERT(np < limit);
+ p = np;
+ }
+
+ if (chunkSize) {
+ _GCTRACE(GC_SWEEP, ("free chunk 0x%p to 0x%p (%d)",
+ cp, (char*)cp + chunkSize - 1, chunkSize));
+ if (chunkSize < MIN_FREE_CHUNK_BYTES) {
+ /* Lost a tiny fragment until (maybe) next time */
+ METER(meter.wastedBytes += chunkSize);
+ p = (PRWord *) cp;
+ chunkSize >>= BYTES_PER_WORD_LOG2;
+ PR_ASSERT(chunkSize != 0);
+ p[0] = MAKE_HEADER(FREE_MEMORY_TYPEIX, chunkSize);
+ SET_HBIT(sp, p);
+ } else {
+ /* See if the chunk constitutes the entire segment */
+ if (chunkSize == segmentSize) {
+ /* Free up the segment right now */
+ if (sp->info->fromMalloc) {
+ ShrinkGCHeap(sp);
+ return PR_TRUE;
+ }
+ }
+
+ /* Put free chunk into the appropriate bin */
+ cp->segment = sp;
+ cp->chunkSize = chunkSize;
+ InlineBinNumber(bin, chunkSize)
+ cp->next = bins[bin];
+ bins[bin] = cp;
+ if (bin < minBin) minBin = bin;
+ if (bin > maxBin) maxBin = bin;
+
+ /* Zero swept memory now */
+ memset(cp+1, 0, chunkSize - sizeof(*cp));
+ METER(meter.numFreeChunks++);
+ totalFree += chunkSize;
+ }
+ }
+
+ /* Advance to next object */
+ p = np;
+ }
+
+ PR_ASSERT(totalFree <= segmentSize);
+
+ _pr_gcData.freeMemory += totalFree;
+ _pr_gcData.busyMemory += (sp->limit - sp->base) - totalFree;
+ return PR_FALSE;
+}
+
+/************************************************************************/
+
+/* This is a list of all the objects that are finalizable. This is not
+ the list of objects that are awaiting finalization because they
+ have been collected. */
+PRCList _pr_finalizeableObjects;
+
+/* This is the list of objects that are awaiting finalization because
+ they have been collected. */
+PRCList _pr_finalQueue;
+
+/* Each object that requires finalization has one of these objects
+ allocated as well. The GCFinal objects are put on the
+ _pr_finalizeableObjects list until the object is collected at which
+ point the GCFinal object is moved to the _pr_finalQueue */
+typedef struct GCFinalStr {
+ PRCList links;
+ PRWord *object;
+} GCFinal;
+
+/* Find pointer to GCFinal struct from the list linkaged embedded in it */
+#define FinalPtr(_qp) \
+ ((GCFinal*) ((char*) (_qp) - offsetof(GCFinal,links)))
+
+static GCFinal *AllocFinalNode(void)
+{
+ return PR_NEWZAP(GCFinal);
+}
+
+static void FreeFinalNode(GCFinal *node)
+{
+ PR_DELETE(node);
+}
+
+/*
+** Prepare for finalization. At this point in the GC cycle we have
+** identified all of the live objects. For each object on the
+** _pr_finalizeableObjects list see if the object is alive or dead. If
+** it's dead, resurrect it and move it from the _pr_finalizeableObjects
+** list to the _pr_finalQueue (object's only get finalized once).
+**
+** Once _pr_finalizeableObjects has been processed we can finish the
+** GC and free up memory and release the threading lock. After that we
+** can invoke the finalization procs for each object that is on the
+** _pr_finalQueue.
+*/
+static void PrepareFinalize(void)
+{
+ PRCList *qp;
+ GCFinal *fp;
+ PRWord h;
+ PRWord *p;
+ void (PR_CALLBACK *livePointer)(void *ptr);
+#ifdef DEBUG
+ CollectorType *ct;
+#endif
+
+ /* This must be done under the same lock that the finalizer uses */
+ PR_ASSERT( GC_IS_LOCKED() );
+
+ /* cache this ptr */
+ livePointer = _pr_gcData.livePointer;
+
+ /*
+ * Pass #1: Identify objects that are to be finalized, set their
+ * FINAL_BIT.
+ */
+ qp = _pr_finalizeableObjects.next;
+ while (qp != &_pr_finalizeableObjects) {
+ fp = FinalPtr(qp);
+ qp = qp->next;
+ h = fp->object[0]; /* Grab header word */
+ if (h & MARK_BIT) {
+ /* Object is already alive */
+ continue;
+ }
+
+#ifdef DEBUG
+ ct = &_pr_collectorTypes[GET_TYPEIX(h)];
+ PR_ASSERT((0 != ct->flags) && (0 != ct->gctype.finalize));
+#endif
+ fp->object[0] |= FINAL_BIT;
+ _GCTRACE(GC_FINAL, ("moving %p (%d) to finalQueue",
+ fp->object, OBJ_BYTES(h)));
+ }
+
+ /*
+ * Pass #2: For each object that is going to be finalized, move it to
+ * the finalization queue and resurrect it
+ */
+ qp = _pr_finalizeableObjects.next;
+ while (qp != &_pr_finalizeableObjects) {
+ fp = FinalPtr(qp);
+ qp = qp->next;
+ h = fp->object[0]; /* Grab header word */
+ if ((h & FINAL_BIT) == 0) {
+ continue;
+ }
+
+ /* Resurrect the object and any objects it refers to */
+ p = &fp->object[1];
+ (*livePointer)(p);
+ PR_REMOVE_LINK(&fp->links);
+ PR_APPEND_LINK(&fp->links, &_pr_finalQueue);
+ }
+}
+
+/*
+** Scan the finalQ, marking each and every object on it live. This is
+** necessary because we might do a GC before objects that are on the
+** final queue get finalized. Since there are no other references
+** (otherwise they would be on the final queue), we have to scan them.
+** This really only does work if we call the GC before the finalizer
+** has a chance to do its job.
+*/
+extern void PR_CALLBACK _PR_ScanFinalQueue(void *notused)
+{
+#ifdef XP_MAC
+#pragma unused (notused)
+#endif
+ PRCList *qp;
+ GCFinal *fp;
+ PRWord *p;
+ void ( PR_CALLBACK *livePointer)(void *ptr);
+
+ livePointer = _pr_gcData.livePointer;
+ qp = _pr_finalQueue.next;
+ while (qp != &_pr_finalQueue) {
+ fp = FinalPtr(qp);
+ _GCTRACE(GC_FINAL, ("marking 0x%x (on final queue)", fp->object));
+ p = &fp->object[1];
+ (*livePointer)(p);
+ qp = qp->next;
+ }
+}
+
+void PR_CALLBACK FinalizerLoop(void* unused)
+{
+#ifdef XP_MAC
+#pragma unused (unused)
+#endif
+ GCFinal *fp;
+ PRWord *p;
+ PRWord h, tix;
+ CollectorType *ct;
+
+ LOCK_GC();
+ for (;;) {
+ p = 0; h = 0; /* don't let the gc find these pointers */
+ while (PR_CLIST_IS_EMPTY(&_pr_finalQueue))
+ PR_Wait(_pr_gcData.lock, PR_INTERVAL_NO_TIMEOUT);
+
+ _GCTRACE(GC_FINAL, ("begin finalization"));
+ while (_pr_finalQueue.next != &_pr_finalQueue) {
+ fp = FinalPtr(_pr_finalQueue.next);
+ PR_REMOVE_LINK(&fp->links);
+ p = fp->object;
+
+ h = p[0]; /* Grab header word */
+ tix = (PRWord)GET_TYPEIX(h);
+ ct = &_pr_collectorTypes[tix];
+ _GCTRACE(GC_FINAL, ("finalize 0x%x (%d)", p, OBJ_BYTES(h)));
+
+ /*
+ ** Give up the GC lock so that other threads can allocate memory
+ ** while this finalization method is running. Get it back
+ ** afterwards so that the list remains thread safe.
+ */
+ UNLOCK_GC();
+ FreeFinalNode(fp);
+ PR_ASSERT(ct->gctype.finalize != 0);
+ (*ct->gctype.finalize)(p + 1);
+ LOCK_GC();
+ }
+ _GCTRACE(GC_FINAL, ("end finalization"));
+ PR_Notify(_pr_gcData.lock);
+ }
+}
+
+static void NotifyFinalizer(void)
+{
+ if (!PR_CLIST_IS_EMPTY(&_pr_finalQueue)) {
+ PR_ASSERT( GC_IS_LOCKED() );
+ PR_Notify(_pr_gcData.lock);
+ }
+}
+
+void _PR_CreateFinalizer(PRThreadScope scope)
+{
+ if (!_pr_gcData.finalizer) {
+ _pr_gcData.finalizer = PR_CreateThreadGCAble(PR_SYSTEM_THREAD,
+ FinalizerLoop, 0,
+ PR_PRIORITY_LOW, scope,
+ PR_UNJOINABLE_THREAD, 0);
+
+ if (_pr_gcData.finalizer == NULL)
+ /* We are doomed if we can't start the finalizer */
+ PR_Abort();
+
+ }
+}
+
+void pr_FinalizeOnExit(void)
+{
+#ifdef DEBUG_warren
+ OutputDebugString("### Doing finalize-on-exit pass\n");
+#endif
+ PR_ForceFinalize();
+#ifdef DEBUG_warren
+ OutputDebugString("### Finalize-on-exit complete. Dumping object left to memory.out\n");
+ PR_DumpMemorySummary();
+ PR_DumpMemory(PR_TRUE);
+#endif
+}
+
+PR_IMPLEMENT(void) PR_ForceFinalize()
+{
+ LOCK_GC();
+ NotifyFinalizer();
+ while (!PR_CLIST_IS_EMPTY(&_pr_finalQueue)) {
+ PR_ASSERT( GC_IS_LOCKED() );
+ (void) PR_Wait(_pr_gcData.lock, PR_INTERVAL_NO_TIMEOUT);
+ }
+ UNLOCK_GC();
+
+ /* XXX I don't know how to make it wait (yet) */
+}
+
+/************************************************************************/
+
+typedef struct GCWeakStr {
+ PRCList links;
+ PRWord *object;
+} GCWeak;
+
+/*
+** Find pointer to GCWeak struct from the list linkaged embedded in it
+*/
+#define WeakPtr(_qp) \
+ ((GCWeak*) ((char*) (_qp) - offsetof(GCWeak,links)))
+
+PRCList _pr_weakLinks = PR_INIT_STATIC_CLIST(&_pr_weakLinks);
+PRCList _pr_freeWeakLinks = PR_INIT_STATIC_CLIST(&_pr_freeWeakLinks);
+
+#define WEAK_FREELIST_ISEMPTY() (_pr_freeWeakLinks.next == &_pr_freeWeakLinks)
+
+/*
+ * Keep objects referred to by weak free list alive until they can be
+ * freed
+ */
+static void PR_CALLBACK ScanWeakFreeList(void *notused) {
+#ifdef XP_MAC
+#pragma unused (notused)
+#endif
+ PRCList *qp = _pr_freeWeakLinks.next;
+ while (qp != &_pr_freeWeakLinks) {
+ GCWeak *wp = WeakPtr(qp);
+ qp = qp->next;
+ ProcessRootPointer(wp->object);
+ }
+}
+
+/*
+ * Empty the list of weak objects. Note that we can't call malloc/free
+ * under the cover of the GC's lock (we might deadlock), so transfer the
+ * list of free objects to a local list under the cover of the lock, then
+ * release the lock and free up the memory.
+ */
+static void EmptyWeakFreeList(void) {
+ if (!WEAK_FREELIST_ISEMPTY()) {
+ PRCList *qp, freeLinks;
+
+ PR_INIT_CLIST(&freeLinks);
+
+ /*
+ * Transfer list of free weak links from the global list to a
+ * local list.
+ */
+ LOCK_GC();
+ qp = _pr_freeWeakLinks.next;
+ while (qp != &_pr_freeWeakLinks) {
+ GCWeak *wp = WeakPtr(qp);
+ qp = qp->next;
+ PR_REMOVE_LINK(&wp->links);
+ PR_APPEND_LINK(&wp->links, &freeLinks);
+ }
+ UNLOCK_GC();
+
+ /* Free up storage now */
+ qp = freeLinks.next;
+ while (qp != &freeLinks) {
+ GCWeak *wp = WeakPtr(qp);
+ qp = qp->next;
+ PR_DELETE(wp);
+ }
+ }
+}
+
+/*
+ * Allocate a new weak node in the weak objects list
+ */
+static GCWeak *AllocWeakNode(void)
+{
+ EmptyWeakFreeList();
+ return PR_NEWZAP(GCWeak);
+}
+
+static void FreeWeakNode(GCWeak *node)
+{
+ PR_DELETE(node);
+}
+
+/*
+ * Check the weak links for validity. Note that the list of weak links is
+ * itself weak (otherwise we would keep the objects with weak links in
+ * them alive forever). As we scan the list check the weak link object
+ * itself and if it's not marked then remove it from the weak link list
+ */
+static void CheckWeakLinks(void) {
+ PRCList *qp;
+ GCWeak *wp;
+ PRWord *p, h, tix, **weakPtrAddress;
+ CollectorType *ct;
+ PRUint32 offset;
+
+ qp = _pr_weakLinks.next;
+ while (qp != &_pr_weakLinks) {
+ wp = WeakPtr(qp);
+ qp = qp->next;
+ if ((p = wp->object) != 0) {
+ h = p[0]; /* Grab header word */
+ if ((h & MARK_BIT) == 0) {
+ /*
+ * The object that has a weak link is no longer being
+ * referenced; remove it from the chain and let it get
+ * swept away by the GC. Transfer it to the list of
+ * free weak links for later freeing.
+ */
+ PR_REMOVE_LINK(&wp->links);
+ PR_APPEND_LINK(&wp->links, &_pr_freeWeakLinks);
+ collectorCleanupNeeded = 1;
+ continue;
+ }
+
+ /* Examine a live object that contains weak links */
+ tix = GET_TYPEIX(h);
+ ct = &_pr_collectorTypes[tix];
+ PR_ASSERT((ct->flags != 0) && (ct->gctype.getWeakLinkOffset != 0));
+ if (0 == ct->gctype.getWeakLinkOffset) {
+ /* Heap is probably corrupted */
+ continue;
+ }
+
+ /* Get offset into the object of where the weak pointer is */
+ offset = (*ct->gctype.getWeakLinkOffset)(p + 1);
+
+ /* Check the weak pointer */
+ weakPtrAddress = (PRWord**)((char*)(p + 1) + offset);
+ p = *weakPtrAddress;
+ if (p != 0) {
+ h = p[-1]; /* Grab header word for pointed to object */
+ if (h & MARK_BIT) {
+ /* Object can't be dead */
+ continue;
+ }
+ /* Break weak link to an object that is about to be swept */
+ *weakPtrAddress = 0;
+ }
+ }
+ }
+}
+
+/************************************************************************/
+
+/*
+** Perform a complete garbage collection
+*/
+
+extern GCLockHook *_pr_GCLockHook;
+
+static void dogc(void)
+{
+ RootFinder *rf;
+ GCLockHook* lhook;
+
+ GCScanQ scanQ;
+ GCSeg *sp, *esp;
+ PRInt64 start, end, diff;
+
+#if defined(GCMETER) || defined(GCTIMINGHOOK)
+ start = PR_Now();
+#endif
+
+ /*
+ ** Stop all of the other threads. This also promises to capture the
+ ** register state of each and every thread
+ */
+
+ /*
+ ** Get all the locks that will be need during GC after SuspendAll. We
+ ** cannot make any locking/library calls after SuspendAll.
+ */
+ if (_pr_GCLockHook) {
+ for (lhook = _pr_GCLockHook->next; lhook != _pr_GCLockHook;
+ lhook = lhook->next) {
+ (*lhook->func)(PR_GCBEGIN, lhook->arg);
+ }
+ }
+
+ PR_SuspendAll();
+
+#ifdef GCMETER
+ /* Reset meter info */
+ if (_pr_gcMeter & _GC_METER_STATS) {
+ fprintf(stderr,
+ "[GCSTATS: busy:%ld skipped:%ld, alloced:%ld+wasted:%ld+free:%ld = total:%ld]\n",
+ (long) _pr_gcData.busyMemory,
+ (long) meter.skippedFreeChunks,
+ (long) meter.allocBytes,
+ (long) meter.wastedBytes,
+ (long) _pr_gcData.freeMemory,
+ (long) _pr_gcData.allocMemory);
+ }
+ memset(&meter, 0, sizeof(meter));
+#endif
+
+ PR_LOG(_pr_msgc_lm, PR_LOG_ALWAYS, ("begin mark phase; busy=%d free=%d total=%d",
+ _pr_gcData.busyMemory, _pr_gcData.freeMemory,
+ _pr_gcData.allocMemory));
+
+ if (_pr_beginGCHook) {
+ (*_pr_beginGCHook)(_pr_beginGCHookArg);
+ }
+
+ /*
+ ** Initialize scanQ to all zero's so that root finder doesn't walk
+ ** over it...
+ */
+ memset(&scanQ, 0, sizeof(scanQ));
+ pScanQ = &scanQ;
+
+ /******************************************/
+ /* MARK PHASE */
+
+ EmptyFreelists();
+
+ /* Find root's */
+ PR_LOG(_pr_msgc_lm, PR_LOG_WARNING,
+ ("begin mark phase; busy=%d free=%d total=%d",
+ _pr_gcData.busyMemory, _pr_gcData.freeMemory,
+ _pr_gcData.allocMemory));
+ METER(_pr_scanDepth = 0);
+ rf = _pr_rootFinders;
+ while (rf) {
+ _GCTRACE(GC_ROOTS, ("finding roots in %s", rf->name));
+ (*rf->func)(rf->arg);
+ rf = rf->next;
+ }
+ _GCTRACE(GC_ROOTS, ("done finding roots"));
+
+ /* Scan remaining object's that need scanning */
+ ScanScanQ(&scanQ);
+ PR_ASSERT(pScanQ == &scanQ);
+ PR_ASSERT(scanQ.queued == 0);
+ METER({
+ if (_pr_scanDepth > _pr_maxScanDepth) {
+ _pr_maxScanDepth = _pr_scanDepth;
+ }
+ });
+
+ /******************************************/
+ /* FINALIZATION PHASE */
+
+ METER(_pr_scanDepth = 0);
+ PrepareFinalize();
+
+ /* Scan any resurrected objects found during finalization */
+ ScanScanQ(&scanQ);
+ PR_ASSERT(pScanQ == &scanQ);
+ PR_ASSERT(scanQ.queued == 0);
+ METER({
+ if (_pr_scanDepth > _pr_maxScanDepth) {
+ _pr_maxScanDepth = _pr_scanDepth;
+ }
+ });
+ pScanQ = 0;
+
+ /******************************************/
+ /* SWEEP PHASE */
+
+ /*
+ ** Sweep each segment clean. While we are at it, figure out which
+ ** segment has the most free space and make that the current segment.
+ */
+ CheckWeakLinks();
+ _GCTRACE(GC_SWEEP, ("begin sweep phase"));
+ _pr_gcData.freeMemory = 0;
+ _pr_gcData.busyMemory = 0;
+ sp = segs;
+ esp = sp + nsegs;
+ while (sp < esp) {
+ if (SweepSegment(sp)) {
+ /*
+ ** Segment is now free and has been replaced with a different
+ ** segment object.
+ */
+ esp--;
+ continue;
+ }
+ sp++;
+ }
+
+#if defined(GCMETER) || defined(GCTIMINGHOOK)
+ end = PR_Now();
+#endif
+#ifdef GCMETER
+ LL_SUB(diff, end, start);
+ PR_LOG(GC, PR_LOG_ALWAYS,
+ ("done; busy=%d free=%d chunks=%d total=%d time=%lldms",
+ _pr_gcData.busyMemory, _pr_gcData.freeMemory,
+ meter.numFreeChunks, _pr_gcData.allocMemory, diff));
+ if (_pr_gcMeter & _GC_METER_FREE_LIST) {
+ PRIntn bin;
+ fprintf(stderr, "Freelist bins:\n");
+ for (bin = 0; bin < NUM_BINS; bin++) {
+ GCFreeChunk *cp = bins[bin];
+ while (cp != NULL) {
+ fprintf(stderr, "%3d: %p %8ld\n",
+ bin, cp, (long) cp->chunkSize);
+ cp = cp->next;
+ }
+ }
+ }
+#endif
+
+ if (_pr_endGCHook) {
+ (*_pr_endGCHook)(_pr_endGCHookArg);
+ }
+
+ /* clear the running total of the bytes allocated via BigAlloc() */
+ bigAllocBytes = 0;
+
+ /* And resume multi-threading */
+ PR_ResumeAll();
+
+ if (_pr_GCLockHook) {
+ for (lhook = _pr_GCLockHook->prev; lhook != _pr_GCLockHook;
+ lhook = lhook->prev) {
+ (*lhook->func)(PR_GCEND, lhook->arg);
+ }
+ }
+
+ /* Kick finalizer */
+ NotifyFinalizer();
+#ifdef GCTIMINGHOOK
+ if (_pr_gcData.gcTimingHook) {
+ PRInt32 time;
+ LL_SUB(diff, end, start);
+ LL_L2I(time, diff);
+ _pr_gcData.gcTimingHook(time);
+ }
+#endif
+}
+
+PR_IMPLEMENT(void) PR_GC(void)
+{
+ LOCK_GC();
+ dogc();
+ UNLOCK_GC();
+
+ EmptyWeakFreeList();
+}
+
+/*******************************************************************************
+ * Heap Walker
+ ******************************************************************************/
+
+/*
+** This is yet another disgusting copy of the body of ProcessRootPointer
+** (the other being ProcessRootBlock), but we're not leveraging a single
+** function in their cases in interest of performance (avoiding the function
+** call).
+*/
+static PRInt32 PR_CALLBACK
+pr_ConservativeWalkPointer(void* ptr, PRWalkFun walkRootPointer, void* data)
+{
+ PRWord *p0, *p, *segBase;
+ GCSeg* sp;
+
+ p0 = (PRWord*) ptr;
+
+ /*
+ ** XXX:
+ ** Until Win16 maintains lowSeg and highSeg correctly,
+ ** (ie. lowSeg=MIN(all segs) and highSeg = MAX(all segs))
+ ** Allways scan through the segment list
+ */
+#if !defined(WIN16)
+ if (p0 < _pr_gcData.lowSeg) return 0; /* below gc heap */
+ if (p0 >= _pr_gcData.highSeg) return 0; /* above gc heap */
+#endif
+
+ /* NOTE: inline expansion of InHeap */
+ /* Find segment */
+ sp = lastInHeap;
+ if (!sp || !IN_SEGMENT(sp,p0)) {
+ GCSeg *esp;
+ sp = segs;
+ esp = segs + nsegs;
+ for (; sp < esp; sp++) {
+ if (IN_SEGMENT(sp, p0)) {
+ lastInHeap = sp;
+ goto find_object;
+ }
+ }
+ return 0;
+ }
+
+ find_object:
+ /* NOTE: Inline expansion of FindObject */
+ /* Align p to it's proper boundary before we start fiddling with it */
+ p = (PRWord*) ((PRWord)p0 & ~(BYTES_PER_WORD-1L));
+ segBase = (PRWord *) sp->base;
+ do {
+ if (IS_HBIT(sp, p)) {
+ goto winner;
+ }
+ p--;
+ } while (p >= segBase);
+
+ /*
+ ** We have a pointer into the heap, but it has no header
+ ** bit. This means that somehow the very first object in the heap
+ ** doesn't have a header. This is impossible so when debugging
+ ** lets abort.
+ */
+#ifdef DEBUG
+ PR_Abort();
+#endif
+ return 0;
+
+ winner:
+ return walkRootPointer(p, data);
+}
+
+static PRInt32 PR_CALLBACK
+pr_ConservativeWalkBlock(void **base, PRInt32 count,
+ PRWalkFun walkRootPointer, void* data)
+{
+ PRWord *p0;
+ while (--count >= 0) {
+ PRInt32 status;
+ p0 = (PRWord*) *base++;
+ status = pr_ConservativeWalkPointer(p0, walkRootPointer, data);
+ if (status) return status;
+ }
+ return 0;
+}
+
+/******************************************************************************/
+
+typedef void (*WalkObject_t)(FILE *out, GCType* tp, PRWord *obj,
+ size_t bytes, PRBool detailed);
+typedef void (*WalkUnknown_t)(FILE *out, GCType* tp, PRWord tix, PRWord *p,
+ size_t bytes, PRBool detailed);
+typedef void (*WalkFree_t)(FILE *out, PRWord *p, size_t size, PRBool detailed);
+typedef void (*WalkSegment_t)(FILE *out, GCSeg* sp, PRBool detailed);
+
+static void
+pr_WalkSegment(FILE* out, GCSeg* sp, PRBool detailed,
+ char* enterMsg, char* exitMsg,
+ WalkObject_t walkObject, WalkUnknown_t walkUnknown, WalkFree_t walkFree)
+{
+ PRWord *p, *limit;
+
+ p = (PRWord *) sp->base;
+ limit = (PRWord *) sp->limit;
+ if (enterMsg)
+ fprintf(out, enterMsg, p);
+ while (p < limit)
+ {
+ if (IS_HBIT(sp, p)) /* Is this an object header? */
+ {
+ PRWord h = p[0];
+ PRWord tix = GET_TYPEIX(h);
+ size_t bytes = OBJ_BYTES(h);
+ PRWord* np = (PRWord*) ((char*)p + bytes);
+
+ GCType* tp = &_pr_collectorTypes[tix].gctype;
+ if ((0 != tp) && walkObject)
+ walkObject(out, tp, p, bytes, detailed);
+ else if (walkUnknown)
+ walkUnknown(out, tp, tix, p, bytes, detailed);
+ p = np;
+ }
+ else
+ {
+ /* Must be a freelist item */
+ size_t size = ((GCFreeChunk*)p)->chunkSize;
+ if (walkFree)
+ walkFree(out, p, size, detailed);
+ p = (PRWord*)((char*)p + size);
+ }
+ }
+ if (p != limit)
+ fprintf(out, "SEGMENT OVERRUN (end should be at 0x%p)\n", limit);
+ if (exitMsg)
+ fprintf(out, exitMsg, p);
+}
+
+static void
+pr_WalkSegments(FILE *out, WalkSegment_t walkSegment, PRBool detailed)
+{
+ GCSeg *sp = segs;
+ GCSeg *esp;
+
+ LOCK_GC();
+ esp = sp + nsegs;
+ while (sp < esp)
+ {
+ walkSegment(out, sp, detailed);
+ sp++;
+ }
+ fprintf(out, "End of heap\n");
+ UNLOCK_GC();
+}
+
+/*******************************************************************************
+ * Heap Dumper
+ ******************************************************************************/
+
+PR_IMPLEMENT(void)
+PR_DumpIndent(FILE *out, int indent)
+{
+ while (--indent >= 0)
+ fprintf(out, " ");
+}
+
+static void
+PR_DumpHexWords(FILE *out, PRWord *p, int nWords,
+ int indent, int nWordsPerLine)
+{
+ while (nWords > 0)
+ {
+ int i;
+
+ PR_DumpIndent(out, indent);
+ i = nWordsPerLine;
+ if (i > nWords)
+ i = nWords;
+ nWords -= i;
+ while (i--)
+ {
+ fprintf(out, "0x%.8lX", (long) *p++);
+ if (i)
+ fputc(' ', out);
+ }
+ fputc('\n', out);
+ }
+}
+
+static void PR_CALLBACK
+pr_DumpObject(FILE *out, GCType* tp, PRWord *p,
+ size_t bytes, PRBool detailed)
+{
+ char kindChar = tp->kindChar;
+ fprintf(out, "0x%p: 0x%.6lX %c ",
+ p, (long) bytes, kindChar ? kindChar : '?');
+ if (tp->dump)
+ (*tp->dump)(out, (void*) (p + 1), detailed, 0);
+ if (detailed)
+ PR_DumpHexWords(out, p, bytes>>2, 22, 4);
+}
+
+static void PR_CALLBACK
+pr_DumpUnknown(FILE *out, GCType* tp, PRWord tix, PRWord *p,
+ size_t bytes, PRBool detailed)
+{
+ char kindChar = tp->kindChar;
+ fprintf(out, "0x%p: 0x%.6lX %c ",
+ p, (long) bytes, kindChar ? kindChar : '?');
+ fprintf(out, "UNKNOWN KIND %ld\n", (long) tix);
+ if (detailed)
+ PR_DumpHexWords(out, p, bytes>>2, 22, 4);
+}
+
+static void PR_CALLBACK
+pr_DumpFree(FILE *out, PRWord *p, size_t size, PRBool detailed)
+{
+#if defined(XP_MAC) && XP_MAC
+# pragma unused( detailed )
+#endif
+
+ fprintf(out, "0x%p: 0x%.6lX - FREE\n", p, (long) size);
+}
+
+static void PR_CALLBACK
+pr_DumpSegment(FILE* out, GCSeg* sp, PRBool detailed)
+{
+ pr_WalkSegment(out, sp, detailed,
+ "\n Address: Length\n0x%p: Beginning of segment\n",
+ "0x%p: End of segment\n\n",
+ pr_DumpObject, pr_DumpUnknown, pr_DumpFree);
+}
+
+static void pr_DumpRoots(FILE *out);
+
+/*
+** Dump out the GC heap.
+*/
+PR_IMPLEMENT(void)
+PR_DumpGCHeap(FILE *out, PRBool detailed)
+{
+ fprintf(out, "\n"
+ "The kinds are:\n"
+ " U unscanned block\n"
+ " W weak link block\n"
+ " S scanned block\n"
+ " F scanned and final block\n"
+ " C class record\n"
+ " X context record\n"
+ " - free list item\n"
+ " ? other\n");
+ LOCK_GC();
+ pr_WalkSegments(out, pr_DumpSegment, detailed);
+ if (detailed)
+ pr_DumpRoots(out);
+ UNLOCK_GC();
+}
+
+PR_IMPLEMENT(void)
+PR_DumpMemory(PRBool detailed)
+{
+ PR_DumpToFile("memory.out", "Dumping memory", PR_DumpGCHeap, detailed);
+}
+
+/******************************************************************************/
+
+static PRInt32 PR_CALLBACK
+pr_DumpRootPointer(PRWord* p, void* data)
+{
+#ifdef XP_MAC
+#pragma unused(data)
+#endif
+ PRWord h = p[0];
+ PRWord tix = GET_TYPEIX(h);
+ size_t bytes = OBJ_BYTES(h);
+
+ GCType* tp = &_pr_collectorTypes[tix].gctype;
+ if (0 != tp)
+ pr_DumpObject(_pr_gcData.dumpOutput, tp, p, bytes, PR_FALSE);
+ else
+ pr_DumpUnknown(_pr_gcData.dumpOutput, tp, tix, p, bytes, PR_FALSE);
+ return 0;
+}
+
+static void PR_CALLBACK
+pr_ConservativeDumpRootPointer(void* ptr)
+{
+ (void)pr_ConservativeWalkPointer(ptr, (PRWalkFun) pr_DumpRootPointer, NULL);
+}
+
+static void PR_CALLBACK
+pr_ConservativeDumpRootBlock(void **base, PRInt32 count)
+{
+ (void)pr_ConservativeWalkBlock(base, count, (PRWalkFun) pr_DumpRootPointer, NULL);
+}
+
+extern int
+DumpThreadRoots(PRThread *t, int i, void *notused);
+
+static void
+pr_DumpRoots(FILE *out)
+{
+ RootFinder *rf;
+ void (*liveBlock)(void **base, PRInt32 count);
+ void (*livePointer)(void *ptr);
+ void (*processRootBlock)(void **base, PRInt32 count);
+ void (*processRootPointer)(void *ptr);
+
+ LOCK_GC();
+
+ liveBlock = _pr_gcData.liveBlock;
+ livePointer = _pr_gcData.livePointer;
+ processRootBlock = _pr_gcData.processRootBlock;
+ processRootPointer = _pr_gcData.processRootPointer;
+
+ _pr_gcData.liveBlock = pr_ConservativeDumpRootBlock;
+ _pr_gcData.livePointer = pr_ConservativeDumpRootPointer;
+ _pr_gcData.processRootBlock = pr_ConservativeDumpRootBlock;
+ _pr_gcData.processRootPointer = pr_ConservativeDumpRootPointer;
+ _pr_gcData.dumpOutput = out;
+
+ rf = _pr_rootFinders;
+ while (rf) {
+ fprintf(out, "\n===== Roots for %s\n", rf->name);
+ (*rf->func)(rf->arg);
+ rf = rf->next;
+ }
+
+ _pr_gcData.liveBlock = liveBlock;
+ _pr_gcData.livePointer = livePointer;
+ _pr_gcData.processRootBlock = processRootBlock;
+ _pr_gcData.processRootPointer = processRootPointer;
+ _pr_gcData.dumpOutput = NULL;
+
+ UNLOCK_GC();
+}
+
+/*******************************************************************************
+ * Heap Summary Dumper
+ ******************************************************************************/
+
+PRSummaryPrinter summaryPrinter = NULL;
+void* summaryPrinterClosure = NULL;
+
+PR_IMPLEMENT(void)
+PR_RegisterSummaryPrinter(PRSummaryPrinter fun, void* closure)
+{
+ summaryPrinter = fun;
+ summaryPrinterClosure = closure;
+}
+
+static void PR_CALLBACK
+pr_SummarizeObject(FILE *out, GCType* tp, PRWord *p,
+ size_t bytes, PRBool detailed)
+{
+#if defined(XP_MAC) && XP_MAC
+# pragma unused( out, detailed )
+#endif
+
+ if (tp->summarize)
+ (*tp->summarize)((void GCPTR*)(p + 1), bytes);
+}
+
+static void PR_CALLBACK
+pr_DumpSummary(FILE* out, GCSeg* sp, PRBool detailed)
+{
+ pr_WalkSegment(out, sp, detailed, NULL, NULL,
+ pr_SummarizeObject, NULL, NULL);
+}
+
+PR_IMPLEMENT(void)
+PR_DumpGCSummary(FILE *out, PRBool detailed)
+{
+ if (summaryPrinter) {
+ pr_WalkSegments(out, pr_DumpSummary, detailed);
+ summaryPrinter(out, summaryPrinterClosure);
+ }
+#if 0
+ fprintf(out, "\nFinalizable objects:\n");
+ {
+ PRCList *qp;
+ qp = _pr_pendingFinalQueue.next;
+ while (qp != &_pr_pendingFinalQueue) {
+ GCFinal* fp = FinalPtr(qp);
+ PRWord h = fp->object[0]; /* Grab header word */
+ PRWord tix = GET_TYPEIX(h);
+ GCType* tp = _pr_gcTypes[tix];
+ size_t bytes = OBJ_BYTES(h);
+ pr_DumpObject(out, tp, fp->object, bytes, PR_FALSE);
+ qp = qp->next;
+ }
+ }
+#endif
+}
+
+PR_IMPLEMENT(void)
+PR_DumpMemorySummary(void)
+{
+ PR_DumpToFile("memory.out", "Memory Summary", PR_DumpGCSummary, PR_FALSE);
+}
+
+/*******************************************************************************
+ * End Of Heap Walker
+ ******************************************************************************/
+
+#ifdef GC_TRACEROOTS
+
+PRInt32 pr_traceGen = 0;
+
+static PRBool
+pr_IsMarked(PRWord* p)
+{
+ GCBlockEnd* end = (GCBlockEnd*)((char*)p + OBJ_BYTES(p[0]) - sizeof(GCBlockEnd));
+ PR_ASSERT(end->check == PR_BLOCK_END);
+ return end->traceGeneration == pr_traceGen;
+}
+
+static void
+pr_Mark(PRWord* p)
+{
+ GCBlockEnd* end = (GCBlockEnd*)((char*)p + OBJ_BYTES(p[0]) - sizeof(GCBlockEnd));
+ PR_ASSERT(end->check == PR_BLOCK_END);
+ end->traceGeneration = pr_traceGen;
+}
+
+PRWord* pr_traceObj; /* set this in the debugger, then execute PR_TraceRoot() */
+
+static PRInt32 PR_CALLBACK
+pr_TraceRootObject(void* obj, void* data);
+
+static PRInt32 PR_CALLBACK
+pr_TraceRootPointer(PRWord *p, void* data)
+{
+ PRInt32 printTrace = 0;
+ PRWord h = p[0];
+ PRWord tix = GET_TYPEIX(h);
+ GCType* tp = &_pr_collectorTypes[tix].gctype;
+ FILE* out = _pr_gcData.dumpOutput;
+
+ PR_ASSERT(tp);
+ if (pr_IsMarked(p))
+ return printTrace;
+
+ pr_Mark(p);
+ if (p == pr_traceObj) {
+ fprintf(out, "\n### Found path to:\n");
+ printTrace = 1;
+ }
+ else {
+ if (PR_StackSpaceLeft(PR_CurrentThread()) < 512) {
+ fprintf(out, "\n### Path too deep (giving up):\n");
+ printTrace = 1;
+ }
+ else if (tp->walk) {
+ printTrace = tp->walk((void*)(p + 1), pr_TraceRootObject, data);
+ }
+ /* else there's no way to walk this object, so we
+ haven't found what we're looking for */
+ }
+
+ if (printTrace == 1) {
+ PR_ASSERT(tp->dump);
+ fprintf(out, "0x%p: ", p);
+ tp->dump(out, (void*)(p + 1), PR_FALSE, 1);
+ }
+ return printTrace;
+}
+
+static PRInt32 PR_CALLBACK
+pr_TraceRootObject(void* obj, void* data)
+{
+ /* This version of pr_TraceRootPointer takes object
+ pointers, instead of gc header pointers. */
+ return pr_TraceRootPointer((PRWord*)obj - 1, data);
+}
+
+static void PR_CALLBACK
+pr_ConservativeTraceRootPointer(PRWord *p)
+{
+ PRInt32 status;
+ ++pr_traceGen;
+ status = pr_ConservativeWalkPointer(p, pr_TraceRootPointer, NULL);
+ if (status) {
+ FILE* out = _pr_gcData.dumpOutput;
+ fprintf(out, "### from root at 0x%p\n\n", p);
+ }
+}
+
+static void PR_CALLBACK
+pr_ConservativeTraceRootBlock(void **base, PRInt32 count)
+{
+ PRInt32 status;
+ ++pr_traceGen;
+ status = pr_ConservativeWalkBlock(base, count, pr_TraceRootPointer, NULL);
+ if (status) {
+ FILE* out = _pr_gcData.dumpOutput;
+ fprintf(out, "### from root in range 0x%p + 0x%lx\n\n",
+ base, (long) count);
+ }
+}
+
+static void
+PR_TraceRoot1(FILE* out, PRBool detailed)
+{
+ RootFinder *rf;
+ void (*liveBlock)(void **base, PRInt32 count);
+ void (*livePointer)(void *ptr);
+ void (*processRootBlock)(void **base, PRInt32 count);
+ void (*processRootPointer)(void *ptr);
+
+ LOCK_GC();
+
+ liveBlock = _pr_gcData.liveBlock;
+ livePointer = _pr_gcData.livePointer;
+ processRootBlock = _pr_gcData.processRootBlock;
+ processRootPointer = _pr_gcData.processRootPointer;
+
+ _pr_gcData.liveBlock = pr_ConservativeTraceRootBlock;
+ _pr_gcData.livePointer = pr_ConservativeTraceRootPointer;
+ _pr_gcData.processRootBlock = pr_ConservativeTraceRootBlock;
+ _pr_gcData.processRootPointer = pr_ConservativeTraceRootPointer;
+ _pr_gcData.dumpOutput = out;
+
+ fprintf(out, "### Looking for paths to 0x%p\n\n", pr_traceObj);
+
+ rf = _pr_rootFinders;
+ while (rf) {
+ fprintf(out, "\n===== Roots for %s\n", rf->name);
+ (*rf->func)(rf->arg);
+ rf = rf->next;
+ }
+
+ _pr_gcData.liveBlock = liveBlock;
+ _pr_gcData.livePointer = livePointer;
+ _pr_gcData.processRootBlock = processRootBlock;
+ _pr_gcData.processRootPointer = processRootPointer;
+ _pr_gcData.dumpOutput = NULL;
+
+ UNLOCK_GC();
+}
+
+PR_PUBLIC_API(void)
+PR_TraceRoot()
+{
+ /*
+ ** How this works:
+ ** Once you find the object you want to trace the roots of, set the
+ ** global variable pr_traceObj to point to it (the header, not the
+ ** java handle), and then call this routine (on Windows, you can set
+ ** a breakpoint at the end of a function that returns void (e.g. dogc)
+ ** and then do a "set next statement" to point to this routine and go.
+ ** This will dump a list of the paths from the roots to the object in
+ ** question to your memory.out file.
+ */
+ PR_DumpToFile("memory.out", "Tracing Roots", PR_TraceRoot1, PR_FALSE);
+}
+
+#endif /* GC_TRACEROOTS */
+
+/******************************************************************************/
+
+#if defined(DEBUG) && defined(WIN32)
+static void DumpApplicationHeap(FILE *out, HANDLE heap)
+{
+ PROCESS_HEAP_ENTRY entry;
+ DWORD err;
+
+ if (!HeapLock(heap))
+ OutputDebugString("Can't lock the heap.\n");
+ entry.lpData = 0;
+ fprintf(out, " address: size ovhd region\n");
+ while (HeapWalk(heap, &entry))
+ {
+ WORD flags = entry.wFlags;
+
+ fprintf(out, "0x%.8X: 0x%.8X 0x%.2X 0x%.2X ", entry.lpData, entry.cbData,
+ entry.cbOverhead, entry.iRegionIndex);
+ if (flags & PROCESS_HEAP_REGION)
+ fprintf(out, "REGION committedSize=0x%.8X uncommittedSize=0x%.8X firstBlock=0x%.8X lastBlock=0x%.8X",
+ entry.Region.dwCommittedSize, entry.Region.dwUnCommittedSize,
+ entry.Region.lpFirstBlock, entry.Region.lpLastBlock);
+ else if (flags & PROCESS_HEAP_UNCOMMITTED_RANGE)
+ fprintf(out, "UNCOMMITTED");
+ else if (flags & PROCESS_HEAP_ENTRY_BUSY)
+ {
+ if (flags & PROCESS_HEAP_ENTRY_DDESHARE)
+ fprintf(out, "DDEShare ");
+ if (flags & PROCESS_HEAP_ENTRY_MOVEABLE)
+ fprintf(out, "Moveable Block handle=0x%.8X", entry.Block.hMem);
+ else
+ fprintf(out, "Block");
+ }
+ fprintf(out, "\n");
+ }
+ if ((err = GetLastError()) != ERROR_NO_MORE_ITEMS)
+ fprintf(out, "ERROR %d iterating through the heap\n", err);
+ if (!HeapUnlock(heap))
+ OutputDebugString("Can't unlock the heap.\n");
+}
+#endif
+
+#if defined(DEBUG) && defined(WIN32)
+static void DumpApplicationHeaps(FILE *out)
+{
+ HANDLE mainHeap;
+ HANDLE heaps[100];
+ DWORD nHeaps;
+ PRInt32 i;
+
+ mainHeap = GetProcessHeap();
+ nHeaps = GetProcessHeaps(100, heaps);
+ if (nHeaps > 100)
+ nHeaps = 0;
+ fprintf(out, "%ld heaps:\n", (long) nHeaps);
+ for (i = 0; i<nHeaps; i++)
+ {
+ HANDLE heap = heaps[i];
+
+ fprintf(out, "Heap at 0x%.8lX", (long) heap);
+ if (heap == mainHeap)
+ fprintf(out, " (main)");
+ fprintf(out, ":\n");
+ DumpApplicationHeap(out, heap);
+ fprintf(out, "\n");
+ }
+ fprintf(out, "End of heap dump\n\n");
+}
+#endif
+
+#if defined(DEBUG) && defined(WIN32)
+PR_IMPLEMENT(void) PR_DumpApplicationHeaps(void)
+{
+ FILE *out;
+
+ OutputDebugString("Dumping heaps...");
+ out = fopen("heaps.out", "a");
+ if (!out)
+ OutputDebugString("Can't open \"heaps.out\"\n");
+ else
+ {
+ struct tm *newtime;
+ time_t aclock;
+
+ time(&aclock);
+ newtime = localtime(&aclock);
+ fprintf(out, "Heap dump on %s\n", asctime(newtime)); /* Print current time */
+ DumpApplicationHeaps(out);
+ fprintf(out, "\n\n");
+ fclose(out);
+ }
+ OutputDebugString(" done\n");
+}
+#else
+
+PR_IMPLEMENT(void) PR_DumpApplicationHeaps(void)
+{
+ fprintf(stderr, "Native heap dumping is currently implemented only for Windows32.\n");
+}
+#endif
+
+/************************************************************************/
+
+/*
+** Scan the freelist bins looking for a big enough chunk of memory to
+** hold "bytes" worth of allocation. "bytes" already has the
+** per-allocation header added to it. Return a pointer to the object with
+** its per-allocation header already prepared.
+*/
+static PRWord *BinAlloc(int cbix, PRInt32 bytes, int dub)
+{
+ GCFreeChunk **cpp, *cp, *cpNext;
+ GCSeg *sp;
+ PRInt32 chunkSize, remainder;
+ PRWord *p, *np;
+ PRInt32 bin, newbin;
+
+ /* Compute bin that allocation belongs in */
+ InlineBinNumber(bin,bytes)
+ if (bin < minBin) {
+ bin = minBin; /* Start at first filled bin */
+ }
+
+ /* Search in the bin, and larger bins, for a big enough piece */
+ for (; bin <= NUM_BINS-1; bin++) {
+ cpp = &bins[bin];
+ while ((cp = *cpp) != 0) {
+ chunkSize = cp->chunkSize;
+ if (chunkSize < bytes) {
+ /* Too small; skip it */
+ METER(meter.skippedFreeChunks++);
+ cpp = &cp->next;
+ continue;
+ }
+
+ /* We have found a hunk of memory large enough to use */
+ p = (PRWord*) cp;
+ sp = cp->segment;
+ cpNext = cp->next;
+#ifndef IS_64
+ if (dub && (((PRWord)p & (PR_BYTES_PER_DWORD-1)) == 0)) {
+ /*
+ * We are double aligning the memory and the current free
+ * chunk is aligned on an even boundary. Because header
+ * words are one word long we need to discard the first
+ * word of memory.
+ */
+ p[0] = MAKE_HEADER(FREE_MEMORY_TYPEIX, 1);
+ SET_HBIT(sp, p);
+ p++;
+ chunkSize -= PR_BYTES_PER_WORD;
+ bytes -= PR_BYTES_PER_WORD;
+ PR_ASSERT(((PRWord)p & (PR_BYTES_PER_DWORD-1)) != 0);
+ _pr_gcData.freeMemory -= PR_BYTES_PER_WORD;
+ _pr_gcData.busyMemory += PR_BYTES_PER_WORD;
+ }
+#endif
+ np = (PRWord*) ((char*) p + bytes);
+ remainder = chunkSize - bytes;
+ if (remainder >= MIN_FREE_CHUNK_BYTES) {
+ /* The left over memory is large enough to be freed. */
+ cp = (GCFreeChunk*) np;
+ cp->segment = sp;
+ cp->chunkSize = remainder;
+ InlineBinNumber(newbin, remainder)
+ if (newbin != bin) {
+ *cpp = (GCFreeChunk*) cpNext; /* remove */
+ cp->next = bins[newbin]; /* insert */
+ bins[newbin] = cp;
+ if (newbin < minBin) minBin = newbin;
+ if (newbin > maxBin) maxBin = newbin;
+ } else {
+ /* Leave it on the same list */
+ cp->next = cpNext;
+ *cpp = (GCFreeChunk*) np;
+ }
+ } else {
+ /*
+ * The left over memory is too small to be released. Just
+ * leave it attached to the chunk of memory being
+ * returned.
+ */
+ *cpp = cpNext;
+ bytes = chunkSize;
+ }
+ p[0] = MAKE_HEADER(cbix, (bytes >> PR_BYTES_PER_WORD_LOG2));
+ SET_HBIT(sp, p);
+ _pr_gcData.freeMemory -= bytes;
+ _pr_gcData.busyMemory += bytes;
+ return p;
+ }
+ }
+ return 0;
+}
+
+/*
+** Allocate a piece of memory that is "big" in it's own segment. Make
+** the object consume the entire segment to avoid fragmentation. When
+** the object is no longer referenced, the segment is freed.
+*/
+static PRWord *BigAlloc(int cbix, PRInt32 bytes, int dub)
+{
+ GCSeg *sp;
+ PRWord *p, h;
+ PRInt32 chunkSize;
+
+ /*
+ ** If the number of bytes allocated via BigAlloc() since the last GC
+ ** exceeds BIG_ALLOC_GC_SIZE then do a GC Now...
+ */
+ if (bigAllocBytes >= BIG_ALLOC_GC_SIZE) {
+ dogc();
+ }
+ bigAllocBytes += bytes;
+
+ /* Get a segment to hold this allocation */
+ sp = GrowHeapExactly(bytes);
+
+ if (sp) {
+ p = (PRWord*) sp->base;
+ chunkSize = sp->limit - sp->base;
+
+ /* All memory is double aligned on 64 bit machines... */
+#ifndef IS_64
+ if (dub && (((PRWord)p & (PR_BYTES_PER_DWORD-1)) == 0)) {
+ /*
+ ** Consume the first word of the chunk with a dummy
+ ** unreferenced object.
+ */
+ p[0] = MAKE_HEADER(FREE_MEMORY_TYPEIX, 1);
+ SET_HBIT(sp, p);
+ p++;
+ chunkSize -= PR_BYTES_PER_WORD;
+ _pr_gcData.freeMemory -= PR_BYTES_PER_WORD;
+ _pr_gcData.busyMemory += PR_BYTES_PER_WORD;
+ PR_ASSERT(((PRWord)p & (PR_BYTES_PER_DWORD-1)) != 0);
+ }
+#endif
+
+#if defined(WIN16)
+ /* All memory MUST be aligned on 32bit boundaries */
+ PR_ASSERT( (((PRWord)p) & (PR_BYTES_PER_WORD-1)) == 0 );
+#endif
+
+ /* Consume the *entire* segment with a single allocation */
+ h = MAKE_HEADER(cbix, (chunkSize >> PR_BYTES_PER_WORD_LOG2));
+ p[0] = h;
+ SET_HBIT(sp, p);
+ _pr_gcData.freeMemory -= chunkSize;
+ _pr_gcData.busyMemory += chunkSize;
+ return p;
+ }
+ return 0;
+}
+
+/* we disable gc allocation during low memory conditions */
+static PRBool allocationEnabled = PR_TRUE;
+
+PR_IMPLEMENT(void) PR_EnableAllocation(PRBool yesOrNo)
+{
+ allocationEnabled = yesOrNo;
+}
+
+static void CollectorCleanup(void) {
+ while (collectorCleanupNeeded) {
+ LOCK_GC();
+ collectorCleanupNeeded = 0;
+ UNLOCK_GC();
+ if (freeSegs) {
+ FreeSegments();
+ }
+ if (!WEAK_FREELIST_ISEMPTY()) {
+ EmptyWeakFreeList();
+ }
+ }
+}
+
+/******************************************************************************/
+
+#ifdef GC_CHECK
+static PRInt32 allocationCount;
+
+static void EarthShatteringKaBoom(PRInt32 whichOne) {
+ long* p = 0;
+ *p = 0;
+}
+
+/* Check a segment of heap memory. Verify that the object memory
+ hasn't been overwritten (past the end at least) */
+static void CheckSegment(GCSeg* sp) {
+ PRWord h, tix;
+ PRWord *p, *lastp, *np, *limit;
+
+ lastp = p = (PRWord *) sp->base;
+ limit = (PRWord *) sp->limit;
+ while (p < limit) {
+ if (IS_HBIT(sp, p)) {
+ char *cp, i;
+ GCBlockEnd* end;
+ PRWord bytes, requestedBytes;
+
+ h = p[0];
+ tix = GET_TYPEIX(h);
+ bytes = OBJ_BYTES(h);
+ np = (PRWord *) ((char *)p + bytes);
+ if (tix != FREE_MEMORY_TYPEIX) {
+ PRInt32 test; /* msdev get's fooled without this local */
+ /* A live object is here. The last word in the object will
+ contain the objects requestedSize */
+ end = (GCBlockEnd*)((char*)(p) + bytes - sizeof(GCBlockEnd));
+ test = end->check;
+ if (test != PR_BLOCK_END) {
+ PR_ASSERT(test == PR_BLOCK_END);
+ }
+ requestedBytes = end->requestedBytes;
+ if (requestedBytes >= bytes) EarthShatteringKaBoom(0);
+ cp = (char*)(p + 1) + requestedBytes;
+ i = (char) 0xff;
+ while (cp < (char*)end) {
+ if (*cp != i) EarthShatteringKaBoom(1);
+ cp++;
+ i--;
+ }
+ }
+ lastp = p;
+ p = np;
+ } else {
+ /* Must be a freelist item */
+ GCFreeChunk *cp = (GCFreeChunk*) p;
+ if ((PRInt32)cp->chunkSize < (PRInt32)sizeof(GCFreeChunk)) {
+ EarthShatteringKaBoom(3);
+ }
+ lastp = p;
+ p = (PRWord*) ((char*)p + cp->chunkSize);
+ }
+ }
+}
+
+static void CheckHeap(void) {
+ GCSeg *sp = segs;
+ GCSeg *esp = sp + nsegs;
+ while (sp < esp) {
+ CheckSegment(sp);
+ sp++;
+ }
+}
+
+#endif /* GC_CHECK */
+
+/******************************************************************************/
+
+#ifdef DEBUG
+long gc_thrash = -1L;
+#endif
+
+/*
+** Allocate memory from the GC Heap. Performs garbage collections if
+** memory gets tight and grows the heap as needed. May return NULL if
+** memory cannot be found.
+*/
+PR_IMPLEMENT(PRWord GCPTR *)PR_AllocMemory(
+ PRWord requestedBytes, PRInt32 tix, PRWord flags)
+{
+ PRWord *p;
+ CollectorType *ct;
+ PRInt32 bytes;
+ GCFinal *final = 0;
+ GCWeak *weak = 0;
+ int dub = flags & PR_ALLOC_DOUBLE;
+ PRInt32 objBytes;
+#ifdef GC_STATS
+ PRInt64 allocTime, ldelta;
+#endif
+
+ if (!allocationEnabled) return NULL;
+
+ PR_ASSERT(requestedBytes >= 0);
+ PR_ASSERT(_pr_collectorTypes[tix].flags != 0);
+
+#ifdef DEBUG
+ if (_pr_do_a_dump) {
+ /*
+ ** Collect, pause for a second (lets finalizer run), and then GC
+ ** again.
+ */
+ PR_GC();
+ PR_Sleep(PR_MicrosecondsToInterval(1000000L));
+ PR_GC();
+ PR_DumpGCHeap(_pr_dump_file, PR_TRUE);
+ _pr_do_a_dump = 0;
+ }
+#endif
+
+#ifdef GC_STATS
+ allocTime = PR_Now();
+#endif
+ bytes = (PRInt32) requestedBytes;
+
+ /*
+ ** Align bytes to a multiple of a PRWord, then add in enough space
+ ** to hold the header word.
+ **
+ ** MSVC 1.52 crashed on the ff. code because of the "complex" shifting :-(
+ */
+#if !defined(WIN16)
+ /* Check for possible overflow of bytes before performing add */
+ if ((MAX_INT - PR_BYTES_PER_WORD) < bytes ) return NULL;
+ bytes = (bytes + PR_BYTES_PER_WORD - 1) >> PR_BYTES_PER_WORD_LOG2;
+ bytes <<= PR_BYTES_PER_WORD_LOG2;
+ /* Check for possible overflow of bytes before performing add */
+ if ((MAX_INT - sizeof(PRWord)) < bytes ) return NULL;
+ bytes += sizeof(PRWord);
+#else
+ /*
+ ** For WIN16 the shifts have been broken out into separate statements
+ ** to prevent the compiler from crashing...
+ */
+ {
+ PRWord shiftVal;
+
+ /* Check for possible overflow of bytes before performing add */
+ if ((MAX_INT - PR_BYTES_PER_WORD) < bytes ) return NULL;
+ bytes += PR_BYTES_PER_WORD - 1L;
+ shiftVal = PR_BYTES_PER_WORD_LOG2;
+ bytes >>= shiftVal;
+ bytes <<= shiftVal;
+ /* Check for possible overflow of bytes before performing add */
+ if ((MAX_INT - sizeof(PRWord)) < bytes ) return NULL;
+ bytes += sizeof(PRWord);
+ }
+#endif
+ /*
+ * Add in an extra word of memory for double-aligned memory. Some
+ * percentage of the time this will waste a word of memory (too
+ * bad). Howver, it makes the allocation logic much simpler and
+ * faster.
+ */
+#ifndef IS_64
+ if (dub) {
+ /* Check for possible overflow of bytes before performing add */
+ if ((MAX_INT - PR_BYTES_PER_WORD) < bytes ) return NULL;
+ bytes += PR_BYTES_PER_WORD;
+ }
+#endif
+
+#ifdef GC_CHECK
+ if (_pr_gcData.flags & GC_CHECK) {
+ /* Bloat the allocation a bit so that we can lay down
+ a check pattern that we will validate */
+ /* Check for possible overflow of bytes before performing add */
+ if ((MAX_INT - PR_BYTES_PER_WORD * 3) < bytes ) return NULL;
+ bytes += PR_BYTES_PER_WORD * 3;
+ }
+#endif
+
+#if defined(GC_CHECK) || defined(GC_STATS) || defined(GC_TRACEROOTS)
+ if ((MAX_INT - sizeof(GCBlockEnd)) < bytes ) return NULL;
+ bytes += sizeof(GCBlockEnd);
+#endif
+
+ PR_ASSERT( bytes < MAX_ALLOC_SIZE );
+ /*
+ ** Java can ask for objects bigger than MAX_ALLOC_SIZE,
+ ** but it won't get them.
+ */
+ if (bytes >= MAX_ALLOC_SIZE) return NULL;
+
+#ifdef DEBUG
+ if (gc_thrash == -1L ? (gc_thrash = (long)PR_GetEnv("GC_THRASH")):gc_thrash) PR_GC();
+#endif
+
+ ct = &_pr_collectorTypes[tix];
+ if (ct->flags & (_GC_TYPE_FINAL|_GC_TYPE_WEAK)) {
+ if (0 != ct->gctype.finalize) {
+ /*
+ ** Allocate a GCFinal struct for this object in advance. Don't put
+ ** it on the pending list until we have allocated the object
+ */
+ final = AllocFinalNode();
+ if (!final) {
+ /* XXX THIS IS NOT ACCEPTABLE*/
+ PR_ASSERT(0);
+ return 0;
+ }
+ }
+ if (0 != ct->gctype.getWeakLinkOffset) {
+ /*
+ ** Allocate a GCWeak struct for this object in advance. Don't put
+ ** it on the weak links list until we have allocated the object
+ */
+ weak = AllocWeakNode();
+ if (!weak) {
+ /* XXX THIS IS NOT ACCEPTABLE*/
+ if (0 != final) {
+ FreeFinalNode(final);
+ }
+ PR_ASSERT(0);
+ return 0;
+ }
+ }
+ }
+
+ LOCK_GC();
+#ifdef GC_CHECK
+ if (_pr_gcData.flags & GC_CHECK) CheckHeap();
+ allocationCount++;
+#endif
+
+ /* Check for overflow of maximum size we can handle */
+ if (bytes > MAX_ALLOC) goto lost;
+
+ /* Try default allocation */
+ p = ((bytes >= BIG_ALLOC) && (nsegs < MAX_SEGS)) ?
+ BigAlloc(tix, bytes, dub) : BinAlloc(tix, bytes, dub);
+ if (0 == p) {
+#ifdef GC_STATS
+ LL_SUB(ldelta, PR_Now(), allocTime);
+#endif
+ /* Collect some memory */
+ _GCTRACE(GC_ALLOC, ("force GC: want %d", bytes));
+ dogc();
+ PR_ASSERT( GC_IS_LOCKED() );
+
+ /* After a collection we check and see if we should grow the
+ ** heap. We grow the heap when the amount of memory free is less
+ ** than a certain percentage of the heap size. We don't check to
+ ** see if the grow succeeded because our fallback strategy in
+ ** either case is to try one more time to allocate. */
+ if ((_pr_gcData.allocMemory < _pr_gcData.maxMemory)
+ && ((_pr_gcData.freeMemory <
+ ((_pr_gcData.allocMemory * MIN_FREE_THRESHOLD_AFTER_GC) / 100L))
+ || (_pr_gcData.freeMemory < bytes))) {
+ GrowHeap(PR_MAX(bytes, segmentSize));
+ }
+#ifdef GC_STATS
+ LL_ADD(allocTime, PR_Now(), ldelta);
+#endif
+
+ /* Try again */
+ p = ((bytes >= BIG_ALLOC) && (nsegs < MAX_SEGS)) ?
+ BigAlloc(tix, bytes, dub) : BinAlloc(tix, bytes, dub);
+ if (0 == p) {
+ /* Well that lost big time. Memory must be pretty well fragmented */
+ if (!GrowHeap(PR_MAX(bytes, segmentSize))) goto lost;
+ p = BinAlloc(tix, bytes, dub);
+ if (0 == p) goto lost;
+ }
+ }
+
+ /* Zero out the portion of the object memory that was used by
+ the GCFreeChunk structure (skip the first word because it
+ was already overwritten by the gc header word) */
+ objBytes = OBJ_BYTES(p[0]);
+ if (objBytes > sizeof(PRWord)) p[1] = 0;
+ if (objBytes > sizeof(PRWord)*2) p[2] = 0;
+
+ if (final) {
+ _GCTRACE(GC_ALLOC, ("alloc 0x%x (%d) final=0x%x",
+ p, bytes, final));
+ final->object = p;
+ PR_APPEND_LINK(&final->links, &_pr_finalizeableObjects);
+ } else {
+ _GCTRACE(GC_ALLOC, ("alloc 0x%x (%d)", p, bytes));
+ }
+ if (weak) {
+ weak->object = p;
+ PR_APPEND_LINK(&weak->links, &_pr_weakLinks);
+ }
+ METER(meter.allocBytes += bytes);
+ METER(meter.wastedBytes += (bytes - requestedBytes));
+ UNLOCK_GC();
+
+ if (collectorCleanupNeeded) {
+ CollectorCleanup();
+ }
+
+#if defined(GC_CHECK) || defined(GC_STATS) || defined(GC_TRACEROOTS)
+ {
+ GCBlockEnd* end = (GCBlockEnd*)((char*)p + OBJ_BYTES(p[0]) - sizeof(GCBlockEnd));
+ end->check = PR_BLOCK_END;
+ }
+#endif
+#ifdef GC_STATS
+ {
+ PRInt64 now = PR_Now();
+ double delta;
+ PRInt32 bin;
+ GCBlockEnd* end = (GCBlockEnd*)((char*)p + OBJ_BYTES(p[0]) - sizeof(GCBlockEnd));
+
+ end->allocTime = allocTime;
+ LL_SUB(ldelta, now, allocTime);
+ LL_L2D(delta, ldelta);
+ InlineBinNumber(bin, requestedBytes);
+ end->bin = bin;
+ gcstats[bin].nallocs++;
+ gcstats[bin].allocTime += delta;
+ gcstats[bin].allocTimeVariance += delta * delta;
+ }
+#endif
+#ifdef GC_CHECK
+ if (_pr_gcData.flags & GC_CHECK) {
+ /* Place a pattern in the memory that was allocated that was not
+ requested. We will check the pattern later. */
+ char* cp = (char*)(p + 1) + requestedBytes;
+ GCBlockEnd* end = (GCBlockEnd*)((char*)p + OBJ_BYTES(p[0]) - sizeof(GCBlockEnd));
+ char i = (char) 0xff;
+ while (cp < (char*)end) {
+ *cp++ = i--;
+ }
+ end->requestedBytes = requestedBytes;
+ CheckHeap();
+ }
+#endif
+ return p + 1;
+
+ lost:
+ /* Out of memory */
+ UNLOCK_GC();
+ if (final) {
+ FreeFinalNode(final);
+ }
+ if (weak) {
+ FreeWeakNode(weak);
+ }
+ if (collectorCleanupNeeded) {
+ CollectorCleanup();
+ }
+ return 0;
+}
+
+/* Shortcut allocator for objects that do not require finalization or
+ are weak objects */
+PR_IMPLEMENT(PRWord GCPTR *)
+PR_AllocSimpleMemory(PRWord requestedBytes, PRInt32 tix)
+{
+ PRWord *p;
+ PRInt32 bytes;
+ PRInt32 objBytes;
+#ifdef GC_STATS
+ PRInt64 allocTime, ldelta;
+#endif
+
+ if (!allocationEnabled) return NULL;
+
+ PR_ASSERT(requestedBytes >= 0);
+ PR_ASSERT(_pr_collectorTypes[tix].flags != 0);
+
+#ifdef DEBUG
+ if (_pr_do_a_dump) {
+ /*
+ ** Collect, pause for a second (lets finalizer run), and then GC
+ ** again.
+ */
+ PR_GC();
+ PR_Sleep(PR_MicrosecondsToInterval(1000000L));
+ PR_GC();
+ PR_DumpGCHeap(_pr_dump_file, PR_TRUE);
+ _pr_do_a_dump = 0;
+ }
+#endif
+
+#ifdef GC_STATS
+ allocTime = PR_NowMS();
+#endif
+ bytes = (PRInt32) requestedBytes;
+
+ /*
+ ** Align bytes to a multiple of a PRWord, then add in enough space
+ ** to hold the header word.
+ **
+ ** MSVC 1.52 crashed on the ff. code because of the "complex" shifting :-(
+ */
+#if !defined(WIN16)
+ bytes = (bytes + PR_BYTES_PER_WORD - 1) >> PR_BYTES_PER_WORD_LOG2;
+ bytes <<= PR_BYTES_PER_WORD_LOG2;
+ bytes += sizeof(PRWord);
+#else
+ /*
+ ** For WIN16 the shifts have been broken out into separate statements
+ ** to prevent the compiler from crashing...
+ */
+ {
+ PRWord shiftVal;
+
+ bytes += PR_BYTES_PER_WORD - 1L;
+ shiftVal = PR_BYTES_PER_WORD_LOG2;
+ bytes >>= shiftVal;
+ bytes <<= shiftVal;
+ bytes += sizeof(PRWord);
+ }
+#endif
+
+ /*
+ * Add in an extra word of memory for double-aligned memory. Some
+ * percentage of the time this will waste a word of memory (too
+ * bad). Howver, it makes the allocation logic much simpler and
+ * faster.
+ */
+#ifndef IS_64
+ bytes += PR_BYTES_PER_WORD;
+#endif
+
+#ifdef GC_CHECK
+ if (_pr_gcData.flags & GC_CHECK) {
+ /* Bloat the allocation a bit so that we can lay down
+ a check pattern that we will validate */
+ bytes += PR_BYTES_PER_WORD * 2;
+ }
+#endif
+
+#if defined(GC_CHECK) || defined(GC_STATS) || defined(GC_TRACEROOTS)
+ bytes += sizeof(GCBlockEnd);
+#endif
+
+#if defined(WIN16)
+ PR_ASSERT( bytes < MAX_ALLOC_SIZE );
+#endif
+ /* Java can ask for objects bigger than 4M, but it won't get them */
+ /*
+ * This check was added because there is a fundamental limit of
+ * the size field maintained by the gc code. Going over the 4M
+ * limit caused some bits to roll over into another bit field,
+ * violating the max segment size and causing a bug.
+ */
+ if (bytes >= MAX_ALLOC_SIZE) {
+ return NULL;
+ }
+#ifdef DEBUG
+ if (gc_thrash == -1L
+ ? (gc_thrash = (long)PR_GetEnv("GC_THRASH"))
+ : gc_thrash) {
+ PR_GC();
+ }
+#endif
+
+ LOCK_GC();
+#ifdef GC_CHECK
+ if (_pr_gcData.flags & GC_CHECK) {
+ CheckHeap();
+ }
+ allocationCount++;
+#endif
+
+ /* Try default allocation */
+ if ((bytes >= BIG_ALLOC) && (nsegs < MAX_SEGS)) {
+ p = BigAlloc(tix, bytes, 1);
+ } else {
+ p = BinAlloc(tix, bytes, 1);
+ }
+ if (0 == p) {
+#ifdef GC_STATS
+ LL_SUB(ldelta, PR_Now(), allocTime);
+#endif
+ /* Collect some memory */
+ _GCTRACE(GC_ALLOC, ("force GC: want %d", bytes));
+ dogc();
+ PR_ASSERT( GC_IS_LOCKED() );
+
+ /* After a collection we check and see if we should grow the
+ heap. We grow the heap when the amount of memory free is less
+ than a certain percentage of the heap size. We don't check to
+ see if the grow succeeded because our fallback strategy in
+ either case is to try one more time to allocate. */
+ if ((_pr_gcData.allocMemory < _pr_gcData.maxMemory) &&
+ (_pr_gcData.freeMemory <
+ ((_pr_gcData.allocMemory * MIN_FREE_THRESHOLD_AFTER_GC) / 100L))) {
+ GrowHeap(PR_MAX(bytes, segmentSize));
+ }
+#ifdef GC_STATS
+ LL_ADD(allocTime, PR_Now(), ldelta);
+#endif
+
+ /* Try one last time */
+ if ((bytes >= BIG_ALLOC) && (nsegs < MAX_SEGS)) {
+ p = BigAlloc(tix, bytes, 1);
+ } else {
+ p = BinAlloc(tix, bytes, 1);
+ }
+ if (0 == p) {
+ /* Well that lost big time. Memory must be pretty well fragmented */
+ if (!GrowHeap(PR_MAX(bytes, segmentSize))) {
+ goto lost;
+ }
+ p = BinAlloc(tix, bytes, 1);
+ if (0 == p) goto lost;
+ }
+ }
+
+ /* Zero out the portion of the object memory that was used by
+ the GCFreeChunk structure (skip the first word because it
+ was already overwritten by the gc header word) */
+ objBytes = OBJ_BYTES(p[0]);
+ if (objBytes > sizeof(PRWord)) p[1] = 0;
+ if (objBytes > sizeof(PRWord)*2) p[2] = 0;
+
+ METER(meter.allocBytes += bytes);
+ METER(meter.wastedBytes += (bytes - requestedBytes));
+ UNLOCK_GC();
+
+ if (collectorCleanupNeeded) {
+ CollectorCleanup();
+ }
+
+#if defined(GC_CHECK) || defined(GC_STATS) || defined(GC_TRACEROOTS)
+ {
+ GCBlockEnd* end = (GCBlockEnd*)((char*)p + OBJ_BYTES(p[0]) - sizeof(GCBlockEnd));
+ end->check = PR_BLOCK_END;
+ }
+#endif
+#ifdef GC_STATS
+ {
+ PRInt64 now = PR_Now();
+ double delta;
+ PRInt32 bin;
+ GCBlockEnd* end = (GCBlockEnd*)((char*)p + OBJ_BYTES(p[0]) - sizeof(GCBlockEnd));
+
+ end->allocTime = allocTime;
+ LL_SUB(ldelta, now, allocTime);
+ LL_L2D(delta, ldelta);
+ InlineBinNumber(bin, requestedBytes);
+ end->bin = bin;
+ gcstats[bin].nallocs++;
+ gcstats[bin].allocTime += delta;
+ gcstats[bin].allocTimeVariance += delta * delta;
+ }
+#endif
+#ifdef GC_CHECK
+ if (_pr_gcData.flags & GC_CHECK) {
+ /* Place a pattern in the memory that was allocated that was not
+ requested. We will check the pattern later. */
+ char* cp = (char*)(p + 1) + requestedBytes;
+ GCBlockEnd* end = (GCBlockEnd*)((char*)p + OBJ_BYTES(p[0]) - sizeof(GCBlockEnd));
+ char i = (char) 0xff;
+ while (cp < (char*)end) {
+ *cp++ = i--;
+ }
+ end->requestedBytes = requestedBytes;
+ CheckHeap();
+ }
+#endif
+ return p + 1;
+
+ lost:
+ /* Out of memory */
+ UNLOCK_GC();
+ if (collectorCleanupNeeded) {
+ CollectorCleanup();
+ }
+ return 0;
+}
+
+/************************************************************************/
+
+PR_IMPLEMENT(PRWord) PR_GetObjectHeader(void *ptr) {
+ GCSeg *sp;
+ PRWord *h;
+
+ if (ptr == 0) return 0;
+ sp = InHeap(ptr);
+ if (sp == 0) return 0;
+ h = (PRWord*)FindObject(sp, (PRWord*)ptr);
+ return GC_GET_USER_BITS(h[0]);
+}
+
+PR_IMPLEMENT(PRWord) PR_SetObjectHeader(void *ptr, PRWord newUserBits) {
+ GCSeg *sp;
+ PRWord *h, rv;
+
+ if (ptr == 0) return 0;
+ sp = InHeap(ptr);
+ if (sp == 0) return 0;
+ h = (PRWord*)FindObject(sp, (PRWord*)ptr);
+ rv = GC_GET_USER_BITS(h[0]);
+ h[0] = (h[0] & ~GC_USER_BITS) |
+ ((newUserBits << GC_USER_BITS_SHIFT) & GC_USER_BITS);
+ return rv;
+}
+
+PR_IMPLEMENT(void) PR_InitGC(
+ PRWord flags, PRInt32 initialHeapSize, PRInt32 segSize, PRThreadScope scope)
+{
+ static char firstTime = 1;
+
+ if (!firstTime) return;
+ firstTime = 0;
+
+ _pr_msgc_lm = PR_NewLogModule("msgc");
+ _pr_pageShift = PR_GetPageShift();
+ _pr_pageSize = PR_GetPageSize();
+
+#if defined(WIN16)
+ PR_ASSERT( initialHeapSize < MAX_ALLOC_SIZE );
+#endif
+
+ /* Setup initial heap size and initial segment size */
+ if (0 != segSize) segmentSize = segSize;
+#ifdef DEBUG
+ GC = PR_NewLogModule("GC");
+ {
+ char *ev = PR_GetEnv("GC_SEGMENT_SIZE");
+ if (ev && ev[0]) {
+ PRInt32 newSegmentSize = atoi(ev);
+ if (0 != newSegmentSize) segmentSize = newSegmentSize;
+ }
+ ev = PR_GetEnv("GC_INITIAL_HEAP_SIZE");
+ if (ev && ev[0]) {
+ PRInt32 newInitialHeapSize = atoi(ev);
+ if (0 != newInitialHeapSize) initialHeapSize = newInitialHeapSize;
+ }
+ ev = PR_GetEnv("GC_FLAGS");
+ if (ev && ev[0]) {
+ flags |= atoi(ev);
+ }
+#ifdef GCMETER
+ ev = PR_GetEnv("GC_METER");
+ if (ev && ev[0]) {
+ _pr_gcMeter = atoi(ev);
+ }
+#endif
+ }
+#endif
+ if (0 == initialHeapSize) initialHeapSize = segmentSize;
+ if (initialHeapSize < segmentSize) initialHeapSize = segmentSize;
+
+ _pr_gcData.maxMemory = MAX_SEGS * segmentSize;
+ _pr_gcData.liveBlock = ProcessRootBlock;
+ _pr_gcData.livePointer = ProcessRootPointer;
+ _pr_gcData.processRootBlock = ProcessRootBlock;
+ _pr_gcData.processRootPointer = ProcessRootPointer;
+ _pr_gcData.dumpOutput = NULL;
+
+ PR_INIT_CLIST(&_pr_finalizeableObjects);
+ PR_INIT_CLIST(&_pr_finalQueue);
+ _PR_InitGC(flags);
+
+ /* Create finalizer thread */
+ _PR_CreateFinalizer(scope);
+
+ /* Allocate the initial segment for the heap */
+ minBin = 31;
+ maxBin = 0;
+ GrowHeap(initialHeapSize);
+ PR_RegisterRootFinder(ScanWeakFreeList, "scan weak free list", 0);
+}
+
+#if defined(WIN16)
+/*
+** For WIN16 the GC_IN_HEAP() macro must call the private InHeap function.
+** This public wrapper function makes this possible...
+*/
+PR_IMPLEMENT(PRBool)
+PR_GC_In_Heap(void *object)
+{
+ return InHeap( object ) != NULL;
+}
+#endif
+
+
+/** Added by Vishy for sanity checking a few GC structures **/
+/** Can use SanityCheckGC to debug corrupted GC Heap situations **/
+
+#ifdef DEBUG
+
+static int SegmentOverlaps(int i, int j)
+{
+ return
+ (((segs[i].limit > segs[j].base) && (segs[i].base < segs[j].base)) ||
+ ((segs[j].limit > segs[i].base) && (segs[j].base < segs[i].base)));
+}
+
+static void NoSegmentOverlaps(void)
+{
+ int i,j;
+
+ for (i = 0; i < nsegs; i++)
+ for (j = i+1 ; j < nsegs ; j++)
+ PR_ASSERT(!SegmentOverlaps(i,j));
+}
+
+static void SegInfoCheck(void)
+{
+ int i;
+ for (i = 0 ; i < nsegs ; i++)
+ PR_ASSERT((segs[i].info->hbits) &&
+ (segs[i].info->hbits == segs[i].hbits) &&
+ (segs[i].info->base == segs[i].base) &&
+ (segs[i].info->limit == segs[i].limit));
+}
+
+static void SanityCheckGC()
+{
+ NoSegmentOverlaps();
+ SegInfoCheck();
+}
+
+#endif
+
+#if defined(DEBUG) && defined(WIN32)
+
+extern void *baseaddr;
+extern void *lastaddr;
+
+PR_IMPLEMENT(void)
+PR_PrintGCStats(void)
+{
+ long reportedSegSpace = _pr_gcData.busyMemory + _pr_gcData.freeMemory;
+ char* msg;
+ long largeCount = 0, largeSize = 0;
+ long segCount = 0, segSize = 0;
+ long freeCount = 0, freeSize = 0;
+ GCSeg *sp, *esp;
+ GCSegInfo* si;
+
+ LOCK_GC();
+
+ sp = segs;
+ esp = sp + nsegs;
+ while (sp < esp) {
+ long size = sp->info->limit - sp->info->base;
+ segCount++;
+ segSize += size;
+ if (sp->info->fromMalloc) {
+ largeCount++;
+ largeSize += size;
+ }
+ sp++;
+ }
+
+ si = freeSegs;
+ while (si != NULL) {
+ long size = si->limit - si->base;
+ freeCount++;
+ freeSize += size;
+ si = si->next;
+ }
+
+ msg = PR_smprintf("\
+# GC Stats:\n\
+# vm space:\n\
+# range: %ld - %ld\n\
+# size: %ld\n\
+# segments:\n\
+# range: %ld - %ld\n\
+# count: %ld (reported: %ld)\n\
+# size: %ld (reported: %ld)\n\
+# free count: %ld\n\
+# free size: %ld\n\
+# busy objs: %ld (%ld%%)\n\
+# free objs: %ld (%ld%%)\n\
+# large blocks:\n\
+# count: %ld\n\
+# total size: %ld (%ld%%)\n\
+# avg size: %ld\n\
+",
+ /* vm space */
+ (long)baseaddr, (long)lastaddr,
+ (long)lastaddr - (long)baseaddr,
+ /* segments */
+ _pr_gcData.lowSeg, _pr_gcData.highSeg,
+ segCount, nsegs,
+ segSize, reportedSegSpace,
+ freeCount,
+ freeSize,
+ _pr_gcData.busyMemory,
+ (_pr_gcData.busyMemory * 100 / reportedSegSpace),
+ _pr_gcData.freeMemory,
+ (_pr_gcData.freeMemory * 100 / reportedSegSpace),
+ /* large blocks */
+ largeCount,
+ largeSize, (largeSize * 100 / reportedSegSpace),
+ (largeCount ? largeSize / largeCount : 0)
+ );
+ UNLOCK_GC();
+ fprintf(stderr, msg);
+ OutputDebugString(msg);
+ PR_smprintf_free(msg);
+#ifdef GC_STATS
+ PR_PrintGCAllocStats();
+#endif
+}
+#endif
+
+PR_IMPLEMENT(void)
+PR_DumpToFile(char* filename, char* msg, PRFileDumper dump, PRBool detailed)
+{
+ FILE *out;
+ OutputDebugString(msg);
+ out = fopen(filename, "a");
+ if (!out) {
+ char buf[64];
+ PR_ASSERT(strlen(filename) < sizeof(buf) - 16);
+ PR_snprintf(buf, sizeof(buf), "Can't open \"%s\"\n",
+ filename);
+ OutputDebugString(buf);
+ }
+ else
+ {
+ struct tm *newtime;
+ time_t aclock;
+ int i;
+
+ time(&aclock);
+ newtime = localtime(&aclock);
+ fprintf(out, "%s on %s\n", msg, asctime(newtime)); /* Print current time */
+ dump(out, detailed);
+ fprintf(out, "\n\n");
+ for (i = 0; i < 80; i++)
+ fprintf(out, "=");
+ fprintf(out, "\n\n");
+ fclose(out);
+ }
+ OutputDebugString(" done\n");
+}
+
diff --git a/src/libs/xpcom18a4/nsprpub/lib/msgc/src/unixgc.c b/src/libs/xpcom18a4/nsprpub/lib/msgc/src/unixgc.c
new file mode 100644
index 00000000..cea4225e
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/msgc/src/unixgc.c
@@ -0,0 +1,155 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "prlock.h"
+#include "prlog.h"
+#include "prmem.h"
+#include "gcint.h"
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+#define _PR_GC_VMBASE 0x40000000
+
+#if defined(SOLARIS)
+#define _MD_MMAP_FLAGS MAP_SHARED
+#elif defined(RELIANTUNIX)
+#define _MD_MMAP_FLAGS MAP_PRIVATE|MAP_FIXED
+#else
+#define _MD_MMAP_FLAGS MAP_PRIVATE
+#endif
+
+static PRInt32 zero_fd = -1;
+static PRLock *zero_fd_lock = NULL;
+
+void _MD_InitGC(void)
+{
+#ifdef DEBUG
+ /*
+ * Disable using mmap(2) if NSPR_NO_MMAP is set
+ */
+ if (getenv("NSPR_NO_MMAP")) {
+ zero_fd = -2;
+ return;
+ }
+#endif
+ zero_fd = open("/dev/zero",O_RDWR , 0);
+ zero_fd_lock = PR_NewLock();
+}
+
+/* This static variable is used by _MD_GrowGCHeap and _MD_ExtendGCHeap */
+static void *lastaddr = (void*) _PR_GC_VMBASE;
+
+void *_MD_GrowGCHeap(PRUint32 *sizep)
+{
+ void *addr;
+ PRUint32 size;
+
+ size = *sizep;
+
+ PR_Lock(zero_fd_lock);
+ if (zero_fd < 0) {
+ goto mmap_loses;
+ }
+
+ /* Extend the mapping */
+ addr = mmap(lastaddr, size, PROT_READ|PROT_WRITE|PROT_EXEC,
+ _MD_MMAP_FLAGS,
+ zero_fd, 0);
+ if (addr == (void*)-1) {
+ zero_fd = -1;
+ goto mmap_loses;
+ }
+ lastaddr = ((char*)addr + size);
+#ifdef DEBUG
+ PR_LOG(_pr_msgc_lm, PR_LOG_WARNING,
+ ("GC: heap extends from %08x to %08x\n",
+ _PR_GC_VMBASE,
+ _PR_GC_VMBASE + (char*)lastaddr - (char*)_PR_GC_VMBASE));
+#endif
+ PR_Unlock(zero_fd_lock);
+ return addr;
+
+mmap_loses:
+ PR_Unlock(zero_fd_lock);
+ return PR_MALLOC(size);
+}
+
+/* XXX - This is disabled. MAP_FIXED just does not work. */
+#if 0
+PRBool _MD_ExtendGCHeap(char *base, PRInt32 oldSize, PRInt32 newSize) {
+ PRBool rv = PR_FALSE;
+ void* addr;
+ PRInt32 allocSize = newSize - oldSize;
+
+ PR_Lock(zero_fd_lock);
+ addr = mmap(base + oldSize, allocSize, PROT_READ|PROT_WRITE|PROT_EXEC,
+ _MD_MMAP_FLAGS | MAP_FIXED, zero_fd, 0);
+ if (addr == (void*)-1) {
+ goto loser;
+ }
+ if (addr != (void*) (base + oldSize)) {
+ munmap(base + oldSize, allocSize);
+ goto loser;
+ }
+ lastaddr = ((char*)base + newSize);
+ PR_LOG(_pr_msgc_lm, PR_LOG_ALWAYS,
+ ("GC: heap now extends from %p to %p",
+ base, base + newSize));
+ rv = PR_TRUE;
+
+loser:
+ PR_Unlock(zero_fd_lock);
+ return rv;
+}
+#else
+PRBool _MD_ExtendGCHeap(char *base, PRInt32 oldSize, PRInt32 newSize) {
+ return PR_FALSE;
+}
+#endif
+
+void _MD_FreeGCSegment(void *base, PRInt32 len)
+{
+ if (zero_fd < 0) {
+ PR_DELETE(base);
+ } else {
+ (void) munmap(base, len);
+ }
+}
diff --git a/src/libs/xpcom18a4/nsprpub/lib/msgc/src/win16gc.c b/src/libs/xpcom18a4/nsprpub/lib/msgc/src/win16gc.c
new file mode 100644
index 00000000..0af0079b
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/msgc/src/win16gc.c
@@ -0,0 +1,77 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+#if defined(WIN16)
+#include <windows.h>
+#endif
+#include "prtypes.h"
+#include <stdlib.h>
+
+#define MAX_SEGMENT_SIZE (65536l - 4096l)
+
+/************************************************************************/
+/*
+** Machine dependent GC Heap management routines:
+** _MD_GrowGCHeap
+*/
+/************************************************************************/
+
+void _MD_InitGC(void) {}
+
+extern void *
+_MD_GrowGCHeap(PRUint32 *sizep)
+{
+ void *addr;
+
+ if( *sizep > MAX_SEGMENT_SIZE ) {
+ *sizep = MAX_SEGMENT_SIZE;
+ }
+
+ addr = malloc((size_t)*sizep);
+ return addr;
+}
+
+HINSTANCE _pr_hInstance;
+
+int CALLBACK LibMain( HINSTANCE hInst, WORD wDataSeg,
+ WORD cbHeapSize, LPSTR lpszCmdLine )
+{
+ _pr_hInstance = hInst;
+ return TRUE;
+}
+
+
diff --git a/src/libs/xpcom18a4/nsprpub/lib/msgc/src/win32gc.c b/src/libs/xpcom18a4/nsprpub/lib/msgc/src/win32gc.c
new file mode 100644
index 00000000..eec83774
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/msgc/src/win32gc.c
@@ -0,0 +1,129 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * GC related routines
+ *
+ */
+#include <windows.h>
+#include "prlog.h"
+
+extern PRLogModuleInfo* _pr_msgc_lm;
+
+#define GC_VMBASE 0x40000000
+#define GC_VMLIMIT 0x00FFFFFF
+
+/************************************************************************/
+/*
+** Machine dependent GC Heap management routines:
+** _MD_GrowGCHeap
+*/
+/************************************************************************/
+
+void *baseaddr = (void*) GC_VMBASE;
+void *lastaddr = (void*) GC_VMBASE;
+
+void _MD_InitGC() {}
+
+void *_MD_GrowGCHeap(PRUint32 *sizep)
+{
+ void *addr;
+ size_t size;
+
+ /* Reserve a block of memory for the GC */
+ if( lastaddr == baseaddr ) {
+ addr = VirtualAlloc( (void *)GC_VMBASE, GC_VMLIMIT, MEM_RESERVE, PAGE_READWRITE );
+
+ /*
+ ** If the GC_VMBASE address is already mapped, then let the OS choose a
+ ** base address that is available...
+ */
+ if (addr == NULL) {
+ addr = VirtualAlloc( NULL, GC_VMLIMIT, MEM_RESERVE, PAGE_READWRITE );
+
+ baseaddr = lastaddr = addr;
+ if (addr == NULL) {
+ PR_LOG(_pr_msgc_lm, PR_LOG_ALWAYS, ("GC: unable to allocate heap: LastError=%ld",
+ GetLastError()));
+ return 0;
+ }
+ }
+ }
+ size = *sizep;
+
+ /* Extend the mapping */
+ addr = VirtualAlloc( lastaddr, size, MEM_COMMIT, PAGE_READWRITE );
+ if (addr == NULL) {
+ return 0;
+ }
+
+ lastaddr = ((char*)addr + size);
+ PR_LOG(_pr_msgc_lm, PR_LOG_ALWAYS,
+ ("GC: heap extends from %08x to %08x",
+ baseaddr, (long)baseaddr + (char*)lastaddr - (char*)baseaddr));
+
+ return addr;
+}
+
+PRBool _MD_ExtendGCHeap(char *base, PRInt32 oldSize, PRInt32 newSize) {
+ void* addr;
+
+ addr = VirtualAlloc( base + oldSize, newSize - oldSize,
+ MEM_COMMIT, PAGE_READWRITE );
+ if (NULL == addr) {
+ PR_LOG(_pr_msgc_lm, PR_LOG_ALWAYS, ("GC: unable to extend heap: LastError=%ld",
+ GetLastError()));
+ return PR_FALSE;
+ }
+ if (base + oldSize != (char*)addr) {
+ PR_LOG(_pr_msgc_lm, PR_LOG_ALWAYS, ("GC: segment extension returned %x instead of %x",
+ addr, base + oldSize));
+ VirtualFree(addr, newSize - oldSize, MEM_DECOMMIT);
+ return PR_FALSE;
+ }
+ lastaddr = base + newSize;
+ PR_LOG(_pr_msgc_lm, PR_LOG_ALWAYS,
+ ("GC: heap now extends from %p to %p",
+ base, base + newSize));
+ return PR_TRUE;
+}
+
+
+void _MD_FreeGCSegment(void *base, PRInt32 len)
+{
+ (void)VirtualFree(base, 0, MEM_RELEASE);
+}
diff --git a/src/libs/xpcom18a4/nsprpub/lib/msgc/tests/.cvsignore b/src/libs/xpcom18a4/nsprpub/lib/msgc/tests/.cvsignore
new file mode 100644
index 00000000..f3c7a7c5
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/msgc/tests/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/src/libs/xpcom18a4/nsprpub/lib/msgc/tests/Makefile.in b/src/libs/xpcom18a4/nsprpub/lib/msgc/tests/Makefile.in
new file mode 100644
index 00000000..23518e15
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/msgc/tests/Makefile.in
@@ -0,0 +1,315 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# 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 MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#! gmake
+
+MOD_DEPTH = ../../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/config.mk
+
+ifeq ($(OS_TARGET), WIN16)
+OS_CFLAGS = $(OS_EXE_CFLAGS)
+W16STDIO = $(MOD_DEPTH)/pr/src/md/windows/$(OBJDIR)/w16stdio.$(OBJ_SUFFIX)
+endif
+
+ifeq ($(OS_TARGET), OS2)
+OS_CFLAGS = $(OS_EXE_CFLAGS)
+endif
+
+CSRCS = gc1.c thrashgc.c
+
+ifeq (,$(filter-out WINNT OS2,$(OS_ARCH)))
+PROG_SUFFIX = .exe
+else
+PROG_SUFFIX =
+endif
+
+PROGS = $(addprefix $(OBJDIR)/, $(CSRCS:.c=$(PROG_SUFFIX)))
+
+TARGETS = $(PROGS) $(OBJS)
+
+INCLUDES = -I$(dist_includedir)
+
+# Setting the variables LDOPTS and LIBPR. We first initialize
+# them to the default values, then adjust them for some platforms.
+LDOPTS = -L$(dist_libdir)
+NSPR_VERSION = $(MOD_MAJOR_VERSION)
+GC_VERSION = $(MOD_MAJOR_VERSION)
+LIBPR = -lnspr$(NSPR_VERSION)
+LIBPLC = -lplc$(NSPR_VERSION)
+LIBGC = -lmsgc$(GC_VERSION)
+
+ifeq ($(OS_ARCH), WINNT)
+ifeq ($(OS_TARGET), WIN16)
+ LIBPR = $(dist_libdir)/nspr$(NSPR_VERSION).lib
+ LIBPLC = $(dist_libdir)/plc$(NSPR_VERSION).lib
+ LIBGC= $(dist_libdir)/msgc$(GC_VERSION).lib
+else
+ LDOPTS = -NOLOGO -DEBUG -DEBUGTYPE:CV -INCREMENTAL:NO
+ LIBPR = $(dist_libdir)/libnspr$(NSPR_VERSION).$(LIB_SUFFIX)
+ LIBPLC = $(dist_libdir)/libplc$(NSPR_VERSION).$(LIB_SUFFIX)
+ LIBGC= $(dist_libdir)/libmsgc$(GC_VERSION).$(LIB_SUFFIX)
+endif
+endif
+
+ifeq ($(OS_ARCH),OS2)
+ifeq ($(MOZ_OS2_TOOLS),VACPP)
+ LDOPTS = -NOE -DEBUG -nologo -PMTYPE:VIO
+ LIBPR = $(dist_libdir)/nspr$(NSPR_VERSION).lib
+ LIBPLC = $(dist_libdir)/plc$(NSPR_VERSION).lib
+ LIBGC= $(dist_libdir)/msgc$(GC_VERSION).lib
+else
+ LDOPTS += -Zomf -Zlinker /PM:VIO
+endif
+endif
+
+ifneq ($(OS_ARCH), WINNT)
+PWD = $(shell pwd)
+endif
+
+ifeq ($(OS_ARCH), IRIX)
+LDOPTS += -rpath $(PWD)/$(dist_libdir) -rdata_shared
+
+# For 6.x machines, include this flag
+ifeq ($(basename $(OS_RELEASE)),6)
+ifeq ($(USE_N32),1)
+LDOPTS += -n32
+else
+LDOPTS += -32
+endif
+endif
+
+endif
+
+ifeq ($(OS_ARCH), OSF1)
+# I haven't figured out how to pass -rpath to cc on OSF1 V3.2, so
+# we do static linking.
+ifeq ($(OS_RELEASE), V3.2)
+ LIBPR = $(dist_libdir)/libnspr$(NSPR_VERSION).a
+ LIBPLC = $(dist_libdir)/libplc$(NSPR_VERSION).a
+ LIBGC = $(dist_libdir)/libmsgc$(GC_VERSION).a
+ EXTRA_LIBS = -lc_r
+else
+ LDOPTS += -rpath $(PWD)/$(dist_libdir)
+endif
+endif
+
+ifeq ($(OS_ARCH), HP-UX)
+LDOPTS += -z -Wl,+s,+b,$(PWD)/$(dist_libdir)
+endif
+
+# AIX
+ifeq ($(OS_ARCH),AIX)
+LDOPTS += -blibpath:$(PWD)/$(dist_libdir):/usr/lib:/lib
+ifeq ($(OS_ARCH)$(OS_RELEASE),AIX4.1)
+LIBPR = -lnspr$(NSPR_VERSION)_shr
+LIBPLC = -lplc$(NSPR_VERSION)_shr
+LIBGC = -lmsgc$(GC_VERSION)_shr
+else
+LDOPTS += -brtl
+EXTRA_LIBS = -ldl
+endif
+endif
+
+# Solaris
+ifeq ($(OS_ARCH), SunOS)
+ifneq ($(OS_RELEASE), 4.1.3_U1)
+ifdef NS_USE_GCC
+LDOPTS += -Xlinker -R -Xlinker $(PWD)/$(dist_libdir)
+else
+LDOPTS += -R $(PWD)/$(dist_libdir)
+endif
+endif
+
+ifneq ($(LOCAL_THREADS_ONLY),1)
+# SunOS 5.4 and 5.5 need to link with -lthread or -lpthread,
+# even though we already linked with these system libraries
+# when we built libnspr.so.
+ifeq ($(OS_RELEASE), 5.4)
+EXTRA_LIBS = -lthread
+endif
+
+ifeq ($(OS_RELEASE), 5.5)
+ifdef USE_PTHREADS
+EXTRA_LIBS = -lpthread
+else
+EXTRA_LIBS = -lthread
+endif
+endif
+endif # LOCAL_THREADS_ONLY
+endif # SunOS
+
+ifeq ($(OS_ARCH),NEC)
+EXTRA_LIBS = $(OS_LIBS)
+# This hardcodes in the executable programs the directory to find
+# libnspr.so etc. at program startup. Equivalent to the -R or -rpath
+# option for ld on other platforms.
+export LD_RUN_PATH = $(PWD)/$(dist_libdir)
+endif
+
+ifeq ($(OS_ARCH), NCR)
+# XXX: We see some strange problems when we link with libnspr.so.
+# So for now we use static libraries on NCR. The shared library
+# stuff below is commented out.
+LIBPR = $(dist_libdir)/libnspr$(NSPR_VERSION).a
+LIBPLC = $(dist_libdir)/libplc$(NSPR_VERSION).a
+LIBGC = $(dist_libdir)/libmsgc$(GC_VERSION).a
+EXTRA_LIBS = -lsocket -lnsl -ldl
+
+# NCR needs to link against -lsocket -lnsl (and -lc, which is linked
+# implicitly by $(CC)) again even though we already linked with these
+# system libraries when we built libnspr.so.
+#EXTRA_LIBS = -lsocket -lnsl
+# This hardcodes in the executable programs the directory to find
+# libnspr.so etc. at program startup. Equivalent to the -R or -rpath
+# option for ld on other platforms.
+#export LD_RUN_PATH = $(PWD)/$(dist_libdir)
+endif
+
+ifeq ($(OS_ARCH), Linux)
+ifeq ($(OS_RELEASE), 1.2)
+EXTRA_LIBS = -ldl
+endif
+endif
+
+ifeq ($(OS_ARCH), SCOOS)
+# SCO Unix needs to link against -lsocket again even though we
+# already linked with these system libraries when we built libnspr.so.
+EXTRA_LIBS = -lsocket
+# This hardcodes in the executable programs the directory to find
+# libnspr.so etc. at program startup. Equivalent to the -R or -rpath
+# option for ld on other platforms.
+export LD_RUN_PATH = $(PWD)/$(dist_libdir)
+endif
+
+ifeq ($(OS_ARCH),SINIX)
+EXTRA_LIBS = -lsocket -lnsl -lresolv -ldl
+# This hardcodes in the executable programs the directory to find
+# libnspr.so etc. at program startup. Equivalent to the -R or -rpath
+# option for ld on other platforms.
+export LD_RUN_PATH = $(PWD)/$(dist_libdir)
+endif
+
+ifeq ($(OS_ARCH), UNIXWARE)
+export LD_RUN_PATH = $(PWD)/$(dist_libdir)
+endif
+
+ifeq ($(OS_ARCH),BSD_OS)
+EXTRA_LIBS = -ldl
+endif
+
+ifeq ($(OS_ARCH),DGUX)
+EXTRA_LIBS = -lsocket -lnsl -ldl
+endif
+
+#####################################################
+#
+# The rules
+#
+#####################################################
+
+include $(topsrcdir)/config/rules.mk
+
+AIX_PRE_4_2 = 0
+ifeq ($(OS_ARCH),AIX)
+ifneq ($(OS_RELEASE),4.2)
+ifneq ($(USE_PTHREADS), 1)
+#AIX_PRE_4_2 = 1
+endif
+endif
+endif
+
+ifeq ($(AIX_PRE_4_2),1)
+
+# AIX releases prior to 4.2 need a special two-step linking hack
+# in order to both override the system select() and be able to
+# get at the original system select().
+#
+# We use a pattern rule in ns/nspr20/config/rules.mk to generate
+# the .$(OBJ_SUFFIX) file from the .c source file, then do the
+# two-step linking hack below.
+
+$(OBJDIR)/%: $(OBJDIR)/%.$(OBJ_SUFFIX)
+ @$(MAKE_OBJDIR)
+ rm -f $@ $(AIX_TMP)
+ $(CC) $(AIX_LINK_OPTS) -o $(AIX_TMP) $< $(dist_libdir)/libnspr$(NSPR_VERSION).a
+ $(CC) -o $@ $(AIX_TMP) $(AIX_WRAP)
+ rm -f $(AIX_TMP)
+
+else
+
+# All platforms that are not AIX pre-4.2.
+
+$(OBJDIR)/%$(PROG_SUFFIX): $(OBJDIR)/%.$(OBJ_SUFFIX)
+ @$(MAKE_OBJDIR)
+ifeq ($(OS_ARCH), WINNT)
+ifeq ($(OS_TARGET),WIN16)
+ echo system windows >w16link
+ echo name $@ >>w16link
+ echo option map >>w16link
+# echo option CASEEXACT >>w16link
+ echo option stack=16K >>w16link
+ echo debug $(DEBUGTYPE) all >>w16link
+ echo file >>w16link
+ echo $< , >>w16link
+ echo $(W16STDIO) >>w16link
+ echo library >>w16link
+ echo $(LIBPR), >>w16link
+ echo $(LIBPLC), >>w16link
+ echo $(LIBGC), >>w16link
+ echo winsock.lib >>w16link
+ wlink @w16link.
+else
+ link $(LDOPTS) $< $(LIBGC) $(LIBPLC) $(LIBPR) wsock32.lib -out:$@
+else
+ifeq ($(OS_ARCH),OS2)
+ $(LINK) $(LDOPTS) $< $(LIBGC) $(LIBPLC) $(LIBPR) $(OS_LIBS) $(EXTRA_LIBS) -o $@
+else
+ $(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBGC) $(LIBPLC) $(LIBPR) $(EXTRA_LIBS) -o $@
+endif
+endif
+endif
+
+export:: $(TARGETS)
+export:: install
+clean::
+ rm -f $(TARGETS)
diff --git a/src/libs/xpcom18a4/nsprpub/lib/msgc/tests/gc1.c b/src/libs/xpcom18a4/nsprpub/lib/msgc/tests/gc1.c
new file mode 100644
index 00000000..d6846235
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/msgc/tests/gc1.c
@@ -0,0 +1,257 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "prgc.h"
+#include "prinit.h"
+#include "prmon.h"
+#include "prinrval.h"
+#ifndef XP_MAC
+#include "private/pprthred.h"
+#else
+#include "pprthred.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef XP_MAC
+#include "prlog.h"
+#define printf PR_LogPrint
+extern void SetupMacPrintfLog(char *logFile);
+#endif
+
+static PRMonitor *mon;
+static PRInt32 threads, waiting, iterations;
+static PRInt32 scanCount, finalizeCount, freeCount;
+
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+
+typedef struct Array {
+ PRUintn size;
+ void *body[1];
+} Array;
+
+int arrayTypeIndex;
+
+static void PR_CALLBACK ScanArray(void *a)
+{
+/* printf ("In ScanArray a = %X size = %d \n", a, a->size); */
+ scanCount++;
+}
+
+static void PR_CALLBACK FinalizeArray(void *a)
+{
+/* printf ("In FinalizeArray a = %X size = %d \n", a, a->size); */
+ finalizeCount++;
+}
+
+static void PR_CALLBACK FreeArray(void *a)
+{
+/* printf ("In FreeArray\n"); */
+ freeCount++;
+}
+
+static Array *NewArray(PRUintn size)
+{
+ Array *a;
+
+ a = (Array *)PR_AllocMemory(sizeof(Array) + size*sizeof(void*) - 1*sizeof(void*),
+ arrayTypeIndex, PR_ALLOC_CLEAN);
+
+/* printf ("In NewArray a = %X \n", a); */
+
+ if (a)
+ a->size = size;
+ return a;
+}
+
+GCType arrayType = {
+ ScanArray,
+ FinalizeArray,
+ 0,
+ 0,
+ FreeArray,
+ 0
+};
+
+static void Initialize(void)
+{
+ PR_InitGC(0, 0, 0, PR_GLOBAL_THREAD);
+ arrayTypeIndex = PR_RegisterType(&arrayType);
+}
+
+static void PR_CALLBACK AllocateLikeMad(void *arg)
+{
+ Array *prev;
+ PRInt32 i;
+ PRInt32 count;
+
+ count = (PRInt32)arg;
+ prev = 0;
+ for (i = 0; i < count; i++) {
+ Array *leak = NewArray(i & 511);
+ if ((i & 1023) == 0) {
+ prev = 0; /* forget */
+ } else {
+ if (i & 1) {
+ prev = leak; /* remember */
+ }
+ }
+ }
+ PR_EnterMonitor(mon);
+ waiting++;
+ PR_Notify(mon);
+ PR_ExitMonitor(mon);
+}
+
+int main(int argc, char **argv)
+{
+ PRIntervalTime start, stop, usec;
+ double d;
+ PRIntn i, totalIterations;
+ /* The command line argument: -d is used to determine if the test is being run
+ in debug mode. The regress tool requires only one line output:PASS or FAIL.
+ All of the printfs associated with this test has been handled with a if (debug_mode)
+ test.
+ Usage: test_name -d
+ */
+ PLOptStatus os;
+ PLOptState *opt = PL_CreateOptState(argc, argv, "dt:c:");
+
+ threads = 10;
+ iterations = 100;
+
+ while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+ {
+ if (PL_OPT_BAD == os) {
+ fprintf(stderr, "Invalid command-line option\n");
+ exit(1);
+ }
+ switch (opt->option)
+ {
+ case 'd': /* debug mode */
+ debug_mode = 1;
+ break;
+ case 't': /* number of threads */
+ threads = atoi(opt->value);
+ break;
+ case 'c': /* iteration count */
+ iterations = atoi(opt->value);
+ break;
+ default:
+ break;
+ }
+ }
+ PL_DestroyOptState(opt);
+
+ fprintf(stderr, "t is %ld, i is %ld\n", (long) threads, (long) iterations);
+ /* main test */
+
+ PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 5);
+ PR_STDIO_INIT();
+ Initialize();
+
+#ifdef XP_MAC
+ SetupMacPrintfLog("gc1.log");
+ debug_mode = 1;
+#endif
+
+ /* Spin all of the allocator threads and then wait for them to exit */
+ start = PR_IntervalNow();
+ mon = PR_NewMonitor();
+ PR_EnterMonitor(mon);
+ waiting = 0;
+ for (i = 0; i < threads; i++) {
+ (void) PR_CreateThreadGCAble(PR_USER_THREAD,
+ AllocateLikeMad, (void*)iterations,
+ PR_PRIORITY_NORMAL,
+ PR_LOCAL_THREAD,
+ PR_UNJOINABLE_THREAD,
+ 0);
+ }
+ while (waiting != threads) {
+ PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT);
+ }
+ PR_ExitMonitor(mon);
+
+ PR_GC();
+ PR_ForceFinalize();
+
+ totalIterations = iterations * threads;
+/*
+ if (scanCount != totalIterations)
+ printf ("scanCount discrepancy scanCount = %d totalIterations = %d \n",
+ scanCount, totalIterations);
+ if (freeCount != totalIterations)
+ printf ("freeCount discrepancy freeCount = %d totalIterations = %d \n",
+ freeCount, totalIterations);
+ if ((finalizeCount != totalIterations) && (finalizeCount != (totalIterations-1)))
+ printf ("finalizeCount discrepancy finalizeCount = %d totalIterations = %d \n",
+ finalizeCount,totalIterations);
+*/
+
+ stop = PR_IntervalNow();
+
+ usec = stop = stop - start;
+ d = (double)usec;
+
+ if (debug_mode) printf("%40s: %6.2f usec\n", "GC allocation", d / (iterations * threads));
+ else {
+ if (d == 0.0) failed_already = PR_TRUE;
+
+ }
+
+ PR_Cleanup();
+ if(failed_already)
+ {
+ printf("FAIL\n");
+ return 1;
+ }
+ else
+ {
+ printf("PASS\n");
+ return 0;
+ }
+}
diff --git a/src/libs/xpcom18a4/nsprpub/lib/msgc/tests/thrashgc.c b/src/libs/xpcom18a4/nsprpub/lib/msgc/tests/thrashgc.c
new file mode 100644
index 00000000..9d49ec19
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/msgc/tests/thrashgc.c
@@ -0,0 +1,274 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/***********************************************************************
+** Name: thrashgc
+**
+** Description: test garbace collection functions.
+**
+** Modification History:
+** 19-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
+** The debug mode will print all of the printfs associated with this test.
+** The regress mode will be the default mode. Since the regress tool limits
+** the output to a one line status:PASS or FAIL,all of the printf statements
+** have been handled with an if (debug_mode) statement.
+** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
+** recognize the return code from tha main program.
+***********************************************************************/
+/***********************************************************************
+** Includes
+***********************************************************************/
+#include "prthread.h"
+#include "prgc.h"
+#include "prprf.h"
+#include "prinrval.h"
+#include "prlock.h"
+#include "prinit.h"
+#include "prcvar.h"
+
+#ifndef XP_MAC
+#include "private/pprthred.h"
+#else
+#include "pprthred.h"
+#endif
+
+#include <stdio.h>
+#include <memory.h>
+#include <string.h>
+
+
+#ifdef XP_MAC
+#include "prlog.h"
+#define printf PR_LogPrint
+extern void SetupMacPrintfLog(char *logFile);
+#endif
+
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+static char* progname;
+static PRInt32 loops = 1000;
+static int tix1, tix2, tix3;
+static GCInfo* gcInfo;
+static PRLock* stderrLock;
+
+typedef struct Type1 Type1;
+typedef struct Type2 Type2;
+
+struct Type1 {
+ Type2* atwo;
+ Type1* next;
+};
+
+struct Type2 {
+ void* buf;
+};
+
+static void PR_CALLBACK ScanType1(void *obj) {
+ gcInfo->livePointer(((Type1 *)obj)->atwo);
+ gcInfo->livePointer(((Type1 *)obj)->next);
+}
+
+static void PR_CALLBACK ScanType2(void *obj) {
+ gcInfo->livePointer(((Type2 *)obj)->buf);
+}
+
+static GCType type1 = {
+ ScanType1
+};
+
+static GCType type2 = {
+ ScanType2
+/* (void (*)(void*)) ScanType2 */
+};
+
+static GCType type3 = {
+ 0
+};
+
+Type1* NewType1(void) {
+ Type1* p = (Type1*) PR_AllocMemory(sizeof(Type1), tix1, PR_ALLOC_DOUBLE);
+ PR_ASSERT(p != NULL);
+ return p;
+}
+
+Type2* NewType2(void) {
+ Type2* p = (Type2*) PR_AllocMemory(sizeof(Type2), tix2, PR_ALLOC_DOUBLE);
+ PR_ASSERT(p != NULL);
+ return p;
+}
+
+void* NewBuffer(PRInt32 size) {
+ void* p = PR_AllocMemory(size, tix3, PR_ALLOC_DOUBLE);
+ PR_ASSERT(p != NULL);
+ return p;
+}
+
+/* Allocate alot of garbage */
+static void PR_CALLBACK AllocStuff(void *unused) {
+ PRInt32 i;
+ void* danglingRefs[50];
+ PRIntervalTime start, end;
+ char msg[100];
+
+ start = PR_IntervalNow();
+ for (i = 0; i < loops; i++) {
+ void* p;
+ if (i & 1) {
+ Type1* t1 = NewType1();
+ t1->atwo = NewType2();
+ t1->next = NewType1();
+ t1->atwo->buf = NewBuffer(100);
+ p = t1;
+ } else {
+ Type2* t2 = NewType2();
+ t2->buf = NewBuffer(i & 16383);
+ p = t2;
+ }
+ if ((i % 10) == 0) {
+ memmove(&danglingRefs[0], &danglingRefs[1], 49*sizeof(void*));
+ danglingRefs[49] = p;
+ }
+ }
+ end = PR_IntervalNow();
+ if (debug_mode) PR_snprintf(msg, sizeof(msg), "Thread %p: %ld allocations took %ld ms",
+ PR_GetCurrentThread(), loops,
+ PR_IntervalToMilliseconds((PRIntervalTime) (end - start)));
+ PR_Lock(stderrLock);
+#ifndef XP_MAC
+ fprintf(stderr, "%s\n", msg);
+#else
+ if (debug_mode) printf("%s\n", msg);
+#endif
+ PR_Unlock(stderrLock);
+ }
+
+static void usage(char *progname) {
+#ifndef XP_MAC
+ fprintf(stderr, "Usage: %s [-t threads] [-l loops]\n", progname);
+#else
+ printf("Usage: %s [-t threads] [-l loops]\n", progname);
+#endif
+ exit(-1);
+}
+
+static int realMain(int argc, char **argv, char *notused) {
+ int i;
+ int threads = 0;
+
+#ifndef XP_MAC
+ progname = strrchr(argv[0], '/');
+ if (progname == 0) progname = argv[0];
+ for (i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "-t") == 0) {
+ if (i == argc - 1) {
+ usage(progname);
+ }
+ threads = atoi(argv[++i]);
+ if (threads < 0) threads = 0;
+ if (threads > 10000) threads = 10000;
+ continue;
+ }
+ if (strcmp(argv[i], "-l") == 0) {
+ if (i == argc - 1) {
+ usage(progname);
+ }
+ loops = atoi(argv[++i]);
+ continue;
+ }
+ usage(progname);
+ }
+#else
+ threads = 50;
+#endif
+
+ for (i = 0; i < threads; i++) {
+ PRThread* thread;
+
+ /* XXXXX */
+ thread = PR_CreateThreadGCAble(PR_USER_THREAD, /* thread type */
+ AllocStuff, /* start function */
+ NULL, /* arg */
+ PR_PRIORITY_NORMAL, /* priority */
+ PR_LOCAL_THREAD, /* thread scope */
+ PR_UNJOINABLE_THREAD, /* thread state */
+ 0); /* stack size */
+ if (thread == 0) {
+#ifndef XP_MAC
+ fprintf(stderr, "%s: no more threads (only %d were created)\n",
+ progname, i);
+#else
+ printf("%s: no more threads (only %d were created)\n",
+ progname, i);
+#endif
+ break;
+ }
+ }
+ AllocStuff(NULL);
+ return 0;
+}
+
+static int padMain(int argc, char **argv) {
+ char pad[512];
+ return realMain(argc, argv, pad);
+}
+
+int main(int argc, char **argv) {
+ int rv;
+
+ debug_mode = 1;
+
+ PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+ PR_SetThreadGCAble();
+
+#ifdef XP_MAC
+ SetupMacPrintfLog("thrashgc.log");
+ debug_mode = 1;
+#endif
+
+ PR_InitGC(0, 0, 0, PR_GLOBAL_THREAD);
+ PR_STDIO_INIT();
+ stderrLock = PR_NewLock();
+ tix1 = PR_RegisterType(&type1);
+ tix2 = PR_RegisterType(&type2);
+ tix3 = PR_RegisterType(&type3);
+ gcInfo = PR_GetGCInfo();
+ rv = padMain(argc, argv);
+ printf("PASS\n");
+ PR_Cleanup();
+ return rv;
+}
diff --git a/src/libs/xpcom18a4/nsprpub/lib/prstreams/.cvsignore b/src/libs/xpcom18a4/nsprpub/lib/prstreams/.cvsignore
new file mode 100644
index 00000000..f3c7a7c5
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/prstreams/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/src/libs/xpcom18a4/nsprpub/lib/prstreams/Makefile.in b/src/libs/xpcom18a4/nsprpub/lib/prstreams/Makefile.in
new file mode 100644
index 00000000..5c1311b2
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/prstreams/Makefile.in
@@ -0,0 +1,207 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# 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 MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#! gmake
+
+MOD_DEPTH = ../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/config.mk
+
+# Disable optimization of the nspr on SunOS4.1.3
+ifeq ($(OS_ARCH),SunOS)
+ ifeq ($(OS_RELEASE),4.1.3_U1)
+ OPTIMIZER =
+ else
+ # The C++ compiler in Workshop 5.0 uses standard
+ # iostreams as default. -library=iostream will
+ # allow Workshop 5.0 to work with classic iostreams.
+ ifndef NS_USE_GCC
+ CCC_VERSION := $(shell $(CCC) -V 2>&1)
+ ifneq (,$(findstring 5.0,$(CCC_VERSION)))
+ CCC_ONLY_FLAGS += -library=iostream
+ endif
+ endif
+ endif
+endif
+
+ifeq ($(OS_ARCH), IRIX)
+ ifneq ($(OS_RELEASE),5.3)
+ CCC_ONLY_FLAGS += -exceptions
+ endif
+endif
+
+ifeq ($(OS_ARCH), BeOS)
+ CFLAGS += -frtti -fexceptions
+endif
+
+INCLUDES = -I$(dist_includedir)
+
+HEADERS = $(wildcard $(srcdir)/*.h)
+
+CSRCS = \
+ plvrsion.c \
+ $(NULL)
+
+CXXSRCS = \
+ prstrms.cpp \
+ $(NULL)
+
+OBJS = $(addprefix $(OBJDIR)/,$(CSRCS:.c=.$(OBJ_SUFFIX)) $(CXXSRCS:.cpp=.$(OBJ_SUFFIX)))
+
+ifeq ($(OS_ARCH), WINNT)
+ DLLBASE=/BASE:0x30000000
+ RES=$(OBJDIR)/prstrms.res
+ RESNAME=prstrms.rc
+ OS_LIBS = user32.lib
+else
+ ifeq ($(OS_ARCH),OS2)
+ ifneq ($(MOZ_OS2_TOOLS),VACPP)
+ OS_LIBS = -lstdcpp
+ endif
+ else
+ ifeq ($(OS_ARCH), AIX)
+ ifeq ($(OS_RELEASE), 4.1)
+ ifeq ($(CLASSIC_NSPR),1)
+ OS_LIBS += -lC -lc
+ else
+ OS_LIBS += -lC_r -lc_r
+ endif
+ else
+ # makeC++SharedLib(_r) is in either /usr/lpp/xlC/bin
+ # or /usr/ibmcxx/bin.
+ ifeq ($(CLASSIC_NSPR),1)
+ MKSHLIB = makeC++SharedLib -p 0
+ else
+ MKSHLIB = makeC++SharedLib_r -p 0
+ endif
+ OS_LIBS += -ldl
+ endif
+ endif
+ endif
+endif
+
+ifeq ($(OS_ARCH),BeOS)
+ OS_LIBS = -lstdc++.r4
+endif
+
+ifeq ($(OS_ARCH), UNIXWARE)
+ OS_LIBS += -lC
+endif
+
+EXTRA_LIBS = $(LIBNSPR)
+
+# On NCR and SCOOS, we can't link with extra libraries when
+# we build a shared library. If we do so, the linker doesn't
+# complain, but we would run into weird problems at run-time.
+# Therefore on these platforms, we link just the object files.
+ifeq ($(OS_ARCH),NCR)
+ EXTRA_LIBS =
+endif
+ifeq ($(OS_ARCH),SCOOS)
+ EXTRA_LIBS =
+endif
+
+ifdef RESOLVE_LINK_SYMBOLS
+EXTRA_LIBS += $(OS_LIBS)
+endif
+
+LIBRARY_NAME = prstrms
+LIBRARY_VERSION = $(MOD_MAJOR_VERSION)
+
+RELEASE_HEADERS = $(HEADERS)
+RELEASE_HEADERS_DEST = $(RELEASE_INCLUDE_DIR)
+RELEASE_LIBS = $(TARGETS)
+
+include $(topsrcdir)/config/rules.mk
+
+#
+# Version information generation (begin)
+#
+ECHO = echo
+TINC = $(OBJDIR)/_pl_bld.h
+PROD = $(notdir $(SHARED_LIBRARY))
+NOW = $(MOD_DEPTH)/config/$(OBJDIR)/now
+SH_DATE = $(shell date "+%Y-%m-%d %T")
+SH_NOW = $(shell $(NOW))
+
+ifeq ($(OS_ARCH), WINNT)
+ SUF = i64
+else
+ SUF = LL
+endif
+
+$(TINC):
+ @$(MAKE_OBJDIR)
+ @$(ECHO) '#define _BUILD_STRING "$(SH_DATE)"' > $(TINC)
+ @if test ! -z "$(SH_NOW)"; then \
+ $(ECHO) '#define _BUILD_TIME $(SH_NOW)$(SUF)' >> $(TINC); \
+ else \
+ true; \
+ fi
+ @$(ECHO) '#define _PRODUCTION "$(PROD)"' >> $(TINC)
+
+
+$(OBJDIR)/plvrsion.$(OBJ_SUFFIX): plvrsion.c $(TINC)
+ifeq ($(OS_ARCH), WINNT)
+ $(CC) -o $@ -c $(CFLAGS) -I$(OBJDIR) $<
+else
+ifeq ($(MOZ_OS2_TOOLS), VACPP)
+ $(CC) -Fo$@ -c $(CFLAGS) -I$(OBJDIR) $<
+else
+ $(CC) -o $@ -c $(CFLAGS) -I$(OBJDIR) $<
+endif
+endif
+#
+# Version information generation (end)
+#
+
+export:: $(TARGETS) $(HEADERS)
+ $(INSTALL) -m 444 $(HEADERS) $(dist_includedir)
+ $(INSTALL) -m 444 $(TARGETS) $(dist_libdir)
+ifeq ($(OS_ARCH),OS2)
+ $(INSTALL) -m 444 $(TARGETS) $(dist_bindir)
+endif
+ifeq ($(OS_ARCH),HP-UX)
+ifdef SHARED_LIBRARY
+ $(INSTALL) -m 755 $(SHARED_LIBRARY) $(dist_libdir)
+endif
+endif
diff --git a/src/libs/xpcom18a4/nsprpub/lib/prstreams/plvrsion.c b/src/libs/xpcom18a4/nsprpub/lib/prstreams/plvrsion.c
new file mode 100644
index 00000000..87b62e7a
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/prstreams/plvrsion.c
@@ -0,0 +1,125 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "prinit.h"
+#include "prvrsion.h"
+
+/************************************************************************/
+/**************************IDENTITY AND VERSIONING***********************/
+/************************************************************************/
+#include "_pl_bld.h"
+#if !defined(_BUILD_TIME)
+#ifdef HAVE_LONG_LONG
+#define _BUILD_TIME 0
+#else
+#define _BUILD_TIME {0, 0}
+#endif
+#endif
+#if !defined(_BUILD_STRING)
+#define _BUILD_STRING ""
+#endif
+#if !defined(_PRODUCTION)
+#define _PRODUCTION ""
+#endif
+#if defined(DEBUG)
+#define _DEBUG_STRING " (debug)"
+#else
+#define _DEBUG_STRING ""
+#endif
+
+/*
+ * A trick to expand the PR_VMAJOR macro before concatenation.
+ */
+#define CONCAT(x, y) x ## y
+#define CONCAT2(x, y) CONCAT(x, y)
+#define VERSION_DESC_NAME CONCAT2(prVersionDescription_libprstrms, PR_VMAJOR)
+
+PRVersionDescription VERSION_DESC_NAME =
+{
+ /* version */ 2, /* this is the only one supported */
+ /* buildTime */ _BUILD_TIME, /* usecs since midnight 1/1/1970 GMT */
+ /* buildTimeString */ _BUILD_STRING, /* ditto, but human readable */
+ /* vMajor */ PR_VMAJOR, /* NSPR's version number */
+ /* vMinor */ PR_VMINOR, /* and minor version */
+ /* vPatch */ PR_VPATCH, /* and patch */
+ /* beta */ PR_BETA, /* beta build boolean */
+#if defined(DEBUG)
+ /* debug */ PR_TRUE, /* a debug build */
+#else
+ /* debug */ PR_FALSE, /* an optomized build */
+#endif
+ /* special */ PR_FALSE, /* they're all special, but ... */
+ /* filename */ _PRODUCTION, /* the produced library name */
+ /* description */ "Portable runtime", /* what we are */
+ /* security */ "N/A", /* not applicable here */
+ /* copywrite */ "Copyright (c) 1998 Netscape Communications Corporation. All Rights Reserved",
+ /* comment */ "http://www.mozilla.org/MPL/",
+ /* specialString */ ""
+};
+
+#ifdef XP_UNIX
+
+/*
+ * Version information for the 'ident' and 'what commands
+ *
+ * NOTE: the first component of the concatenated rcsid string
+ * must not end in a '$' to prevent rcs keyword substitution.
+ */
+static char rcsid[] = "$Header: NSPR " PR_VERSION _DEBUG_STRING
+ " " _BUILD_STRING " $";
+static char sccsid[] = "@(#)NSPR " PR_VERSION _DEBUG_STRING
+ " " _BUILD_STRING;
+
+#endif /* XP_UNIX */
+
+PR_IMPLEMENT(const PRVersionDescription*) libVersionPoint()
+{
+#ifdef XP_UNIX
+ /*
+ * Add dummy references to rcsid and sccsid to prevent them
+ * from being optimized away as unused variables.
+ */
+ const char *dummy;
+
+ dummy = rcsid;
+ dummy = sccsid;
+#endif
+ return &VERSION_DESC_NAME;
+} /* versionEntryPointType */
+
+/* plvrsion.c */
+
diff --git a/src/libs/xpcom18a4/nsprpub/lib/prstreams/prstrms.cpp b/src/libs/xpcom18a4/nsprpub/lib/prstreams/prstrms.cpp
new file mode 100644
index 00000000..17b280ea
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/prstreams/prstrms.cpp
@@ -0,0 +1,550 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * Robin J. Maxwell 11-22-96
+ */
+
+#include "prstrms.h"
+#include <string.h> // memmove
+
+//
+// Definition of macros _PRSTR_BP, _PRSTR_DELBUF, and _PRSTR_DELBUF_C.
+//
+// _PRSTR_BP is the protected member of class ios that is returned
+// by the public method rdbuf().
+//
+// _PRSTR_DELBUF is the method or data member of class ios, if available,
+// with which we can ensure that the ios destructor does not delete
+// the associated streambuf. If such a method or data member does not
+// exist, define _PRSTR_DELBUF to be empty.
+//
+// _PRSTR_DELBUF_C is just _PRSTR_DELBUF qualified by a base class.
+//
+
+#if defined(__GNUC__)
+#define _PRSTR_BP _strbuf
+#define _PRSTR_DELBUF(x) /* as nothing */
+#define _PRSTR_DELBUF_C(c, x) /* as nothing */
+#elif defined(WIN32)
+#define _PRSTR_BP bp
+#define _PRSTR_DELBUF(x) delbuf(x)
+#define _PRSTR_DELBUF_C(c, x) c::_PRSTR_DELBUF(x)
+#elif defined(VMS)
+#undef _PRSTR_BP
+#define _PRSTR_DELBUF(x) /* as nothing */
+#define _PRSTR_DELBUF_C(c, x) /* as nothing */
+#elif defined(OSF1)
+#define _PRSTR_BP m_psb
+#define _PRSTR_DELBUF(x) /* as nothing */
+#define _PRSTR_DELBUF_C(c, x) /* as nothing */
+#elif defined(QNX)
+#define PRFSTREAMS_BROKEN
+#else
+#define _PRSTR_BP bp
+// Unix compilers don't believe in encapsulation
+// At least on Solaris this is also ignored
+#define _PRSTR_DELBUF(x) delbuf = x
+#define _PRSTR_DELBUF_C(c, x) c::_PRSTR_DELBUF(x)
+#endif
+
+const PRIntn STRM_BUFSIZ = 8192;
+
+#if !defined (PRFSTREAMS_BROKEN)
+
+PRfilebuf::PRfilebuf():
+_fd(0),
+_opened(PR_FALSE),
+_allocated(PR_FALSE)
+{
+}
+
+PRfilebuf::PRfilebuf(PRFileDesc *fd):
+streambuf(),
+_fd(fd),
+_opened(PR_FALSE),
+_allocated(PR_FALSE)
+{
+}
+
+PRfilebuf::PRfilebuf(PRFileDesc *fd, char * buffptr, int bufflen):
+_fd(fd),
+_opened(PR_FALSE),
+_allocated(PR_FALSE)
+{
+ PRfilebuf::setbuf(buffptr, bufflen);
+}
+
+PRfilebuf::~PRfilebuf()
+{
+ if (_opened){
+ close();
+ }else
+ sync();
+ if (_allocated)
+ delete base();
+}
+
+PRfilebuf*
+PRfilebuf::open(const char *name, int mode, int flags)
+{
+ if (_fd != 0)
+ return 0; // error if already open
+ PRIntn PRmode = 0;
+ // translate mode argument
+ if (!(mode & ios::nocreate))
+ PRmode |= PR_CREATE_FILE;
+ //if (mode & ios::noreplace)
+ // PRmode |= O_EXCL;
+ if (mode & ios::app){
+ mode |= ios::out;
+ PRmode |= PR_APPEND;
+ }
+ if (mode & ios::trunc){
+ mode |= ios::out; // IMPLIED
+ PRmode |= PR_TRUNCATE;
+ }
+ if (mode & ios::out){
+ if (mode & ios::in)
+ PRmode |= PR_RDWR;
+ else
+ PRmode |= PR_WRONLY;
+ if (!(mode & (ios::in|ios::app|ios::ate|ios::noreplace))){
+ mode |= ios::trunc; // IMPLIED
+ PRmode |= PR_TRUNCATE;
+ }
+ }else if (mode & ios::in)
+ PRmode |= PR_RDONLY;
+ else
+ return 0; // error if not ios:in or ios::out
+
+
+ //
+ // The usual portable across unix crap...
+ // NT gets a hokey piece of junk layer that prevents
+ // access to the API.
+#ifdef WIN32
+ _fd = PR_Open(name, PRmode, PRmode);
+#else
+ _fd = PR_Open(name, PRmode, flags);
+#endif
+ if (_fd == 0)
+ return 0;
+ _opened = PR_TRUE;
+ if ((!unbuffered()) && (!ebuf())){
+ char * sbuf = new char[STRM_BUFSIZ];
+ if (!sbuf)
+ unbuffered(1);
+ else{
+ _allocated = PR_TRUE;
+ streambuf::setb(sbuf,sbuf+STRM_BUFSIZ,0);
+ }
+ }
+ if (mode & ios::ate){
+ if (seekoff(0,ios::end,mode)==EOF){
+ close();
+ return 0;
+ }
+ }
+ return this;
+}
+
+PRfilebuf*
+PRfilebuf::attach(PRFileDesc *fd)
+{
+ _opened = PR_FALSE;
+ _fd = fd;
+ return this;
+}
+
+int
+PRfilebuf::overflow(int c)
+{
+ if (allocate()==EOF) // make sure there is a reserve area
+ return EOF;
+ if (PRfilebuf::sync()==EOF) // sync before new buffer created below
+ return EOF;
+
+ if (!unbuffered())
+ setp(base(),ebuf());
+
+ if (c!=EOF){
+ if ((!unbuffered()) && (pptr() < epptr())) // guard against recursion
+ sputc(c);
+ else{
+ if (PR_Write(_fd, &c, 1)!=1)
+ return(EOF);
+ }
+ }
+ return(1); // return something other than EOF if successful
+}
+
+int
+PRfilebuf::underflow()
+{
+ int count;
+ unsigned char tbuf;
+
+ if (in_avail())
+ return (int)(unsigned char) *gptr();
+
+ if (allocate()==EOF) // make sure there is a reserve area
+ return EOF;
+ if (PRfilebuf::sync()==EOF)
+ return EOF;
+
+ if (unbuffered())
+ {
+ if (PR_Read(_fd,(void *)&tbuf,1)<=0)
+ return EOF;
+ return (int)tbuf;
+ }
+
+ if ((count=PR_Read(_fd,(void *)base(),blen())) <= 0)
+ return EOF; // reached EOF
+ setg(base(),base(),base()+count);
+ return (int)(unsigned char) *gptr();
+}
+
+streambuf*
+PRfilebuf::setbuf(char *buffptr, PRstreambuflen bufflen)
+{
+ if (is_open() && (ebuf()))
+ return 0;
+ if ((!buffptr) || (bufflen <= 0))
+ unbuffered(1);
+ else
+ setb(buffptr, buffptr+bufflen, 0);
+ return this;
+}
+
+streampos
+PRfilebuf::seekoff(streamoff offset, ios::seek_dir dir, int /* mode */)
+{
+ if (PR_GetDescType(_fd) == PR_DESC_FILE){
+ PRSeekWhence fdir;
+ PRInt32 retpos;
+ switch (dir) {
+ case ios::beg :
+ fdir = PR_SEEK_SET;
+ break;
+ case ios::cur :
+ fdir = PR_SEEK_CUR;
+ break;
+ case ios::end :
+ fdir = PR_SEEK_END;
+ break;
+ default:
+ // error
+ return(EOF);
+ }
+
+ if (PRfilebuf::sync()==EOF)
+ return EOF;
+ if ((retpos=PR_Seek(_fd, offset, fdir))==-1L)
+ return (EOF);
+ return((streampos)retpos);
+ }else
+ return (EOF);
+}
+
+
+int
+PRfilebuf::sync()
+{
+ PRInt32 count;
+
+ if (_fd==0)
+ return(EOF);
+
+ if (!unbuffered()){
+ // Sync write area
+ if ((count=out_waiting())!=0){
+ PRInt32 nout;
+ if ((nout =PR_Write(_fd,
+ (void *) pbase(),
+ (unsigned int)count)) != count){
+ if (nout > 0) {
+ // should set _pptr -= nout
+ pbump(-(int)nout);
+ memmove(pbase(), pbase()+nout, (int)(count-nout));
+ }
+ return(EOF);
+ }
+ }
+ setp(0,0); // empty put area
+
+ if (PR_GetDescType(_fd) == PR_DESC_FILE){
+ // Sockets can't seek; don't need this
+ if ((count=in_avail()) > 0){
+ if (PR_Seek(_fd, -count, PR_SEEK_CUR)!=-1L)
+ {
+ return (EOF);
+ }
+ }
+ }
+ setg(0,0,0); // empty get area
+ }
+ return(0);
+}
+
+PRfilebuf *
+PRfilebuf::close()
+{
+ int retval;
+ if (_fd==0)
+ return 0;
+
+ retval = sync();
+
+ if ((PR_Close(_fd)==0) || (retval==EOF))
+ return 0;
+ _fd = 0;
+ return this;
+}
+
+PRifstream::PRifstream():
+istream(new PRfilebuf)
+{
+ _PRSTR_DELBUF(0);
+}
+
+PRifstream::PRifstream(PRFileDesc *fd):
+istream(new PRfilebuf(fd))
+{
+ _PRSTR_DELBUF(0);
+}
+
+PRifstream::PRifstream(PRFileDesc *fd, char *buff, int bufflen):
+istream(new PRfilebuf(fd, buff, bufflen))
+{
+ _PRSTR_DELBUF(0);
+}
+
+PRifstream::PRifstream(const char * name, int mode, int flags):
+istream(new PRfilebuf)
+{
+ _PRSTR_DELBUF(0);
+ if (!rdbuf()->open(name, (mode|ios::in), flags))
+ clear(rdstate() | ios::failbit);
+}
+
+PRifstream::~PRifstream()
+{
+ sync();
+
+ delete rdbuf();
+#ifdef _PRSTR_BP
+ _PRSTR_BP = 0;
+#endif
+}
+
+streambuf *
+PRifstream::setbuf(char * ptr, int len)
+{
+ if ((is_open()) || (!(rdbuf()->setbuf(ptr, len)))){
+ clear(rdstate() | ios::failbit);
+ return 0;
+ }
+ return rdbuf();
+}
+
+void
+PRifstream::attach(PRFileDesc *fd)
+{
+ if (!(rdbuf()->attach(fd)))
+ clear(rdstate() | ios::failbit);
+}
+
+void
+PRifstream::open(const char * name, int mode, int flags)
+{
+ if (is_open() || !(rdbuf()->open(name, (mode|ios::in), flags)))
+ clear(rdstate() | ios::failbit);
+}
+
+void
+PRifstream::close()
+{
+ clear((rdbuf()->close()) ? 0 : (rdstate() | ios::failbit));
+}
+
+PRofstream::PRofstream():
+ostream(new PRfilebuf)
+{
+ _PRSTR_DELBUF(0);
+}
+
+PRofstream::PRofstream(PRFileDesc *fd):
+ostream(new PRfilebuf(fd))
+{
+ _PRSTR_DELBUF(0);
+}
+
+PRofstream::PRofstream(PRFileDesc *fd, char *buff, int bufflen):
+ostream(new PRfilebuf(fd, buff, bufflen))
+{
+ _PRSTR_DELBUF(0);
+}
+
+PRofstream::PRofstream(const char *name, int mode, int flags):
+ostream(new PRfilebuf)
+{
+ _PRSTR_DELBUF(0);
+ if (!rdbuf()->open(name, (mode|ios::out), flags))
+ clear(rdstate() | ios::failbit);
+}
+
+PRofstream::~PRofstream()
+{
+ flush();
+
+ delete rdbuf();
+#ifdef _PRSTR_BP
+ _PRSTR_BP = 0;
+#endif
+}
+
+streambuf *
+PRofstream::setbuf(char * ptr, int len)
+{
+ if ((is_open()) || (!(rdbuf()->setbuf(ptr, len)))){
+ clear(rdstate() | ios::failbit);
+ return 0;
+ }
+ return rdbuf();
+}
+
+void
+PRofstream::attach(PRFileDesc *fd)
+{
+ if (!(rdbuf()->attach(fd)))
+ clear(rdstate() | ios::failbit);
+}
+
+void
+PRofstream::open(const char * name, int mode, int flags)
+{
+ if (is_open() || !(rdbuf()->open(name, (mode|ios::out), flags)))
+ clear(rdstate() | ios::failbit);
+}
+
+void
+PRofstream::close()
+{
+ clear((rdbuf()->close()) ? 0 : (rdstate() | ios::failbit));
+}
+
+PRfstream::PRfstream():
+iostream(new PRfilebuf)
+{
+ _PRSTR_DELBUF_C(istream, 0);
+ _PRSTR_DELBUF_C(ostream, 0);
+}
+
+PRfstream::PRfstream(PRFileDesc *fd):
+iostream(new PRfilebuf(fd))
+{
+ _PRSTR_DELBUF_C(istream, 0);
+ _PRSTR_DELBUF_C(ostream, 0);
+}
+
+PRfstream::PRfstream(PRFileDesc *fd, char *buff, int bufflen):
+iostream(new PRfilebuf(fd, buff, bufflen))
+{
+ _PRSTR_DELBUF_C(istream, 0);
+ _PRSTR_DELBUF_C(ostream, 0);
+}
+
+PRfstream::PRfstream(const char *name, int mode, int flags):
+iostream(new PRfilebuf)
+{
+ _PRSTR_DELBUF_C(istream, 0);
+ _PRSTR_DELBUF_C(ostream, 0);
+ if (!rdbuf()->open(name, (mode|(ios::in|ios::out)), flags))
+ clear(rdstate() | ios::failbit);
+}
+
+PRfstream::~PRfstream()
+{
+ sync();
+ flush();
+
+ delete rdbuf();
+#ifdef _PRSTR_BP
+ istream::_PRSTR_BP = 0;
+ ostream::_PRSTR_BP = 0;
+#endif
+}
+
+streambuf *
+PRfstream::setbuf(char * ptr, int len)
+{
+ if ((is_open()) || (!(rdbuf()->setbuf(ptr, len)))){
+ clear(rdstate() | ios::failbit);
+ return 0;
+ }
+ return rdbuf();
+}
+
+void
+PRfstream::attach(PRFileDesc *fd)
+{
+ if (!(rdbuf()->attach(fd)))
+ clear(rdstate() | ios::failbit);
+}
+
+void
+PRfstream::open(const char * name, int mode, int flags)
+{
+ if (is_open() || !(rdbuf()->open(name, (mode|(ios::in|ios::out)), flags)))
+ clear(rdstate() | ios::failbit);
+}
+
+void
+PRfstream::close()
+{
+ clear((rdbuf()->close()) ? 0 : (rdstate() | ios::failbit));
+}
+
+#else
+
+// fix it sometime
+
+int fix_prfstreams () { return 0; }
+
+#endif
diff --git a/src/libs/xpcom18a4/nsprpub/lib/prstreams/prstrms.h b/src/libs/xpcom18a4/nsprpub/lib/prstreams/prstrms.h
new file mode 100644
index 00000000..a6752fc4
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/prstreams/prstrms.h
@@ -0,0 +1,153 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * Robin J. Maxwell 11-22-96
+ */
+
+#ifndef _PRSTRMS_H
+#define _PRSTRMS_H
+
+#include "prtypes.h"
+#include "prio.h"
+
+#ifdef _MSC_VER
+#pragma warning( disable : 4275)
+#endif
+#include <iostream.h>
+
+#if defined(AIX) && defined(__64BIT__)
+typedef long PRstreambuflen;
+#else
+typedef int PRstreambuflen;
+#endif
+
+#if defined (PRFSTREAMS_BROKEN)
+
+// fix it sometime
+
+#define PRfilebuf streambuf
+#define PRifstream ifstream
+#define PRofstream ofstream
+#define PRfstream fstream
+
+#else
+
+class PR_IMPLEMENT(PRfilebuf): public streambuf
+{
+public:
+ PRfilebuf();
+ PRfilebuf(PRFileDesc *fd);
+ PRfilebuf(PRFileDesc *fd, char * buffptr, int bufflen);
+ ~PRfilebuf();
+ virtual int overflow(int=EOF);
+ virtual int underflow();
+ virtual streambuf *setbuf(char *buff, PRstreambuflen bufflen);
+ virtual streampos seekoff(streamoff, ios::seek_dir, int);
+ virtual int sync();
+ PRfilebuf *open(const char *name, int mode, int flags);
+ PRfilebuf *attach(PRFileDesc *fd);
+ PRfilebuf *close();
+ int is_open() const {return (_fd != 0);}
+ PRFileDesc *fd(){return _fd;}
+
+private:
+ PRFileDesc * _fd;
+ PRBool _opened;
+ PRBool _allocated;
+};
+
+class PR_IMPLEMENT(PRifstream): public istream {
+public:
+ PRifstream();
+ PRifstream(const char *, int mode=ios::in, int flags = 0);
+ PRifstream(PRFileDesc *);
+ PRifstream(PRFileDesc *, char *, int);
+ ~PRifstream();
+
+ streambuf * setbuf(char *, int);
+ PRfilebuf* rdbuf(){return (PRfilebuf*) ios::rdbuf(); }
+
+ void attach(PRFileDesc *fd);
+ PRFileDesc *fd() {return rdbuf()->fd();}
+
+ int is_open(){return rdbuf()->is_open();}
+ void open(const char *, int mode=ios::in, int flags= 0);
+ void close();
+};
+
+class PR_IMPLEMENT(PRofstream) : public ostream {
+public:
+ PRofstream();
+ PRofstream(const char *, int mode=ios::out, int flags = 0);
+ PRofstream(PRFileDesc *);
+ PRofstream(PRFileDesc *, char *, int);
+ ~PRofstream();
+
+ streambuf * setbuf(char *, int);
+ PRfilebuf* rdbuf() { return (PRfilebuf*) ios::rdbuf(); }
+
+ void attach(PRFileDesc *);
+ PRFileDesc *fd() {return rdbuf()->fd();}
+
+ int is_open(){return rdbuf()->is_open();}
+ void open(const char *, int =ios::out, int = 0);
+ void close();
+};
+
+class PR_IMPLEMENT(PRfstream) : public iostream {
+public:
+ PRfstream();
+ PRfstream(const char *name, int mode, int flags= 0);
+ PRfstream(PRFileDesc *fd);
+ PRfstream(PRFileDesc *fd, char *buff, int bufflen);
+ ~PRfstream();
+
+ streambuf * setbuf(char *, int);
+ PRfilebuf* rdbuf(){ return (PRfilebuf*) ostream::rdbuf(); }
+
+ void attach(PRFileDesc *);
+ PRFileDesc *fd() { return rdbuf()->fd(); }
+
+ int is_open() { return rdbuf()->is_open(); }
+ void open(const char *, int, int = 0);
+ void close();
+};
+
+#endif
+
+#endif /* _PRSTRMS_H */
diff --git a/src/libs/xpcom18a4/nsprpub/lib/prstreams/prstrms.rc b/src/libs/xpcom18a4/nsprpub/lib/prstreams/prstrms.rc
new file mode 100644
index 00000000..589a64d1
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/prstreams/prstrms.rc
@@ -0,0 +1,102 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "prinit.h"
+#include <winver.h>
+
+#define MY_LIBNAME "prstrms"
+#define MY_FILEDESCRIPTION "PRSTRMS Library"
+
+#define STRINGIZE(x) #x
+#define STRINGIZE2(x) STRINGIZE(x)
+#define PR_VMAJOR_STR STRINGIZE2(PR_VMAJOR)
+
+#ifdef _DEBUG
+#define MY_DEBUG_STR " (debug)"
+#define MY_FILEFLAGS_1 VS_FF_DEBUG
+#else
+#define MY_DEBUG_STR ""
+#define MY_FILEFLAGS_1 0x0L
+#endif
+#if PR_BETA
+#define MY_FILEFLAGS_2 MY_FILEFLAGS_1|VS_FF_PRERELEASE
+#else
+#define MY_FILEFLAGS_2 MY_FILEFLAGS_1
+#endif
+
+#ifdef WINNT
+#define MY_FILEOS VOS_NT_WINDOWS32
+#define MY_INTERNAL_NAME "lib" MY_LIBNAME PR_VMAJOR_STR
+#else
+#define MY_FILEOS VOS__WINDOWS32
+#define MY_INTERNAL_NAME MY_LIBNAME PR_VMAJOR_STR
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version-information resource
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION PR_VMAJOR,PR_VMINOR,PR_VPATCH,0
+ PRODUCTVERSION PR_VMAJOR,PR_VMINOR,PR_VPATCH,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS MY_FILEFLAGS_2
+ FILEOS MY_FILEOS
+ FILETYPE VFT_DLL
+ FILESUBTYPE 0x0L // not used
+
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904B0" // Lang=US English, CharSet=Unicode
+ BEGIN
+ VALUE "CompanyName", "Netscape Communications Corporation\0"
+ VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0"
+ VALUE "FileVersion", PR_VERSION "\0"
+ VALUE "InternalName", MY_INTERNAL_NAME "\0"
+ VALUE "LegalCopyright", "Copyright \251 1996-2000 Netscape Communications Corporation\0"
+ VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0"
+ VALUE "ProductName", "Netscape Portable Runtime\0"
+ VALUE "ProductVersion", PR_VERSION "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/src/libs/xpcom18a4/nsprpub/lib/prstreams/tests/testprstrm/.cvsignore b/src/libs/xpcom18a4/nsprpub/lib/prstreams/tests/testprstrm/.cvsignore
new file mode 100644
index 00000000..f3c7a7c5
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/prstreams/tests/testprstrm/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/src/libs/xpcom18a4/nsprpub/lib/prstreams/tests/testprstrm/Makefile.in b/src/libs/xpcom18a4/nsprpub/lib/prstreams/tests/testprstrm/Makefile.in
new file mode 100644
index 00000000..1b682ff8
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/prstreams/tests/testprstrm/Makefile.in
@@ -0,0 +1,254 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# 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 MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#! gmake
+
+MOD_DEPTH = ../../../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/config.mk
+
+ifeq ($(OS_TARGET), WIN16)
+OS_CFLAGS = $(OS_EXE_CFLAGS)
+endif
+
+CXXSRCS = \
+ testprstrm.cpp \
+ $(NULL)
+
+OBJS = $(addprefix $(OBJDIR)/,$(CXXSRCS:.cpp=.$(OBJ_SUFFIX)))
+
+ifeq (,$(filter-out WINNT OS2,$(OS_ARCH)))
+PROG_SUFFIX = .exe
+else
+PROG_SUFFIX =
+endif
+
+PROGS = $(addprefix $(OBJDIR)/, $(CXXSRCS:.cpp=$(PROG_SUFFIX)))
+
+TARGETS = $(PROGS) $(OBJS)
+
+INCLUDES = -I$(dist_includedir)
+
+# Setting the variables LDOPTS and LIBPR. We first initialize
+# them to the default values, then adjust them for some platforms.
+LDOPTS = -L$(dist_libdir)
+LIBPR = -lnspr$(MOD_MAJOR_VERSION)
+LIBPRSTRMS = -lprstrms$(MOD_MAJOR_VERSION)
+
+ifeq ($(OS_ARCH), WINNT)
+ifeq ($(OS_TARGET), WIN16)
+ LIBPR = $(dist_libdir)/nspr$(MOD_MAJOR_VERSION).lib
+ LIBPRSTRMS = $(dist_libdir)/prstrms$(MOD_MAJOR_VERSION).lib
+else
+ LDOPTS = -NOLOGO -DEBUG -DEBUGTYPE:CV -INCREMENTAL:NO
+ ifeq ($(OS_TARGET), WIN95)
+ LIBPR = $(dist_libdir)/nspr$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)
+ LIBPRSTRMS = $(dist_libdir)/prstrms$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)
+ else
+ LIBPR = $(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)
+ LIBPRSTRMS = $(dist_libdir)/libprstrms$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)
+ endif
+endif
+endif
+
+ifeq ($(OS_ARCH),OS2)
+ ifeq ($(MOZ_OS2_TOOLS),VACPP)
+ LDOPTS = -NOE -DEBUG -nologo -PMTYPE:VIO /S:32768
+ LIBPR = $(dist_libdir)/nspr$(MOD_MAJOR_VERSION).lib
+ LIBPRSTRMS = $(dist_libdir)/prstrms$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)
+ else
+ LDOPTS += -Zomf -Zlinker /PM:VIO -lstdcpp
+ endif
+endif
+
+ifneq ($(OS_ARCH), WINNT)
+PWD = $(shell pwd)
+endif
+
+ifeq ($(OS_ARCH), IRIX)
+LDOPTS += -rpath $(PWD)/$(dist_libdir)
+endif
+
+ifeq ($(OS_ARCH), OSF1)
+LDOPTS += -rpath $(PWD)/$(dist_libdir)
+endif
+
+ifeq ($(OS_ARCH), HP-UX)
+LDOPTS += -Wl,+s,+b,$(PWD)/$(dist_libdir)
+endif
+
+# AIX
+ifeq ($(OS_ARCH),AIX)
+LDOPTS += -blibpath:$(PWD)/$(dist_libdir):/usr/lib:/lib
+ifeq ($(OS_ARCH)$(OS_RELEASE),AIX4.1)
+LIBPR = -lnspr$(MOD_MAJOR_VERSION)_shr
+LIBPRSTRMS = -lprstrms$(MOD_MAJOR_VERSION)_shr
+else
+LDOPTS += -brtl
+EXTRA_LIBS = -ldl
+endif
+endif
+
+# Solaris
+ifeq ($(OS_ARCH), SunOS)
+ifneq ($(OS_RELEASE), 4.1.3_U1)
+ifdef NS_USE_GCC
+LDOPTS += -Xlinker -R -Xlinker $(PWD)/$(dist_libdir)
+else
+LDOPTS += -R $(PWD)/$(dist_libdir)
+# CC on SunOS 5.4 and 5.5.x need to link with -lthread or -lpthread
+# (or use the -mt switch) even though we already linked with these
+# system libraries when we built libnspr.so.
+ifdef USE_PTHREADS
+EXTRA_LIBS = -lpthread
+else
+EXTRA_LIBS = -lthread
+endif # USE_PTHREADS
+endif # NS_USE_GCC
+endif # 4.1.3_U1
+endif # SunOS
+
+ifeq ($(OS_ARCH), NCR)
+# XXX: We see some strange problems when we link with libnspr.so.
+# So for now we use static libraries on NCR. The shared library
+# stuff below is commented out.
+LIBPR = $(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).a
+LIBPRSTRMS = $(dist_libdir)/libprstrms$(MOD_MAJOR_VERSION).a
+EXTRA_LIBS = -lsocket -lnsl -ldl
+
+# NCR needs to link against -lsocket -lnsl (and -lc, which is linked
+# implicitly by $(CC)) again even though we already linked with these
+# system libraries when we built libnspr.so.
+#EXTRA_LIBS = -lsocket -lnsl
+# This hardcodes in the executable programs the directory to find
+# libnspr.so etc. at program startup. Equivalent to the -R or -rpath
+# option for ld on other platforms.
+#export LD_RUN_PATH = $(PWD)/$(dist_libdir)
+endif
+
+ifeq ($(OS_ARCH), SCOOS)
+# SCO Unix needs to link against -lsocket again even though we
+# already linked with these system libraries when we built libnspr.so.
+EXTRA_LIBS = -lsocket
+# This hardcodes in the executable programs the directory to find
+# libnspr.so etc. at program startup. Equivalent to the -R or -rpath
+# option for ld on other platforms.
+export LD_RUN_PATH = $(PWD)/$(dist_libdir)
+endif
+
+ifeq ($(OS_ARCH), UNIXWARE)
+export LD_RUN_PATH = $(PWD)/$(dist_libdir)
+endif
+
+#####################################################
+#
+# The rules
+#
+#####################################################
+
+include $(topsrcdir)/config/rules.mk
+
+AIX_PRE_4_2 = 0
+ifeq ($(OS_ARCH),AIX)
+ifneq ($(OS_RELEASE),4.2)
+ifneq ($(USE_PTHREADS), 1)
+#AIX_PRE_4_2 = 1
+endif
+endif
+endif
+
+ifeq ($(AIX_PRE_4_2),1)
+
+# AIX releases prior to 4.2 need a special two-step linking hack
+# in order to both override the system select() and be able to
+# get at the original system select().
+#
+# We use a pattern rule in ns/nspr20/config/rules.mk to generate
+# the .$(OBJ_SUFFIX) file from the .c source file, then do the
+# two-step linking hack below.
+
+$(OBJDIR)/%: $(OBJDIR)/%.$(OBJ_SUFFIX)
+ @$(MAKE_OBJDIR)
+ rm -f $@ $(AIX_TMP)
+ $(CC) $(AIX_LINK_OPTS) -o $(AIX_TMP) $< $(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).a
+ $(CC) -o $@ $(AIX_TMP) $(AIX_WRAP)
+ rm -f $(AIX_TMP)
+
+else
+
+# All platforms that are not AIX pre-4.2.
+
+$(OBJDIR)/%$(PROG_SUFFIX): $(OBJDIR)/%.$(OBJ_SUFFIX)
+ @$(MAKE_OBJDIR)
+ifeq ($(OS_ARCH), WINNT)
+ifeq ($(OS_TARGET),WIN16)
+ echo system windows >w16link
+ echo option map >>w16link
+ echo option stack=10K >>w16link
+ echo option heapsize=32K >>w16link
+ echo debug $(DEBUGTYPE) all >>w16link
+ echo name $@ >>w16link
+ echo file >>w16link
+ echo $< >>w16link
+ echo library >>w16link
+ echo $(LIBPR), >>w16link
+ echo $(LIBPRSTRMS), >>w16link
+ echo winsock.lib >>w16link
+ wlink @w16link.
+else
+ link $(LDOPTS) $< $(LIBPR) $(LIBPRSTRMS) wsock32.lib -out:$@
+endif
+else
+ifeq ($(OS_ARCH),OS2)
+ $(LINK) $(EXEFLAGS) $(LDOPTS) $< $(LIBPR) $(LIBPRSTRMS) $(OS_LIBS) $(EXTRA_LIBS)
+else
+ $(CCC) $(XCFLAGS) $< $(LDOPTS) $(LIBPR) $(LIBPRSTRMS) $(EXTRA_LIBS) -o $@
+endif
+endif
+endif
+
+export:: $(TARGETS)
+clean::
+ rm -f $(TARGETS)
+
+testlinker:
+ echo $(LINK)
diff --git a/src/libs/xpcom18a4/nsprpub/lib/prstreams/tests/testprstrm/testprstrm.cpp b/src/libs/xpcom18a4/nsprpub/lib/prstreams/tests/testprstrm/testprstrm.cpp
new file mode 100644
index 00000000..6e8b8665
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/prstreams/tests/testprstrm/testprstrm.cpp
@@ -0,0 +1,204 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "prinit.h"
+#include "prstrms.h"
+#include "prio.h"
+#include <string.h>
+#include <stdio.h>
+#if defined(XP_UNIX) || defined(XP_OS2_EMX)
+#include <sys/types.h>
+#include <sys/stat.h>
+#endif
+
+const unsigned int MaxCnt = 1;
+
+void threadwork(void *mytag);
+
+
+typedef struct threadarg {
+ void *mytag;
+} threadarg;
+
+void
+#ifdef XP_OS2_VACPP
+_Optlink
+#endif
+threadmain(void *mytag)
+{
+ threadarg arg;
+
+ arg.mytag = mytag;
+
+ threadwork(&arg);
+}
+
+
+void
+threadwork(void *_arg)
+{
+ threadarg *arg = (threadarg *)_arg;
+ unsigned int i;
+
+ char fname1[256];
+ char fname2[256];
+
+ strcpy(fname1, (char *)arg->mytag);
+ strcpy(fname2, (char *)arg->mytag);
+ strcat(fname2, "2");
+ PR_Delete(fname1);
+ PR_Delete(fname2);
+
+ PRfilebuf *fb[MaxCnt];
+ PRifstream *ifs[MaxCnt];
+ PRofstream *ofs[MaxCnt];
+ int mode = 0;
+#ifdef XP_UNIX
+ mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IRGRP|S_IWOTH|S_IROTH;
+#endif
+
+ //
+ // Allocate a bunch
+ cout << "Testing unused filebufs ----------------" << endl;
+ for (i=0; i < MaxCnt; i++){
+ fb[i] = new PRfilebuf;
+ }
+ // Delete them
+ for (i=0; i < MaxCnt; i++){
+ delete fb[i];
+ }
+ cout << "Unused filebufs complete ---------------" << endl;
+
+ //
+ // Allocate a bunch
+ cout << "Testing unused ifstream -----------------" << endl;
+ for (i=0; i < MaxCnt; i++){
+ ifs[i] = new PRifstream;
+ }
+ //
+ // Delete them
+ for (i=0; i < MaxCnt; i++){
+ delete ifs[i];
+ }
+ cout << "Unused ifstream complete ----------------" << endl;
+ //
+ // Allocate a bunch
+ cout << "Testing unused ofstream -----------------" << endl;
+ for (i=0; i < MaxCnt; i++){
+ ofs[i] = new PRofstream;
+ }
+ for (i=0; i < MaxCnt; i++){
+ *(ofs[i]) << "A"; // Write a bit
+ delete ofs[i]; // Delete it.
+ }
+ cout << "Unused ofstream complete ----------------" << endl;
+
+ cout << "Testing use of ofstream 1 (extra filebuf allocated) ---------" << endl;
+ PRofstream *aos = new PRofstream(fname1, ios::out|ios::ate, mode);
+ for (i=0; i < MaxCnt; i++){
+ for (int j=0; j < 8192; j++)
+ *aos << "AaBbCcDdEeFfGg" << endl;
+ fb[i] = new PRfilebuf; // Allocate as we go to hack at the heap
+ }
+ //
+ // Delete the extra foo we allocated
+ for (i=0; i < MaxCnt; i++){
+ delete fb[i];
+ }
+ aos->flush(); // Explicit flush
+ delete aos;
+ cout << "Testing use of ofstream 1 complete (extra filebuf deleted) --" << endl;
+ cout << "Testing use of ofstream 2 (extra filebuf allocated) ---------" << endl;
+ PRofstream *aos2 = new PRofstream(fname2, ios::out, mode);
+
+ for (i=0; i < MaxCnt; i++){
+ *aos2 << "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz";
+ }
+ // Force flushing in the dtor
+ delete aos2;
+ cout << "Testing use of ofstream 2 complete (extra filebuf deleted) --" << endl;
+ char line[1024];
+ cout << "Testing use of ifstream 1 (stack allocation) -------------" << endl;
+ PRifstream ais(fname1);
+ for (i=0; i < MaxCnt; i++){
+ ais >> line;
+ }
+ cout << "Testing use of ifstream 1 complete -----------------------" << endl;
+ cout << "Testing use of ifstream 2 ----------------------" << endl;
+ PRifstream *ais2 = new PRifstream(fname2);
+ char achar;
+ for (i=0; i < MaxCnt*10; i++){
+ *ais2 >> achar;
+ }
+ delete ais2;
+ cout << "Testing use of ifstream 2 complete -------------" << endl;
+}
+
+#define STACKSIZE 1024*1024
+int
+main(int argc, char **argv)
+{
+ PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 256);
+ threadmain("TestFile");
+ PRThread *thr1 = PR_CreateThread(PR_SYSTEM_THREAD,
+ threadmain,
+ (void *)"TestFile1",
+ PR_PRIORITY_NORMAL,
+ PR_GLOBAL_THREAD,
+ PR_JOINABLE_THREAD,
+ STACKSIZE);
+ PRThread *thr2 = PR_CreateThread(PR_SYSTEM_THREAD,
+ threadmain,
+ (void *)"TestFile2",
+ PR_PRIORITY_NORMAL,
+ PR_GLOBAL_THREAD,
+ PR_JOINABLE_THREAD,
+ STACKSIZE);
+
+ PRThread *thr3 = PR_CreateThread(PR_SYSTEM_THREAD,
+ threadmain,
+ (void *)"TestFile3",
+ PR_PRIORITY_NORMAL,
+ PR_GLOBAL_THREAD,
+ PR_JOINABLE_THREAD,
+ STACKSIZE);
+ PR_JoinThread(thr1);
+ PR_JoinThread(thr2);
+ PR_JoinThread(thr3);
+ return 0;
+}
+
diff --git a/src/libs/xpcom18a4/nsprpub/lib/tests/.cvsignore b/src/libs/xpcom18a4/nsprpub/lib/tests/.cvsignore
new file mode 100644
index 00000000..f3c7a7c5
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/tests/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/src/libs/xpcom18a4/nsprpub/lib/tests/Makefile.in b/src/libs/xpcom18a4/nsprpub/lib/tests/Makefile.in
new file mode 100644
index 00000000..8c3dc9a8
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/tests/Makefile.in
@@ -0,0 +1,259 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998-2000
+# 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 MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#! gmake
+
+MOD_DEPTH = ../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/config.mk
+
+ifeq ($(OS_ARCH), WINNT)
+# DIRS = windows
+endif
+
+ifeq ($(OS_TARGET), WIN16)
+OS_CFLAGS = $(OS_EXE_CFLAGS)
+endif
+
+CSRCS = \
+ arena.c \
+ string.c \
+ base64t.c
+
+ifeq (,$(filter-out WINNT OS2,$(OS_ARCH)))
+CSRCS += arena.c
+endif
+
+ifeq (,$(filter-out WINNT OS2,$(OS_ARCH)))
+PROG_SUFFIX = .exe
+else
+PROG_SUFFIX =
+endif
+
+PROGS = $(addprefix $(OBJDIR)/, $(CSRCS:.c=$(PROG_SUFFIX)))
+
+TARGETS = $(PROGS) $(OBJS)
+
+INCLUDES = -I$(dist_includedir)
+
+# Setting the variables LDOPTS and LIBPR. We first initialize
+# them to the default values, then adjust them for some platforms.
+LDOPTS = -L$(dist_libdir)
+LIBPR = -lnspr$(MOD_MAJOR_VERSION)
+LIBPLC = -lplc$(MOD_MAJOR_VERSION)
+LIBPLDS = -lplds$(MOD_MAJOR_VERSION)
+
+ifeq ($(OS_ARCH), WINNT)
+ifeq ($(OS_TARGET), WIN16)
+ LIBPR = $(dist_libdir)/nspr$(MOD_MAJOR_VERSION).lib
+ LIBPLC= $(dist_libdir)/plc$(MOD_MAJOR_VERSION).lib
+ LIBPLDS= $(dist_libdir)/plds$(MOD_MAJOR_VERSION).lib
+else
+ LDOPTS = -NOLOGO -DEBUG -DEBUGTYPE:CV -INCREMENTAL:NO
+ ifeq ($(OS_TARGET), WIN95)
+ LIBPR = $(dist_libdir)/nspr$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)
+ LIBPLC= $(dist_libdir)/plc$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)
+ LIBPLDS= $(dist_libdir)/plds$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)
+ else
+ LIBPR = $(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)
+ LIBPLC= $(dist_libdir)/libplc$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)
+ LIBPLDS= $(dist_libdir)/libplds$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)
+ endif
+endif
+endif
+
+ifeq ($(OS_ARCH),OS2)
+ ifeq ($(MOZ_OS2_TOOLS),VACPP)
+ LDOPTS = -NOE -DEBUG -nologo -PMTYPE:VIO /S:32768
+ LIBPR = $(dist_libdir)/nspr$(MOD_MAJOR_VERSION).lib
+ LIBPLC = $(dist_libdir)/plc$(MOD_MAJOR_VERSION).lib
+ LIBPLDS= $(dist_libdir)/plds$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)
+ else
+ LDOPTS += -Zomf -Zlinker /PM:VIO
+ endif
+endif
+
+ifneq ($(OS_ARCH), WINNT)
+PWD = $(shell pwd)
+endif
+
+ifeq ($(OS_ARCH), IRIX)
+LDOPTS += -rpath $(PWD)/$(dist_libdir)
+endif
+
+ifeq ($(OS_ARCH), Linux)
+ ifeq ($(OS_RELEASE), 1.2)
+ EXTRA_LIBS = -ldl
+ else
+ LDOPTS += -Xlinker -rpath $(PWD)/$(dist_libdir)
+ ifeq ($(USE_PTHREADS),1)
+ EXTRA_LIBS = -lpthread
+ endif
+ endif
+endif
+
+ifeq ($(OS_ARCH), OSF1)
+LDOPTS += -rpath $(PWD)/$(dist_libdir) -lpthread
+endif
+
+ifeq ($(OS_ARCH), HP-UX)
+LDOPTS += -Wl,+s,+b,$(PWD)/$(dist_libdir)
+endif
+
+# AIX
+ifeq ($(OS_ARCH),AIX)
+LDOPTS += -blibpath:$(PWD)/$(dist_libdir):/usr/lib:/lib
+LIBPR = -lnspr$(MOD_MAJOR_VERSION)_shr
+LIBPLC = -lplc$(MOD_MAJOR_VERSION)_shr
+endif
+
+# Solaris
+ifeq ($(OS_ARCH), SunOS)
+ifneq ($(OS_RELEASE), 4.1.3_U1)
+ifdef NS_USE_GCC
+LDOPTS += -Xlinker -R -Xlinker $(PWD)/$(dist_libdir)
+else
+LDOPTS += -R $(PWD)/$(dist_libdir)
+endif
+endif
+
+# SunOS 5.4 and 5.5 need to link with -lthread or -lpthread,
+# even though we already linked with these system libraries
+# when we built libnspr.so.
+ifeq ($(OS_RELEASE), 5.4)
+EXTRA_LIBS = -lthread
+endif
+
+ifeq ($(OS_RELEASE), 5.5)
+ifdef USE_PTHREADS
+EXTRA_LIBS = -lpthread
+else
+EXTRA_LIBS = -lthread
+endif
+endif
+endif # SunOS
+
+ifeq ($(OS_ARCH), NCR)
+# NCR needs to link against -lsocket -lnsl (and -lc, which is linked
+# implicitly by $(CC)) again even though we already linked with these
+# system libraries when we built libnspr.so.
+EXTRA_LIBS = -lsocket -lnsl
+# This hardcodes in the executable programs the directory to find
+# libnspr.so etc. at program startup. Equivalent to the -R or -rpath
+# option for ld on other platforms.
+export LD_RUN_PATH = $(PWD)/$(dist_libdir)
+endif
+
+#####################################################
+#
+# The rules
+#
+#####################################################
+
+include $(topsrcdir)/config/rules.mk
+
+AIX_PRE_4_2 = 0
+ifeq ($(OS_ARCH),AIX)
+ifneq ($(OS_RELEASE),4.2)
+ifneq ($(USE_PTHREADS), 1)
+#AIX_PRE_4_2 = 1
+endif
+endif
+endif
+
+ifeq ($(AIX_PRE_4_2),1)
+
+# AIX releases prior to 4.2 need a special two-step linking hack
+# in order to both override the system select() and be able to
+# get at the original system select().
+#
+# We use a pattern rule in ns/nspr20/config/rules.mk to generate
+# the .$(OBJ_SUFFIX) file from the .c source file, then do the
+# two-step linking hack below.
+
+$(OBJDIR)/%: $(OBJDIR)/%.$(OBJ_SUFFIX)
+ @$(MAKE_OBJDIR)
+ rm -f $@ $(AIX_TMP)
+ $(CC) $(AIX_LINK_OPTS) -o $(AIX_TMP) $< $(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).a
+ $(CC) -o $@ $(AIX_TMP) $(AIX_WRAP)
+ rm -f $(AIX_TMP)
+
+else
+
+# All platforms that are not AIX pre-4.2.
+
+$(OBJDIR)/%$(PROG_SUFFIX): $(OBJDIR)/%.$(OBJ_SUFFIX)
+ @$(MAKE_OBJDIR)
+
+ifeq ($(OS_ARCH), WINNT)
+ifeq ($(OS_TARGET),WIN16)
+ echo system windows >w16link
+ echo option map >>w16link
+ echo option stack=10K >>w16link
+ echo option heapsize=32K >>w16link
+ echo debug $(DEBUGTYPE) all >>w16link
+ echo name $@ >>w16link
+ echo file >>w16link
+ echo $< >>w16link
+ echo library >>w16link
+ echo $(LIBPR), >>w16link
+ echo $(LIBPLC), >>w16link
+ echo winsock.lib >>w16link
+ wlink @w16link.
+else
+ link $(LDOPTS) $< $(LIBPLC) $(LIBPLDS) $(LIBPR) wsock32.lib -out:$@
+endif
+else
+ifeq ($(OS_ARCH),OS2)
+ $(LINK) $(EXEFLAGS) $(LDOPTS) $< $(LIBPLC) $(LIBPLDS) $(LIBPR) $(OS_LIBS) $(EXTRA_LIBS)
+else
+ $(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPLC) $(LIBPLDS) $(LIBPR) $(EXTRA_LIBS) -o $@
+endif
+endif
+endif
+
+export:: $(TARGETS)
+clean::
+ rm -f $(TARGETS)
+
+
+
diff --git a/src/libs/xpcom18a4/nsprpub/lib/tests/arena.c b/src/libs/xpcom18a4/nsprpub/lib/tests/arena.c
new file mode 100644
index 00000000..9c74479c
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/tests/arena.c
@@ -0,0 +1,401 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File: arena.c
+** Description: Testing arenas
+**
+*/
+
+#include <string.h>
+#include <time.h>
+#include <stdlib.h>
+#include "nspr.h"
+#include "plarena.h"
+#include "plgetopt.h"
+
+PRLogModuleInfo *tLM;
+PRIntn threadCount = 0;
+PRMonitor *tMon;
+PRBool failed_already = PR_FALSE;
+
+/* Arguments from the command line with default values */
+PRIntn debug_mode = 0;
+PRIntn poolMin = 4096;
+PRIntn poolMax = (100 * 4096);
+PRIntn arenaMin = 40;
+PRIntn arenaMax = (100 * 40);
+PRIntn stressIterations = 15;
+PRIntn maxAlloc = (1024 * 1024);
+PRIntn stressThreads = 4;
+
+void DumpAll( void )
+{
+ return;
+}
+
+/*
+** Test Arena allocation.
+*/
+static void ArenaAllocate( void )
+{
+ PLArenaPool ap;
+ void *ptr;
+ PRInt32 i;
+
+ PL_InitArenaPool( &ap, "AllocArena", 2048, sizeof(double));
+ PR_LOG( tLM, PR_LOG_DEBUG, ("AA, InitPool -- Pool: %p. first: %p, current: %p, size: %d",
+ &ap, ap.first, ap.current, ap.arenasize ));
+
+ for( i = 0; i < 150; i++ )
+ {
+ PL_ARENA_ALLOCATE( ptr, &ap, 512 );
+ PR_LOG( tLM, PR_LOG_DEBUG,("AA, after alloc -- Pool: %p. first: %p, current: %p, size: %d",
+ &ap, ap.first, ap.current, ap.arenasize ));
+ PR_LOG( tLM, PR_LOG_DEBUG,(
+ "AA -- Pool: %p. alloc: %p ", &ap, ptr ));
+ }
+
+ PL_FreeArenaPool( &ap );
+
+ for( i = 0; i < 221; i++ )
+ {
+ PL_ARENA_ALLOCATE( ptr, &ap, 512 );
+ PR_LOG( tLM, PR_LOG_DEBUG,("AA, after alloc -- Pool: %p. first: %p, current: %p, size: %d",
+ &ap, ap.first, ap.current, ap.arenasize ));
+ PR_LOG( tLM, PR_LOG_DEBUG,(
+ "AA -- Pool: %p. alloc: %p ", &ap, ptr ));
+ }
+
+ PL_FreeArenaPool( &ap );
+
+ return;
+} /* end ArenaGrow() */
+/*
+** Test Arena grow.
+*/
+static void ArenaGrow( void )
+{
+ PLArenaPool ap;
+ void *ptr;
+ PRInt32 i;
+
+ PL_InitArenaPool( &ap, "TheArena", 4096, sizeof(double));
+ PL_ARENA_ALLOCATE( ptr, &ap, 512 );
+
+ PR_LOG( tLM, PR_LOG_DEBUG, ("Before growth -- Pool: %p. alloc: %p ", &ap, ptr ));
+
+ for( i = 0; i < 10; i++ )
+ {
+ PL_ARENA_GROW( ptr, &ap, 512, 7000 );
+ PR_LOG( tLM, PR_LOG_DEBUG, ("After growth -- Pool: %p. alloc: %p ", &ap, ptr ));
+ }
+
+
+ return;
+} /* end ArenaGrow() */
+
+
+/*
+** Test arena Mark and Release.
+*/
+static void MarkAndRelease( void )
+{
+ PLArenaPool ap;
+ void *ptr = NULL;
+ void *mark0, *mark1;
+ PRIntn i;
+
+ PL_InitArenaPool( &ap, "TheArena", 4096, sizeof(double));
+ mark0 = PL_ARENA_MARK( &ap );
+ PR_LOG( tLM, PR_LOG_DEBUG,
+ ("mark0. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p, m0: %p",
+ &ap, ap.first.next, ap.current, ap.arenasize, ptr, mark0 ));
+
+ for( i = 0; i < 201; i++ )
+ {
+ PL_ARENA_ALLOCATE( ptr, &ap, 512 );
+ PR_LOG( tLM, PR_LOG_DEBUG,
+ ("mr. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p",
+ &ap, ap.first.next, ap.current, ap.arenasize, ptr ));
+ }
+
+ mark1 = PL_ARENA_MARK( &ap );
+ PR_LOG( tLM, PR_LOG_DEBUG,
+ ("mark1. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p, m1: %p",
+ &ap, ap.first.next, ap.current, ap.arenasize, ptr, mark1 ));
+
+
+ for( i = 0; i < 225; i++ )
+ {
+ PL_ARENA_ALLOCATE( ptr, &ap, 512 );
+ PR_LOG( tLM, PR_LOG_DEBUG,
+ ("mr. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p",
+ &ap, ap.first.next, ap.current, ap.arenasize, ptr ));
+ }
+
+ PL_ARENA_RELEASE( &ap, mark1 );
+ PR_LOG( tLM, PR_LOG_DEBUG,
+ ("Release-1: %p -- Pool: %p. first: %p, current: %p, size: %d",
+ mark1, &ap, ap.first, ap.current, ap.arenasize ));
+
+ for( i = 0; i < 20; i++ )
+ {
+ PL_ARENA_ALLOCATE( ptr, &ap, 512 );
+ PR_LOG( tLM, PR_LOG_DEBUG,
+ ("mr. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p",
+ &ap, ap.first.next, ap.current, ap.arenasize, ptr ));
+ }
+
+ PL_ARENA_RELEASE( &ap, mark1 );
+ PR_LOG( tLM, PR_LOG_DEBUG,
+ ("Release-1. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p",
+ &ap, ap.first.next, ap.current, ap.arenasize, ptr ));
+
+ PL_ARENA_RELEASE( &ap, mark0 );
+ PR_LOG( tLM, PR_LOG_DEBUG,
+ ("Release-0. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p",
+ &ap, ap.first.next, ap.current, ap.arenasize, ptr ));
+
+ PL_FreeArenaPool( &ap );
+ PR_LOG( tLM, PR_LOG_DEBUG,
+ ("Free. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p",
+ &ap, ap.first.next, ap.current, ap.arenasize, ptr ));
+
+ PL_FinishArenaPool( &ap );
+ PR_LOG( tLM, PR_LOG_DEBUG,
+ ("Finish. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p",
+ &ap, ap.first.next, ap.current, ap.arenasize, ptr ));
+
+ return;
+} /* end MarkAndRelease() */
+
+/*
+** RandSize() returns a random number in the range
+** min..max, rounded to the next doubleword
+**
+*/
+static PRIntn RandSize( PRIntn min, PRIntn max )
+{
+ PRIntn sz = (rand() % (max -min)) + min + sizeof(double);
+
+ sz &= ~sizeof(double)-1;
+
+ return(sz);
+}
+
+
+/*
+** StressThread()
+** A bunch of these beat on individual arenas
+** This tests the free_list protection.
+**
+*/
+static void PR_CALLBACK StressThread( void *arg )
+{
+ PLArenaPool ap;
+ PRIntn i;
+ PRIntn sz;
+ void *ptr;
+ PRThread *tp = PR_GetCurrentThread();
+
+ PR_LOG( tLM, PR_LOG_DEBUG, ("Stress Thread %p started\n", PR_GetCurrentThread()));
+ PL_InitArenaPool( &ap, "TheArena", RandSize( poolMin, poolMax), sizeof(double));
+
+ for ( i = 0; i < stressIterations; i++ )
+ {
+ PRIntn allocated = 0;
+
+ while ( allocated < maxAlloc )
+ {
+ sz = RandSize( arenaMin, arenaMax );
+ PL_ARENA_ALLOCATE( ptr, &ap, sz );
+ if ( ptr == NULL )
+ {
+ PR_LOG( tLM, PR_LOG_ERROR, ("ARENA_ALLOCATE() returned NULL\n\tAllocated: %d\n", allocated));
+ break;
+ }
+ allocated += sz;
+ }
+ PR_LOG( tLM, PR_LOG_DEBUG, ("Stress thread %p finished one iteration\n", tp));
+ PL_FreeArenaPool( &ap );
+ }
+ PR_LOG( tLM, PR_LOG_DEBUG, ("Stress thread %p finished all iteration\n", tp));
+ PL_FinishArenaPool( &ap );
+ PR_LOG( tLM, PR_LOG_DEBUG, ("Stress thread %p after FinishArenaPool()\n", tp));
+
+ /* That's all folks! let's quit */
+ PR_EnterMonitor(tMon);
+ threadCount--;
+ PR_Notify(tMon);
+ PR_ExitMonitor(tMon);
+ return;
+}
+
+/*
+** Stress()
+** Flog the hell out of arenas multi-threaded.
+** Do NOT pass an individual arena to another thread.
+**
+*/
+static void Stress( void )
+{
+ PRThread *tt;
+ PRIntn i;
+
+ tMon = PR_NewMonitor();
+
+ for ( i = 0 ; i < stressThreads ; i++ )
+ {
+ PR_EnterMonitor(tMon);
+ tt = PR_CreateThread(PR_USER_THREAD,
+ StressThread,
+ NULL,
+ PR_PRIORITY_NORMAL,
+ PR_GLOBAL_THREAD,
+ PR_UNJOINABLE_THREAD,
+ 0);
+ threadCount++;
+ PR_ExitMonitor(tMon);
+ }
+
+ /* Wait for all threads to exit */
+ PR_EnterMonitor(tMon);
+ while ( threadCount != 0 )
+ {
+ PR_Wait(tMon, PR_INTERVAL_NO_TIMEOUT);
+ }
+ PR_ExitMonitor(tMon);
+ PR_DestroyMonitor(tMon);
+
+ return;
+} /* end Stress() */
+
+/*
+** EvaluateResults()
+** uses failed_already to display results and set program
+** exit code.
+*/
+static PRIntn EvaluateResults(void)
+{
+ PRIntn rc = 0;
+
+ if ( failed_already == PR_TRUE )
+ {
+ PR_LOG( tLM, PR_LOG_DEBUG, ("FAIL\n"));
+ rc =1;
+ }
+ else
+ {
+ PR_LOG( tLM, PR_LOG_DEBUG, ("PASS\n"));
+ }
+ return(rc);
+} /* EvaluateResults() */
+
+void Help( void )
+{
+ printf("arena [options]\n");
+ printf("where options are:\n");
+ printf("-p <n> minimum size of an arena pool. Default(%d)\n", poolMin);
+ printf("-P <n> maximum size of an arena pool. Default(%d)\n", poolMax);
+ printf("-a <n> minimum size of an arena allocation. Default(%d)\n", arenaMin);
+ printf("-A <n> maximum size of an arena allocation. Default(%d)\n", arenaMax);
+ printf("-i <n> number of iterations in a stress thread. Default(%d)\n", stressIterations);
+ printf("-s <n> maximum allocation for a single stress thread. Default(%d)\n", maxAlloc);
+ printf("-t <n> number of stress threads. Default(%d)\n", stressThreads );
+ printf("-d enable debug mode\n");
+ printf("\n");
+ exit(1);
+}
+
+PRIntn main(PRIntn argc, char *argv[])
+{
+ PLOptStatus os;
+ PLOptState *opt = PL_CreateOptState(argc, argv, "dhp:P:a:A:i:s:t:");
+ while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+ {
+ if (PL_OPT_BAD == os) continue;
+ switch (opt->option)
+ {
+ case 'a': /* arena Min size */
+ arenaMin = atol( opt->value );
+ break;
+ case 'A': /* arena Max size */
+ arenaMax = atol( opt->value );
+ break;
+ case 'p': /* pool Min size */
+ poolMin = atol( opt->value );
+ break;
+ case 'P': /* pool Max size */
+ poolMax = atol( opt->value );
+ break;
+ case 'i': /* Iterations in stress tests */
+ stressIterations = atol( opt->value );
+ break;
+ case 's': /* storage to get per iteration */
+ maxAlloc = atol( opt->value );
+ break;
+ case 't': /* Number of stress threads to create */
+ stressThreads = atol( opt->value );
+ break;
+ case 'd': /* debug mode */
+ debug_mode = 1;
+ break;
+ case 'h': /* help */
+ default:
+ Help();
+ } /* end switch() */
+ } /* end while() */
+ PL_DestroyOptState(opt);
+
+ srand( (unsigned)time( NULL ) ); /* seed random number generator */
+ tLM = PR_NewLogModule("testcase");
+
+
+#if 0
+ ArenaAllocate();
+ ArenaGrow();
+#endif
+
+ MarkAndRelease();
+
+ Stress();
+
+ return(EvaluateResults());
+} /* end main() */
+
+/* arena.c */
diff --git a/src/libs/xpcom18a4/nsprpub/lib/tests/base64t.c b/src/libs/xpcom18a4/nsprpub/lib/tests/base64t.c
new file mode 100644
index 00000000..c3c48813
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/tests/base64t.c
@@ -0,0 +1,3047 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "plbase64.h"
+#include "plstr.h"
+#include "nspr.h"
+
+#include <stdio.h>
+
+static unsigned char *base = (unsigned char *)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+/* PL_Base64Encode, single characters */
+PRBool test_001(void)
+{
+ PRUint32 a, b;
+ unsigned char plain[ 4 ];
+ unsigned char cypher[ 5 ];
+ char result[ 8 ];
+ char *rv;
+
+ printf("Test 001 (PL_Base64Encode, single characters) ..."); fflush(stdout);
+
+ plain[1] = plain[2] = plain[3] = (unsigned char)0;
+ cypher[2] = cypher[3] = (unsigned char)'=';
+ cypher[4] = (unsigned char)0;
+
+ for( a = 0; a < 64; a++ )
+ {
+ cypher[0] = base[a];
+
+ for( b = 0; b < 4; b++ )
+ {
+ plain[0] = (unsigned char)(a * 4 + b);
+ cypher[1] = base[(b * 16)];
+
+ rv = PL_Base64Encode((char *)plain, 1, result);
+ if( rv != result )
+ {
+ printf("FAIL\n\t(%d, %d): return value\n", a, b);
+ return PR_FALSE;
+ }
+
+ if( 0 != PL_strncmp((char *)cypher, result, 4) )
+ {
+ printf("FAIL\n\t(%d, %d): expected \"%s,\" got \"%.4s.\"\n",
+ a, b, cypher, result);
+ return PR_FALSE;
+ }
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_Base64Encode, double characters */
+PRBool test_002(void)
+{
+ PRUint32 a, b, c, d;
+ unsigned char plain[ 4 ];
+ unsigned char cypher[ 5 ];
+ char result[ 8 ];
+ char *rv;
+
+ printf("Test 002 (PL_Base64Encode, double characters) ..."); fflush(stdout);
+
+ plain[2] = plain[3] = (unsigned char)0;
+ cypher[3] = (unsigned char)'=';
+ cypher[4] = (unsigned char)0;
+
+ for( a = 0; a < 64; a++ )
+ {
+ cypher[0] = base[a];
+ for( b = 0; b < 4; b++ )
+ {
+ plain[0] = (a*4) + b;
+ for( c = 0; c < 16; c++ )
+ {
+ cypher[1] = base[b*16 + c];
+ for( d = 0; d < 16; d++ )
+ {
+ plain[1] = c*16 + d;
+ cypher[2] = base[d*4];
+
+ rv = PL_Base64Encode((char *)plain, 2, result);
+ if( rv != result )
+ {
+ printf("FAIL\n\t(%d, %d, %d, %d): return value\n", a, b, c, d);
+ return PR_FALSE;
+ }
+
+ if( 0 != PL_strncmp((char *)cypher, result, 4) )
+ {
+ printf("FAIL\n\t(%d, %d, %d, %d): expected \"%s,\" got \"%.4s.\"\n",
+ a, b, c, d, cypher, result);
+ return PR_FALSE;
+ }
+ }
+ }
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_Base64Encode, triple characters */
+PRBool test_003(void)
+{
+ PRUint32 a, b, c, d, e, f;
+ unsigned char plain[ 4 ];
+ unsigned char cypher[ 5 ];
+ char result[ 8 ];
+ char *rv;
+
+ printf("Test 003 (PL_Base64Encode, triple characters) ..."); fflush(stdout);
+
+ cypher[4] = (unsigned char)0;
+
+ for( a = 0; a < 64; a++ )
+ {
+ cypher[0] = base[a];
+ for( b = 0; b < 4; b++ )
+ {
+ plain[0] = (a*4) + b;
+ for( c = 0; c < 16; c++ )
+ {
+ cypher[1] = base[b*16 + c];
+ for( d = 0; d < 16; d++ )
+ {
+ plain[1] = c*16 + d;
+ for( e = 0; e < 4; e++ )
+ {
+ cypher[2] = base[d*4 + e];
+ for( f = 0; f < 64; f++ )
+ {
+ plain[2] = e * 64 + f;
+ cypher[3] = base[f];
+
+ rv = PL_Base64Encode((char *)plain, 3, result);
+ if( rv != result )
+ {
+ printf("FAIL\n\t(%d, %d, %d, %d, %d, %d): return value\n", a, b, c, d, e, f);
+ return PR_FALSE;
+ }
+
+ if( 0 != PL_strncmp((char *)cypher, result, 4) )
+ {
+ printf("FAIL\n\t(%d, %d, %d, %d, %d, %d): expected \"%s,\" got \"%.4s.\"\n",
+ a, b, c, d, e, f, cypher, result);
+ return PR_FALSE;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+ static struct
+ {
+ const char *plaintext;
+ const char *cyphertext;
+ } array[] =
+ {
+ /* Cyphertexts generated with uuenview 0.5.13 */
+ { " ", "IA==" },
+ { ".", "Lg==" },
+ { "/", "Lw==" },
+ { "C", "Qw==" },
+ { "H", "SA==" },
+ { "S", "Uw==" },
+ { "^", "Xg==" },
+ { "a", "YQ==" },
+ { "o", "bw==" },
+ { "t", "dA==" },
+
+ { "AB", "QUI=" },
+ { "AH", "QUg=" },
+ { "AQ", "QVE=" },
+ { "BD", "QkQ=" },
+ { "CR", "Q1I=" },
+ { "CS", "Q1M=" },
+ { "DB", "REI=" },
+ { "DC", "REM=" },
+ { "EK", "RUs=" },
+ { "ET", "RVQ=" },
+ { "IM", "SU0=" },
+ { "JR", "SlI=" },
+ { "LO", "TE8=" },
+ { "LW", "TFc=" },
+ { "ML", "TUw=" },
+ { "SB", "U0I=" },
+ { "TO", "VE8=" },
+ { "VS", "VlM=" },
+ { "WP", "V1A=" },
+ /* legitimate two-letter words */
+ { "ad", "YWQ=" },
+ { "ah", "YWg=" },
+ { "am", "YW0=" },
+ { "an", "YW4=" },
+ { "as", "YXM=" },
+ { "at", "YXQ=" },
+ { "ax", "YXg=" },
+ { "be", "YmU=" },
+ { "by", "Ynk=" },
+ { "do", "ZG8=" },
+ { "go", "Z28=" },
+ { "he", "aGU=" },
+ { "hi", "aGk=" },
+ { "if", "aWY=" },
+ { "in", "aW4=" },
+ { "is", "aXM=" },
+ { "it", "aXQ=" },
+ { "me", "bWU=" },
+ { "my", "bXk=" },
+ { "no", "bm8=" },
+ { "of", "b2Y=" },
+ { "on", "b24=" },
+ { "or", "b3I=" },
+ { "ox", "b3g=" },
+ { "so", "c28=" },
+ { "to", "dG8=" },
+ { "up", "dXA=" },
+ { "us", "dXM=" },
+ { "we", "d2U=" },
+ /* all three-letter entries in /usr/dict/words */
+ { "1st", "MXN0" },
+ { "2nd", "Mm5k" },
+ { "3rd", "M3Jk" },
+ { "4th", "NHRo" },
+ { "5th", "NXRo" },
+ { "6th", "NnRo" },
+ { "7th", "N3Ro" },
+ { "8th", "OHRo" },
+ { "9th", "OXRo" },
+ { "AAA", "QUFB" },
+ { "AAU", "QUFV" },
+ { "ABA", "QUJB" },
+ { "abc", "YWJj" },
+ { "Abe", "QWJl" },
+ { "Abo", "QWJv" },
+ { "ace", "YWNl" },
+ { "ACM", "QUNN" },
+ { "ACS", "QUNT" },
+ { "act", "YWN0" },
+ { "Ada", "QWRh" },
+ { "add", "YWRk" },
+ { "ado", "YWRv" },
+ { "aft", "YWZ0" },
+ { "age", "YWdl" },
+ { "ago", "YWdv" },
+ { "aid", "YWlk" },
+ { "ail", "YWls" },
+ { "aim", "YWlt" },
+ { "air", "YWly" },
+ { "ala", "YWxh" },
+ { "alb", "YWxi" },
+ { "ale", "YWxl" },
+ { "Ali", "QWxp" },
+ { "all", "YWxs" },
+ { "alp", "YWxw" },
+ { "A&M", "QSZN" },
+ { "AMA", "QU1B" },
+ { "ami", "YW1p" },
+ { "amp", "YW1w" },
+ { "Amy", "QW15" },
+ { "amy", "YW15" },
+ { "ana", "YW5h" },
+ { "and", "YW5k" },
+ { "ani", "YW5p" },
+ { "Ann", "QW5u" },
+ { "ant", "YW50" },
+ { "any", "YW55" },
+ { "A&P", "QSZQ" },
+ { "ape", "YXBl" },
+ { "Apr", "QXBy" },
+ { "APS", "QVBT" },
+ { "apt", "YXB0" },
+ { "arc", "YXJj" },
+ { "are", "YXJl" },
+ { "ark", "YXJr" },
+ { "arm", "YXJt" },
+ { "art", "YXJ0" },
+ { "a's", "YSdz" },
+ { "ash", "YXNo" },
+ { "ask", "YXNr" },
+ { "ass", "YXNz" },
+ { "ate", "YXRl" },
+ { "Aug", "QXVn" },
+ { "auk", "YXVr" },
+ { "Ave", "QXZl" },
+ { "awe", "YXdl" },
+ { "awl", "YXds" },
+ { "awn", "YXdu" },
+ { "axe", "YXhl" },
+ { "aye", "YXll" },
+ { "bad", "YmFk" },
+ { "bag", "YmFn" },
+ { "bah", "YmFo" },
+ { "bam", "YmFt" },
+ { "ban", "YmFu" },
+ { "bar", "YmFy" },
+ { "bat", "YmF0" },
+ { "bay", "YmF5" },
+ { "bed", "YmVk" },
+ { "bee", "YmVl" },
+ { "beg", "YmVn" },
+ { "bel", "YmVs" },
+ { "Ben", "QmVu" },
+ { "bet", "YmV0" },
+ { "bey", "YmV5" },
+ { "bib", "Ymli" },
+ { "bid", "Ymlk" },
+ { "big", "Ymln" },
+ { "bin", "Ymlu" },
+ { "bit", "Yml0" },
+ { "biz", "Yml6" },
+ { "BMW", "Qk1X" },
+ { "boa", "Ym9h" },
+ { "bob", "Ym9i" },
+ { "bog", "Ym9n" },
+ { "bon", "Ym9u" },
+ { "boo", "Ym9v" },
+ { "bop", "Ym9w" },
+ { "bow", "Ym93" },
+ { "box", "Ym94" },
+ { "boy", "Ym95" },
+ { "b's", "Yidz" },
+ { "BTL", "QlRM" },
+ { "BTU", "QlRV" },
+ { "bub", "YnVi" },
+ { "bud", "YnVk" },
+ { "bug", "YnVn" },
+ { "bum", "YnVt" },
+ { "bun", "YnVu" },
+ { "bus", "YnVz" },
+ { "but", "YnV0" },
+ { "buy", "YnV5" },
+ { "bye", "Ynll" },
+ { "cab", "Y2Fi" },
+ { "Cal", "Q2Fs" },
+ { "cam", "Y2Ft" },
+ { "can", "Y2Fu" },
+ { "cap", "Y2Fw" },
+ { "car", "Y2Fy" },
+ { "cat", "Y2F0" },
+ { "caw", "Y2F3" },
+ { "CBS", "Q0JT" },
+ { "CDC", "Q0RD" },
+ { "CEQ", "Q0VR" },
+ { "chi", "Y2hp" },
+ { "CIA", "Q0lB" },
+ { "cit", "Y2l0" },
+ { "cod", "Y29k" },
+ { "cog", "Y29n" },
+ { "col", "Y29s" },
+ { "con", "Y29u" },
+ { "coo", "Y29v" },
+ { "cop", "Y29w" },
+ { "cos", "Y29z" },
+ { "cot", "Y290" },
+ { "cow", "Y293" },
+ { "cox", "Y294" },
+ { "coy", "Y295" },
+ { "CPA", "Q1BB" },
+ { "cpu", "Y3B1" },
+ { "CRT", "Q1JU" },
+ { "cry", "Y3J5" },
+ { "c's", "Yydz" },
+ { "cub", "Y3Vi" },
+ { "cud", "Y3Vk" },
+ { "cue", "Y3Vl" },
+ { "cup", "Y3Vw" },
+ { "cur", "Y3Vy" },
+ { "cut", "Y3V0" },
+ { "dab", "ZGFi" },
+ { "dad", "ZGFk" },
+ { "dam", "ZGFt" },
+ { "Dan", "RGFu" },
+ { "Dar", "RGFy" },
+ { "day", "ZGF5" },
+ { "Dec", "RGVj" },
+ { "Dee", "RGVl" },
+ { "Del", "RGVs" },
+ { "den", "ZGVu" },
+ { "Des", "RGVz" },
+ { "dew", "ZGV3" },
+ { "dey", "ZGV5" },
+ { "did", "ZGlk" },
+ { "die", "ZGll" },
+ { "dig", "ZGln" },
+ { "dim", "ZGlt" },
+ { "din", "ZGlu" },
+ { "dip", "ZGlw" },
+ { "Dis", "RGlz" },
+ { "DNA", "RE5B" },
+ { "DOD", "RE9E" },
+ { "doe", "ZG9l" },
+ { "dog", "ZG9n" },
+ { "don", "ZG9u" },
+ { "dot", "ZG90" },
+ { "Dow", "RG93" },
+ { "dry", "ZHJ5" },
+ { "d's", "ZCdz" },
+ { "dub", "ZHVi" },
+ { "dud", "ZHVk" },
+ { "due", "ZHVl" },
+ { "dug", "ZHVn" },
+ { "dun", "ZHVu" },
+ { "dye", "ZHll" },
+ { "ear", "ZWFy" },
+ { "eat", "ZWF0" },
+ { "ebb", "ZWJi" },
+ { "EDT", "RURU" },
+ { "eel", "ZWVs" },
+ { "eft", "ZWZ0" },
+ { "e.g", "ZS5n" },
+ { "egg", "ZWdn" },
+ { "ego", "ZWdv" },
+ { "eke", "ZWtl" },
+ { "Eli", "RWxp" },
+ { "elk", "ZWxr" },
+ { "ell", "ZWxs" },
+ { "elm", "ZWxt" },
+ { "Ely", "RWx5" },
+ { "end", "ZW5k" },
+ { "Eng", "RW5n" },
+ { "EPA", "RVBB" },
+ { "era", "ZXJh" },
+ { "ere", "ZXJl" },
+ { "erg", "ZXJn" },
+ { "err", "ZXJy" },
+ { "e's", "ZSdz" },
+ { "EST", "RVNU" },
+ { "eta", "ZXRh" },
+ { "etc", "ZXRj" },
+ { "Eva", "RXZh" },
+ { "eve", "ZXZl" },
+ { "ewe", "ZXdl" },
+ { "eye", "ZXll" },
+ { "FAA", "RkFB" },
+ { "fad", "ZmFk" },
+ { "fag", "ZmFn" },
+ { "fan", "ZmFu" },
+ { "far", "ZmFy" },
+ { "fat", "ZmF0" },
+ { "fay", "ZmF5" },
+ { "FBI", "RkJJ" },
+ { "FCC", "RkND" },
+ { "FDA", "RkRB" },
+ { "Feb", "RmVi" },
+ { "fed", "ZmVk" },
+ { "fee", "ZmVl" },
+ { "few", "ZmV3" },
+ { "fib", "Zmli" },
+ { "fig", "Zmln" },
+ { "fin", "Zmlu" },
+ { "fir", "Zmly" },
+ { "fit", "Zml0" },
+ { "fix", "Zml4" },
+ { "Flo", "Rmxv" },
+ { "flu", "Zmx1" },
+ { "fly", "Zmx5" },
+ { "FMC", "Rk1D" },
+ { "fob", "Zm9i" },
+ { "foe", "Zm9l" },
+ { "fog", "Zm9n" },
+ { "fop", "Zm9w" },
+ { "for", "Zm9y" },
+ { "fox", "Zm94" },
+ { "FPC", "RlBD" },
+ { "fro", "ZnJv" },
+ { "fry", "ZnJ5" },
+ { "f's", "Zidz" },
+ { "FTC", "RlRD" },
+ { "fum", "ZnVt" },
+ { "fun", "ZnVu" },
+ { "fur", "ZnVy" },
+ { "gab", "Z2Fi" },
+ { "gad", "Z2Fk" },
+ { "gag", "Z2Fn" },
+ { "gal", "Z2Fs" },
+ { "gam", "Z2Ft" },
+ { "GAO", "R0FP" },
+ { "gap", "Z2Fw" },
+ { "gar", "Z2Fy" },
+ { "gas", "Z2Fz" },
+ { "gay", "Z2F5" },
+ { "gee", "Z2Vl" },
+ { "gel", "Z2Vs" },
+ { "gem", "Z2Vt" },
+ { "get", "Z2V0" },
+ { "gig", "Z2ln" },
+ { "Gil", "R2ls" },
+ { "gin", "Z2lu" },
+ { "GMT", "R01U" },
+ { "GNP", "R05Q" },
+ { "gnu", "Z251" },
+ { "Goa", "R29h" },
+ { "gob", "Z29i" },
+ { "god", "Z29k" },
+ { "gog", "Z29n" },
+ { "GOP", "R09Q" },
+ { "got", "Z290" },
+ { "GPO", "R1BP" },
+ { "g's", "Zydz" },
+ { "GSA", "R1NB" },
+ { "gum", "Z3Vt" },
+ { "gun", "Z3Vu" },
+ { "Gus", "R3Vz" },
+ { "gut", "Z3V0" },
+ { "guy", "Z3V5" },
+ { "gym", "Z3lt" },
+ { "gyp", "Z3lw" },
+ { "had", "aGFk" },
+ { "Hal", "SGFs" },
+ { "ham", "aGFt" },
+ { "Han", "SGFu" },
+ { "hap", "aGFw" },
+ { "hat", "aGF0" },
+ { "haw", "aGF3" },
+ { "hay", "aGF5" },
+ { "hem", "aGVt" },
+ { "hen", "aGVu" },
+ { "her", "aGVy" },
+ { "hew", "aGV3" },
+ { "hex", "aGV4" },
+ { "hey", "aGV5" },
+ { "hid", "aGlk" },
+ { "him", "aGlt" },
+ { "hip", "aGlw" },
+ { "his", "aGlz" },
+ { "hit", "aGl0" },
+ { "hob", "aG9i" },
+ { "hoc", "aG9j" },
+ { "hoe", "aG9l" },
+ { "hog", "aG9n" },
+ { "hoi", "aG9p" },
+ { "Hom", "SG9t" },
+ { "hop", "aG9w" },
+ { "hot", "aG90" },
+ { "how", "aG93" },
+ { "hoy", "aG95" },
+ { "h's", "aCdz" },
+ { "hub", "aHVi" },
+ { "hue", "aHVl" },
+ { "hug", "aHVn" },
+ { "huh", "aHVo" },
+ { "hum", "aHVt" },
+ { "Hun", "SHVu" },
+ { "hut", "aHV0" },
+ { "Ian", "SWFu" },
+ { "IBM", "SUJN" },
+ { "Ibn", "SWJu" },
+ { "ICC", "SUND" },
+ { "ice", "aWNl" },
+ { "icy", "aWN5" },
+ { "I'd", "SSdk" },
+ { "Ida", "SWRh" },
+ { "i.e", "aS5l" },
+ { "iii", "aWlp" },
+ { "Ike", "SWtl" },
+ { "ill", "aWxs" },
+ { "I'm", "SSdt" },
+ { "imp", "aW1w" },
+ { "Inc", "SW5j" },
+ { "ink", "aW5r" },
+ { "inn", "aW5u" },
+ { "ion", "aW9u" },
+ { "Ira", "SXJh" },
+ { "ire", "aXJl" },
+ { "irk", "aXJr" },
+ { "IRS", "SVJT" },
+ { "i's", "aSdz" },
+ { "Ito", "SXRv" },
+ { "ITT", "SVRU" },
+ { "ivy", "aXZ5" },
+ { "jab", "amFi" },
+ { "jag", "amFn" },
+ { "jam", "amFt" },
+ { "Jan", "SmFu" },
+ { "jar", "amFy" },
+ { "jaw", "amF3" },
+ { "jay", "amF5" },
+ { "Jed", "SmVk" },
+ { "jet", "amV0" },
+ { "Jew", "SmV3" },
+ { "jig", "amln" },
+ { "Jim", "Smlt" },
+ { "job", "am9i" },
+ { "Joe", "Sm9l" },
+ { "jog", "am9n" },
+ { "Jon", "Sm9u" },
+ { "jot", "am90" },
+ { "joy", "am95" },
+ { "j's", "aidz" },
+ { "jug", "anVn" },
+ { "jut", "anV0" },
+ { "Kay", "S2F5" },
+ { "keg", "a2Vn" },
+ { "ken", "a2Vu" },
+ { "key", "a2V5" },
+ { "kid", "a2lk" },
+ { "Kim", "S2lt" },
+ { "kin", "a2lu" },
+ { "kit", "a2l0" },
+ { "k's", "aydz" },
+ { "lab", "bGFi" },
+ { "lac", "bGFj" },
+ { "lad", "bGFk" },
+ { "lag", "bGFn" },
+ { "lam", "bGFt" },
+ { "Lao", "TGFv" },
+ { "lap", "bGFw" },
+ { "law", "bGF3" },
+ { "lax", "bGF4" },
+ { "lay", "bGF5" },
+ { "lea", "bGVh" },
+ { "led", "bGVk" },
+ { "lee", "bGVl" },
+ { "leg", "bGVn" },
+ { "Len", "TGVu" },
+ { "Leo", "TGVv" },
+ { "let", "bGV0" },
+ { "Lev", "TGV2" },
+ { "Lew", "TGV3" },
+ { "lew", "bGV3" },
+ { "lid", "bGlk" },
+ { "lie", "bGll" },
+ { "lim", "bGlt" },
+ { "Lin", "TGlu" },
+ { "lip", "bGlw" },
+ { "lit", "bGl0" },
+ { "Liz", "TGl6" },
+ { "lob", "bG9i" },
+ { "log", "bG9n" },
+ { "lop", "bG9w" },
+ { "Los", "TG9z" },
+ { "lot", "bG90" },
+ { "Lou", "TG91" },
+ { "low", "bG93" },
+ { "loy", "bG95" },
+ { "l's", "bCdz" },
+ { "LSI", "TFNJ" },
+ { "Ltd", "THRk" },
+ { "LTV", "TFRW" },
+ { "lug", "bHVn" },
+ { "lux", "bHV4" },
+ { "lye", "bHll" },
+ { "Mac", "TWFj" },
+ { "mad", "bWFk" },
+ { "Mae", "TWFl" },
+ { "man", "bWFu" },
+ { "Mao", "TWFv" },
+ { "map", "bWFw" },
+ { "mar", "bWFy" },
+ { "mat", "bWF0" },
+ { "maw", "bWF3" },
+ { "Max", "TWF4" },
+ { "max", "bWF4" },
+ { "may", "bWF5" },
+ { "MBA", "TUJB" },
+ { "Meg", "TWVn" },
+ { "Mel", "TWVs" },
+ { "men", "bWVu" },
+ { "met", "bWV0" },
+ { "mew", "bWV3" },
+ { "mid", "bWlk" },
+ { "mig", "bWln" },
+ { "min", "bWlu" },
+ { "MIT", "TUlU" },
+ { "mix", "bWl4" },
+ { "mob", "bW9i" },
+ { "Moe", "TW9l" },
+ { "moo", "bW9v" },
+ { "mop", "bW9w" },
+ { "mot", "bW90" },
+ { "mow", "bW93" },
+ { "MPH", "TVBI" },
+ { "Mrs", "TXJz" },
+ { "m's", "bSdz" },
+ { "mud", "bXVk" },
+ { "mug", "bXVn" },
+ { "mum", "bXVt" },
+ { "nab", "bmFi" },
+ { "nag", "bmFn" },
+ { "Nan", "TmFu" },
+ { "nap", "bmFw" },
+ { "Nat", "TmF0" },
+ { "nay", "bmF5" },
+ { "NBC", "TkJD" },
+ { "NBS", "TkJT" },
+ { "NCO", "TkNP" },
+ { "NCR", "TkNS" },
+ { "Ned", "TmVk" },
+ { "nee", "bmVl" },
+ { "net", "bmV0" },
+ { "new", "bmV3" },
+ { "nib", "bmli" },
+ { "NIH", "TklI" },
+ { "nil", "bmls" },
+ { "nip", "bmlw" },
+ { "nit", "bml0" },
+ { "NNE", "Tk5F" },
+ { "NNW", "Tk5X" },
+ { "nob", "bm9i" },
+ { "nod", "bm9k" },
+ { "non", "bm9u" },
+ { "nor", "bm9y" },
+ { "not", "bm90" },
+ { "Nov", "Tm92" },
+ { "now", "bm93" },
+ { "NRC", "TlJD" },
+ { "n's", "bidz" },
+ { "NSF", "TlNG" },
+ { "nun", "bnVu" },
+ { "nut", "bnV0" },
+ { "NYC", "TllD" },
+ { "NYU", "TllV" },
+ { "oaf", "b2Fm" },
+ { "oak", "b2Fr" },
+ { "oar", "b2Fy" },
+ { "oat", "b2F0" },
+ { "Oct", "T2N0" },
+ { "odd", "b2Rk" },
+ { "ode", "b2Rl" },
+ { "off", "b2Zm" },
+ { "oft", "b2Z0" },
+ { "ohm", "b2ht" },
+ { "oil", "b2ls" },
+ { "old", "b2xk" },
+ { "one", "b25l" },
+ { "opt", "b3B0" },
+ { "orb", "b3Ji" },
+ { "ore", "b3Jl" },
+ { "Orr", "T3Jy" },
+ { "o's", "bydz" },
+ { "Ott", "T3R0" },
+ { "our", "b3Vy" },
+ { "out", "b3V0" },
+ { "ova", "b3Zh" },
+ { "owe", "b3dl" },
+ { "owl", "b3ds" },
+ { "own", "b3du" },
+ { "pad", "cGFk" },
+ { "pal", "cGFs" },
+ { "Pam", "UGFt" },
+ { "pan", "cGFu" },
+ { "pap", "cGFw" },
+ { "par", "cGFy" },
+ { "pat", "cGF0" },
+ { "paw", "cGF3" },
+ { "pax", "cGF4" },
+ { "pay", "cGF5" },
+ { "Paz", "UGF6" },
+ { "PBS", "UEJT" },
+ { "PDP", "UERQ" },
+ { "pea", "cGVh" },
+ { "pee", "cGVl" },
+ { "peg", "cGVn" },
+ { "pen", "cGVu" },
+ { "pep", "cGVw" },
+ { "per", "cGVy" },
+ { "pet", "cGV0" },
+ { "pew", "cGV3" },
+ { "PhD", "UGhE" },
+ { "phi", "cGhp" },
+ { "pie", "cGll" },
+ { "pig", "cGln" },
+ { "pin", "cGlu" },
+ { "pip", "cGlw" },
+ { "pit", "cGl0" },
+ { "ply", "cGx5" },
+ { "pod", "cG9k" },
+ { "Poe", "UG9l" },
+ { "poi", "cG9p" },
+ { "pol", "cG9s" },
+ { "pop", "cG9w" },
+ { "pot", "cG90" },
+ { "pow", "cG93" },
+ { "ppm", "cHBt" },
+ { "pro", "cHJv" },
+ { "pry", "cHJ5" },
+ { "p's", "cCdz" },
+ { "psi", "cHNp" },
+ { "PTA", "UFRB" },
+ { "pub", "cHVi" },
+ { "PUC", "UFVD" },
+ { "pug", "cHVn" },
+ { "pun", "cHVu" },
+ { "pup", "cHVw" },
+ { "pus", "cHVz" },
+ { "put", "cHV0" },
+ { "PVC", "UFZD" },
+ { "QED", "UUVE" },
+ { "q's", "cSdz" },
+ { "qua", "cXVh" },
+ { "quo", "cXVv" },
+ { "Rae", "UmFl" },
+ { "rag", "cmFn" },
+ { "raj", "cmFq" },
+ { "ram", "cmFt" },
+ { "ran", "cmFu" },
+ { "rap", "cmFw" },
+ { "rat", "cmF0" },
+ { "raw", "cmF3" },
+ { "ray", "cmF5" },
+ { "RCA", "UkNB" },
+ { "R&D", "UiZE" },
+ { "reb", "cmVi" },
+ { "red", "cmVk" },
+ { "rep", "cmVw" },
+ { "ret", "cmV0" },
+ { "rev", "cmV2" },
+ { "Rex", "UmV4" },
+ { "rho", "cmhv" },
+ { "rib", "cmli" },
+ { "rid", "cmlk" },
+ { "rig", "cmln" },
+ { "rim", "cmlt" },
+ { "Rio", "Umlv" },
+ { "rip", "cmlw" },
+ { "RNA", "Uk5B" },
+ { "rob", "cm9i" },
+ { "rod", "cm9k" },
+ { "roe", "cm9l" },
+ { "Ron", "Um9u" },
+ { "rot", "cm90" },
+ { "row", "cm93" },
+ { "Roy", "Um95" },
+ { "RPM", "UlBN" },
+ { "r's", "cidz" },
+ { "rub", "cnVi" },
+ { "rue", "cnVl" },
+ { "rug", "cnVn" },
+ { "rum", "cnVt" },
+ { "run", "cnVu" },
+ { "rut", "cnV0" },
+ { "rye", "cnll" },
+ { "sac", "c2Fj" },
+ { "sad", "c2Fk" },
+ { "sag", "c2Fn" },
+ { "Sal", "U2Fs" },
+ { "Sam", "U2Ft" },
+ { "San", "U2Fu" },
+ { "Sao", "U2Fv" },
+ { "sap", "c2Fw" },
+ { "sat", "c2F0" },
+ { "saw", "c2F3" },
+ { "sax", "c2F4" },
+ { "say", "c2F5" },
+ { "Sci", "U2Np" },
+ { "SCM", "U0NN" },
+ { "sea", "c2Vh" },
+ { "sec", "c2Vj" },
+ { "see", "c2Vl" },
+ { "sen", "c2Vu" },
+ { "seq", "c2Vx" },
+ { "set", "c2V0" },
+ { "sew", "c2V3" },
+ { "sex", "c2V4" },
+ { "she", "c2hl" },
+ { "Shu", "U2h1" },
+ { "shy", "c2h5" },
+ { "sib", "c2li" },
+ { "sic", "c2lj" },
+ { "sin", "c2lu" },
+ { "sip", "c2lw" },
+ { "sir", "c2ly" },
+ { "sis", "c2lz" },
+ { "sit", "c2l0" },
+ { "six", "c2l4" },
+ { "ski", "c2tp" },
+ { "sky", "c2t5" },
+ { "sly", "c2x5" },
+ { "sob", "c29i" },
+ { "Soc", "U29j" },
+ { "sod", "c29k" },
+ { "Sol", "U29s" },
+ { "son", "c29u" },
+ { "sop", "c29w" },
+ { "sou", "c291" },
+ { "sow", "c293" },
+ { "soy", "c295" },
+ { "spa", "c3Bh" },
+ { "spy", "c3B5" },
+ { "Sri", "U3Jp" },
+ { "s's", "cydz" },
+ { "SSE", "U1NF" },
+ { "SST", "U1NU" },
+ { "SSW", "U1NX" },
+ { "Stu", "U3R1" },
+ { "sub", "c3Vi" },
+ { "sud", "c3Vk" },
+ { "sue", "c3Vl" },
+ { "sum", "c3Vt" },
+ { "sun", "c3Vu" },
+ { "sup", "c3Vw" },
+ { "Sus", "U3Vz" },
+ { "tab", "dGFi" },
+ { "tad", "dGFk" },
+ { "tag", "dGFn" },
+ { "tam", "dGFt" },
+ { "tan", "dGFu" },
+ { "tao", "dGFv" },
+ { "tap", "dGFw" },
+ { "tar", "dGFy" },
+ { "tat", "dGF0" },
+ { "tau", "dGF1" },
+ { "tax", "dGF4" },
+ { "tea", "dGVh" },
+ { "Ted", "VGVk" },
+ { "ted", "dGVk" },
+ { "tee", "dGVl" },
+ { "Tel", "VGVs" },
+ { "ten", "dGVu" },
+ { "the", "dGhl" },
+ { "thy", "dGh5" },
+ { "tic", "dGlj" },
+ { "tid", "dGlk" },
+ { "tie", "dGll" },
+ { "til", "dGls" },
+ { "Tim", "VGlt" },
+ { "tin", "dGlu" },
+ { "tip", "dGlw" },
+ { "tit", "dGl0" },
+ { "TNT", "VE5U" },
+ { "toe", "dG9l" },
+ { "tog", "dG9n" },
+ { "Tom", "VG9t" },
+ { "ton", "dG9u" },
+ { "too", "dG9v" },
+ { "top", "dG9w" },
+ { "tor", "dG9y" },
+ { "tot", "dG90" },
+ { "tow", "dG93" },
+ { "toy", "dG95" },
+ { "TRW", "VFJX" },
+ { "try", "dHJ5" },
+ { "t's", "dCdz" },
+ { "TTL", "VFRM" },
+ { "TTY", "VFRZ" },
+ { "tub", "dHVi" },
+ { "tug", "dHVn" },
+ { "tum", "dHVt" },
+ { "tun", "dHVu" },
+ { "TVA", "VFZB" },
+ { "TWA", "VFdB" },
+ { "two", "dHdv" },
+ { "TWX", "VFdY" },
+ { "ugh", "dWdo" },
+ { "UHF", "VUhG" },
+ { "Uri", "VXJp" },
+ { "urn", "dXJu" },
+ { "U.S", "VS5T" },
+ { "u's", "dSdz" },
+ { "USA", "VVNB" },
+ { "USC", "VVND" },
+ { "use", "dXNl" },
+ { "USN", "VVNO" },
+ { "van", "dmFu" },
+ { "vat", "dmF0" },
+ { "vee", "dmVl" },
+ { "vet", "dmV0" },
+ { "vex", "dmV4" },
+ { "VHF", "VkhG" },
+ { "via", "dmlh" },
+ { "vie", "dmll" },
+ { "vii", "dmlp" },
+ { "vis", "dmlz" },
+ { "viz", "dml6" },
+ { "von", "dm9u" },
+ { "vow", "dm93" },
+ { "v's", "didz" },
+ { "WAC", "V0FD" },
+ { "wad", "d2Fk" },
+ { "wag", "d2Fn" },
+ { "wah", "d2Fo" },
+ { "wan", "d2Fu" },
+ { "war", "d2Fy" },
+ { "was", "d2Fz" },
+ { "wax", "d2F4" },
+ { "way", "d2F5" },
+ { "web", "d2Vi" },
+ { "wed", "d2Vk" },
+ { "wee", "d2Vl" },
+ { "Wei", "V2Vp" },
+ { "wet", "d2V0" },
+ { "who", "d2hv" },
+ { "why", "d2h5" },
+ { "wig", "d2ln" },
+ { "win", "d2lu" },
+ { "wit", "d2l0" },
+ { "woe", "d29l" },
+ { "wok", "d29r" },
+ { "won", "d29u" },
+ { "woo", "d29v" },
+ { "wop", "d29w" },
+ { "wow", "d293" },
+ { "wry", "d3J5" },
+ { "w's", "dydz" },
+ { "x's", "eCdz" },
+ { "yah", "eWFo" },
+ { "yak", "eWFr" },
+ { "yam", "eWFt" },
+ { "yap", "eWFw" },
+ { "yaw", "eWF3" },
+ { "yea", "eWVh" },
+ { "yen", "eWVu" },
+ { "yet", "eWV0" },
+ { "yin", "eWlu" },
+ { "yip", "eWlw" },
+ { "yon", "eW9u" },
+ { "you", "eW91" },
+ { "yow", "eW93" },
+ { "y's", "eSdz" },
+ { "yuh", "eXVo" },
+ { "zag", "emFn" },
+ { "Zan", "WmFu" },
+ { "zap", "emFw" },
+ { "Zen", "WmVu" },
+ { "zig", "emln" },
+ { "zip", "emlw" },
+ { "Zoe", "Wm9l" },
+ { "zoo", "em9v" },
+ { "z's", "eidz" },
+ /* the false rumors file */
+ { "\"So when I die, the first thing I will see in heaven is a score list?\"",
+ "IlNvIHdoZW4gSSBkaWUsIHRoZSBmaXJzdCB0aGluZyBJIHdpbGwgc2VlIGluIGhlYXZlbiBpcyBhIHNjb3JlIGxpc3Q/Ig==" },
+ { "1st Law of Hacking: leaving is much more difficult than entering.",
+ "MXN0IExhdyBvZiBIYWNraW5nOiBsZWF2aW5nIGlzIG11Y2ggbW9yZSBkaWZmaWN1bHQgdGhhbiBlbnRlcmluZy4=" },
+ { "2nd Law of Hacking: first in, first out.",
+ "Mm5kIExhdyBvZiBIYWNraW5nOiBmaXJzdCBpbiwgZmlyc3Qgb3V0Lg==" },
+ { "3rd Law of Hacking: the last blow counts most.",
+ "M3JkIExhdyBvZiBIYWNraW5nOiB0aGUgbGFzdCBibG93IGNvdW50cyBtb3N0Lg==" },
+ { "4th Law of Hacking: you will find the exit at the entrance.",
+ "NHRoIExhdyBvZiBIYWNraW5nOiB5b3Ugd2lsbCBmaW5kIHRoZSBleGl0IGF0IHRoZSBlbnRyYW5jZS4=" },
+ { "A chameleon imitating a mail daemon often delivers scrolls of fire.",
+ "QSBjaGFtZWxlb24gaW1pdGF0aW5nIGEgbWFpbCBkYWVtb24gb2Z0ZW4gZGVsaXZlcnMgc2Nyb2xscyBvZiBmaXJlLg==" },
+ { "A cockatrice corpse is guaranteed to be untainted!",
+ "QSBjb2NrYXRyaWNlIGNvcnBzZSBpcyBndWFyYW50ZWVkIHRvIGJlIHVudGFpbnRlZCE=" },
+ { "A dead cockatrice is just a dead lizard.",
+ "QSBkZWFkIGNvY2thdHJpY2UgaXMganVzdCBhIGRlYWQgbGl6YXJkLg==" },
+ { "A dragon is just a snake that ate a scroll of fire.",
+ "QSBkcmFnb24gaXMganVzdCBhIHNuYWtlIHRoYXQgYXRlIGEgc2Nyb2xsIG9mIGZpcmUu" },
+ { "A fading corridor enlightens your insight.",
+ "QSBmYWRpbmcgY29ycmlkb3IgZW5saWdodGVucyB5b3VyIGluc2lnaHQu" },
+ { "A glowing potion is too hot to drink.",
+ "QSBnbG93aW5nIHBvdGlvbiBpcyB0b28gaG90IHRvIGRyaW5rLg==" },
+ { "A good amulet may protect you against guards.",
+ "QSBnb29kIGFtdWxldCBtYXkgcHJvdGVjdCB5b3UgYWdhaW5zdCBndWFyZHMu" },
+ { "A lizard corpse is a good thing to turn undead.",
+ "QSBsaXphcmQgY29ycHNlIGlzIGEgZ29vZCB0aGluZyB0byB0dXJuIHVuZGVhZC4=" },
+ { "A long worm can be defined recursively. So how should you attack it?",
+ "QSBsb25nIHdvcm0gY2FuIGJlIGRlZmluZWQgcmVjdXJzaXZlbHkuIFNvIGhvdyBzaG91bGQgeW91IGF0dGFjayBpdD8=" },
+ { "A monstrous mind is a toy forever.",
+ "QSBtb25zdHJvdXMgbWluZCBpcyBhIHRveSBmb3JldmVyLg==" },
+ { "A nymph will be very pleased if you call her by her real name: Lorelei.",
+ "QSBueW1waCB3aWxsIGJlIHZlcnkgcGxlYXNlZCBpZiB5b3UgY2FsbCBoZXIgYnkgaGVyIHJlYWwgbmFtZTogTG9yZWxlaS4=" },
+ { "A ring of dungeon master control is a great find.",
+ "QSByaW5nIG9mIGR1bmdlb24gbWFzdGVyIGNvbnRyb2wgaXMgYSBncmVhdCBmaW5kLg==" },
+ { "A ring of extra ring finger is useless if not enchanted.",
+ "QSByaW5nIG9mIGV4dHJhIHJpbmcgZmluZ2VyIGlzIHVzZWxlc3MgaWYgbm90IGVuY2hhbnRlZC4=" },
+ { "A rope may form a trail in a maze.",
+ "QSByb3BlIG1heSBmb3JtIGEgdHJhaWwgaW4gYSBtYXplLg==" },
+ { "A staff may recharge if you drop it for awhile.",
+ "QSBzdGFmZiBtYXkgcmVjaGFyZ2UgaWYgeW91IGRyb3AgaXQgZm9yIGF3aGlsZS4=" },
+ { "A visit to the Zoo is very educational; you meet interesting animals.",
+ "QSB2aXNpdCB0byB0aGUgWm9vIGlzIHZlcnkgZWR1Y2F0aW9uYWw7IHlvdSBtZWV0IGludGVyZXN0aW5nIGFuaW1hbHMu" },
+ { "A wand of deaf is a more dangerous weapon than a wand of sheep.",
+ "QSB3YW5kIG9mIGRlYWYgaXMgYSBtb3JlIGRhbmdlcm91cyB3ZWFwb24gdGhhbiBhIHdhbmQgb2Ygc2hlZXAu" },
+ { "A wand of vibration might bring the whole cave crashing about your ears.",
+ "QSB3YW5kIG9mIHZpYnJhdGlvbiBtaWdodCBicmluZyB0aGUgd2hvbGUgY2F2ZSBjcmFzaGluZyBhYm91dCB5b3VyIGVhcnMu" },
+ { "A winner never quits. A quitter never wins.",
+ "QSB3aW5uZXIgbmV2ZXIgcXVpdHMuIEEgcXVpdHRlciBuZXZlciB3aW5zLg==" },
+ { "A wish? Okay, make me a fortune cookie!",
+ "QSB3aXNoPyBPa2F5LCBtYWtlIG1lIGEgZm9ydHVuZSBjb29raWUh" },
+ { "Afraid of mimics? Try to wear a ring of true seeing.",
+ "QWZyYWlkIG9mIG1pbWljcz8gVHJ5IHRvIHdlYXIgYSByaW5nIG9mIHRydWUgc2VlaW5nLg==" },
+ { "All monsters are created evil, but some are more evil than others.",
+ "QWxsIG1vbnN0ZXJzIGFyZSBjcmVhdGVkIGV2aWwsIGJ1dCBzb21lIGFyZSBtb3JlIGV2aWwgdGhhbiBvdGhlcnMu" },
+ { "Always attack a floating eye from behind!",
+ "QWx3YXlzIGF0dGFjayBhIGZsb2F0aW5nIGV5ZSBmcm9tIGJlaGluZCE=" },
+ { "An elven cloak is always the height of fashion.",
+ "QW4gZWx2ZW4gY2xvYWsgaXMgYWx3YXlzIHRoZSBoZWlnaHQgb2YgZmFzaGlvbi4=" },
+ { "Any small object that is accidentally dropped will hide under a larger object.",
+ "QW55IHNtYWxsIG9iamVjdCB0aGF0IGlzIGFjY2lkZW50YWxseSBkcm9wcGVkIHdpbGwgaGlkZSB1bmRlciBhIGxhcmdlciBvYmplY3Qu" },
+ { "Balrogs do not appear above level 20.",
+ "QmFscm9ncyBkbyBub3QgYXBwZWFyIGFib3ZlIGxldmVsIDIwLg==" },
+ { "Banana peels work especially well against Keystone Kops.",
+ "QmFuYW5hIHBlZWxzIHdvcmsgZXNwZWNpYWxseSB3ZWxsIGFnYWluc3QgS2V5c3RvbmUgS29wcy4=" },
+ { "Be careful when eating bananas. Monsters might slip on the peels.",
+ "QmUgY2FyZWZ1bCB3aGVuIGVhdGluZyBiYW5hbmFzLiBNb25zdGVycyBtaWdodCBzbGlwIG9uIHRoZSBwZWVscy4=" },
+ { "Better leave the dungeon; otherwise you might get hurt badly.",
+ "QmV0dGVyIGxlYXZlIHRoZSBkdW5nZW9uOyBvdGhlcndpc2UgeW91IG1pZ2h0IGdldCBodXJ0IGJhZGx5Lg==" },
+ { "Beware of the potion of nitroglycerin -- it's not for the weak of heart.",
+ "QmV3YXJlIG9mIHRoZSBwb3Rpb24gb2Ygbml0cm9nbHljZXJpbiAtLSBpdCdzIG5vdCBmb3IgdGhlIHdlYWsgb2YgaGVhcnQu" },
+ { "Beware: there's always a chance that your wand explodes as you try to zap it!",
+ "QmV3YXJlOiB0aGVyZSdzIGFsd2F5cyBhIGNoYW5jZSB0aGF0IHlvdXIgd2FuZCBleHBsb2RlcyBhcyB5b3UgdHJ5IHRvIHphcCBpdCE=" },
+ { "Beyond the 23rd level lies a happy retirement in a room of your own.",
+ "QmV5b25kIHRoZSAyM3JkIGxldmVsIGxpZXMgYSBoYXBweSByZXRpcmVtZW50IGluIGEgcm9vbSBvZiB5b3VyIG93bi4=" },
+ { "Changing your suit without dropping your sword? You must be kidding!",
+ "Q2hhbmdpbmcgeW91ciBzdWl0IHdpdGhvdXQgZHJvcHBpbmcgeW91ciBzd29yZD8gWW91IG11c3QgYmUga2lkZGluZyE=" },
+ { "Cockatrices might turn themselves to stone faced with a mirror.",
+ "Q29ja2F0cmljZXMgbWlnaHQgdHVybiB0aGVtc2VsdmVzIHRvIHN0b25lIGZhY2VkIHdpdGggYSBtaXJyb3Iu" },
+ { "Consumption of home-made food is strictly forbidden in this dungeon.",
+ "Q29uc3VtcHRpb24gb2YgaG9tZS1tYWRlIGZvb2QgaXMgc3RyaWN0bHkgZm9yYmlkZGVuIGluIHRoaXMgZHVuZ2Vvbi4=" },
+ { "Dark room? Your chance to develop your photographs!",
+ "RGFyayByb29tPyBZb3VyIGNoYW5jZSB0byBkZXZlbG9wIHlvdXIgcGhvdG9ncmFwaHMh" },
+ { "Dark rooms are not *completely* dark: just wait and let your eyes adjust...",
+ "RGFyayByb29tcyBhcmUgbm90ICpjb21wbGV0ZWx5KiBkYXJrOiBqdXN0IHdhaXQgYW5kIGxldCB5b3VyIGV5ZXMgYWRqdXN0Li4u" },
+ { "David London sez, \"Hey guys, *WIELD* a lizard corpse against a cockatrice!\"",
+ "RGF2aWQgTG9uZG9uIHNleiwgIkhleSBndXlzLCAqV0lFTEQqIGEgbGl6YXJkIGNvcnBzZSBhZ2FpbnN0IGEgY29ja2F0cmljZSEi" },
+ { "Death is just life's way of telling you you've been fired.",
+ "RGVhdGggaXMganVzdCBsaWZlJ3Mgd2F5IG9mIHRlbGxpbmcgeW91IHlvdSd2ZSBiZWVuIGZpcmVkLg==" },
+ { "Demi-gods don't need any help from the gods.",
+ "RGVtaS1nb2RzIGRvbid0IG5lZWQgYW55IGhlbHAgZnJvbSB0aGUgZ29kcy4=" },
+ { "Demons *HATE* Priests and Priestesses.",
+ "RGVtb25zICpIQVRFKiBQcmllc3RzIGFuZCBQcmllc3Rlc3Nlcy4=" },
+ { "Didn't you forget to pay?",
+ "RGlkbid0IHlvdSBmb3JnZXQgdG8gcGF5Pw==" },
+ { "Didn't your mother tell you not to eat food off the floor?",
+ "RGlkbid0IHlvdXIgbW90aGVyIHRlbGwgeW91IG5vdCB0byBlYXQgZm9vZCBvZmYgdGhlIGZsb29yPw==" },
+ { "Direct a direct hit on your direct opponent, directing in the right direction.",
+ "RGlyZWN0IGEgZGlyZWN0IGhpdCBvbiB5b3VyIGRpcmVjdCBvcHBvbmVudCwgZGlyZWN0aW5nIGluIHRoZSByaWdodCBkaXJlY3Rpb24u" },
+ { "Do you want to make more money? Sure, we all do! Join the Fort Ludios guard!",
+ "RG8geW91IHdhbnQgdG8gbWFrZSBtb3JlIG1vbmV5PyBTdXJlLCB3ZSBhbGwgZG8hIEpvaW4gdGhlIEZvcnQgTHVkaW9zIGd1YXJkIQ==" },
+ { "Don't eat too much: you might start hiccoughing!",
+ "RG9uJ3QgZWF0IHRvbyBtdWNoOiB5b3UgbWlnaHQgc3RhcnQgaGljY291Z2hpbmch" },
+ { "Don't play hack at your work; your boss might hit you!",
+ "RG9uJ3QgcGxheSBoYWNrIGF0IHlvdXIgd29yazsgeW91ciBib3NzIG1pZ2h0IGhpdCB5b3Uh" },
+ { "Don't tell a soul you found a secret door, otherwise it isn't a secret anymore.",
+ "RG9uJ3QgdGVsbCBhIHNvdWwgeW91IGZvdW5kIGEgc2VjcmV0IGRvb3IsIG90aGVyd2lzZSBpdCBpc24ndCBhIHNlY3JldCBhbnltb3JlLg==" },
+ { "Drinking potions of booze may land you in jail if you are under 21.",
+ "RHJpbmtpbmcgcG90aW9ucyBvZiBib296ZSBtYXkgbGFuZCB5b3UgaW4gamFpbCBpZiB5b3UgYXJlIHVuZGVyIDIxLg==" },
+ { "Drop your vanity and get rid of your jewels! Pickpockets about!",
+ "RHJvcCB5b3VyIHZhbml0eSBhbmQgZ2V0IHJpZCBvZiB5b3VyIGpld2VscyEgUGlja3BvY2tldHMgYWJvdXQh" },
+ { "Eat 10 cloves of garlic and keep all humans at a two-square distance.",
+ "RWF0IDEwIGNsb3ZlcyBvZiBnYXJsaWMgYW5kIGtlZXAgYWxsIGh1bWFucyBhdCBhIHR3by1zcXVhcmUgZGlzdGFuY2Uu" },
+ { "Eels hide under mud. Use a unicorn to clear the water and make them visible.",
+ "RWVscyBoaWRlIHVuZGVyIG11ZC4gVXNlIGEgdW5pY29ybiB0byBjbGVhciB0aGUgd2F0ZXIgYW5kIG1ha2UgdGhlbSB2aXNpYmxlLg==" },
+ { "Engrave your wishes with a wand of wishing.",
+ "RW5ncmF2ZSB5b3VyIHdpc2hlcyB3aXRoIGEgd2FuZCBvZiB3aXNoaW5nLg==" },
+ { "Eventually you will come to admire the swift elegance of a retreating nymph.",
+ "RXZlbnR1YWxseSB5b3Ugd2lsbCBjb21lIHRvIGFkbWlyZSB0aGUgc3dpZnQgZWxlZ2FuY2Ugb2YgYSByZXRyZWF0aW5nIG55bXBoLg==" },
+ { "Ever heard hissing outside? I *knew* you hadn't!",
+ "RXZlciBoZWFyZCBoaXNzaW5nIG91dHNpZGU/IEkgKmtuZXcqIHlvdSBoYWRuJ3Qh" },
+ { "Ever lifted a dragon corpse?",
+ "RXZlciBsaWZ0ZWQgYSBkcmFnb24gY29ycHNlPw==" },
+ { "Ever seen a leocrotta dancing the tengu?",
+ "RXZlciBzZWVuIGEgbGVvY3JvdHRhIGRhbmNpbmcgdGhlIHRlbmd1Pw==" },
+ { "Ever seen your weapon glow plaid?",
+ "RXZlciBzZWVuIHlvdXIgd2VhcG9uIGdsb3cgcGxhaWQ/" },
+ { "Ever tamed a shopkeeper?",
+ "RXZlciB0YW1lZCBhIHNob3BrZWVwZXI/" },
+ { "Ever tried digging through a Vault Guard?",
+ "RXZlciB0cmllZCBkaWdnaW5nIHRocm91Z2ggYSBWYXVsdCBHdWFyZD8=" },
+ { "Ever tried enchanting a rope?",
+ "RXZlciB0cmllZCBlbmNoYW50aW5nIGEgcm9wZT8=" },
+ { "Floating eyes can't stand Hawaiian shirts.",
+ "RmxvYXRpbmcgZXllcyBjYW4ndCBzdGFuZCBIYXdhaWlhbiBzaGlydHMu" },
+ { "For any remedy there is a misery.",
+ "Rm9yIGFueSByZW1lZHkgdGhlcmUgaXMgYSBtaXNlcnku" },
+ { "Giant bats turn into giant vampires.",
+ "R2lhbnQgYmF0cyB0dXJuIGludG8gZ2lhbnQgdmFtcGlyZXMu" },
+ { "Good day for overcoming obstacles. Try a steeplechase.",
+ "R29vZCBkYXkgZm9yIG92ZXJjb21pbmcgb2JzdGFjbGVzLiBUcnkgYSBzdGVlcGxlY2hhc2Uu" },
+ { "Half Moon tonight. (At least it's better than no Moon at all.)",
+ "SGFsZiBNb29uIHRvbmlnaHQuIChBdCBsZWFzdCBpdCdzIGJldHRlciB0aGFuIG5vIE1vb24gYXQgYWxsLik=" },
+ { "Help! I'm being held prisoner in a fortune cookie factory!",
+ "SGVscCEgSSdtIGJlaW5nIGhlbGQgcHJpc29uZXIgaW4gYSBmb3J0dW5lIGNvb2tpZSBmYWN0b3J5IQ==" },
+ { "Housecats have nine lives, kittens only one.",
+ "SG91c2VjYXRzIGhhdmUgbmluZSBsaXZlcywga2l0dGVucyBvbmx5IG9uZS4=" },
+ { "How long can you tread water?",
+ "SG93IGxvbmcgY2FuIHlvdSB0cmVhZCB3YXRlcj8=" },
+ { "Hungry? There is an abundance of food on the next level.",
+ "SHVuZ3J5PyBUaGVyZSBpcyBhbiBhYnVuZGFuY2Ugb2YgZm9vZCBvbiB0aGUgbmV4dCBsZXZlbC4=" },
+ { "I guess you've never hit a mail daemon with the Amulet of Yendor...",
+ "SSBndWVzcyB5b3UndmUgbmV2ZXIgaGl0IGEgbWFpbCBkYWVtb24gd2l0aCB0aGUgQW11bGV0IG9mIFllbmRvci4uLg==" },
+ { "If you are the shopkeeper, you can take things for free.",
+ "SWYgeW91IGFyZSB0aGUgc2hvcGtlZXBlciwgeW91IGNhbiB0YWtlIHRoaW5ncyBmb3IgZnJlZS4=" },
+ { "If you can't learn to do it well, learn to enjoy doing it badly.",
+ "SWYgeW91IGNhbid0IGxlYXJuIHRvIGRvIGl0IHdlbGwsIGxlYXJuIHRvIGVuam95IGRvaW5nIGl0IGJhZGx5Lg==" },
+ { "If you thought the Wizard was bad, just wait till you meet the Warlord!",
+ "SWYgeW91IHRob3VnaHQgdGhlIFdpemFyZCB3YXMgYmFkLCBqdXN0IHdhaXQgdGlsbCB5b3UgbWVldCB0aGUgV2FybG9yZCE=" },
+ { "If you turn blind, don't expect your dog to be turned into a seeing-eye dog.",
+ "SWYgeW91IHR1cm4gYmxpbmQsIGRvbid0IGV4cGVjdCB5b3VyIGRvZyB0byBiZSB0dXJuZWQgaW50byBhIHNlZWluZy1leWUgZG9nLg==" },
+ { "If you want to feel great, you must eat something real big.",
+ "SWYgeW91IHdhbnQgdG8gZmVlbCBncmVhdCwgeW91IG11c3QgZWF0IHNvbWV0aGluZyByZWFsIGJpZy4=" },
+ { "If you want to float, you'd better eat a floating eye.",
+ "SWYgeW91IHdhbnQgdG8gZmxvYXQsIHlvdSdkIGJldHRlciBlYXQgYSBmbG9hdGluZyBleWUu" },
+ { "If your ghost kills a player, it increases your score.",
+ "SWYgeW91ciBnaG9zdCBraWxscyBhIHBsYXllciwgaXQgaW5jcmVhc2VzIHlvdXIgc2NvcmUu" },
+ { "Increase mindpower: Tame your own ghost!",
+ "SW5jcmVhc2UgbWluZHBvd2VyOiBUYW1lIHlvdXIgb3duIGdob3N0IQ==" },
+ { "It furthers one to see the great man.",
+ "SXQgZnVydGhlcnMgb25lIHRvIHNlZSB0aGUgZ3JlYXQgbWFuLg==" },
+ { "It's easy to overlook a monster in a wood.",
+ "SXQncyBlYXN5IHRvIG92ZXJsb29rIGEgbW9uc3RlciBpbiBhIHdvb2Qu" },
+ { "Just below any trapdoor there may be another one. Just keep falling!",
+ "SnVzdCBiZWxvdyBhbnkgdHJhcGRvb3IgdGhlcmUgbWF5IGJlIGFub3RoZXIgb25lLiBKdXN0IGtlZXAgZmFsbGluZyE=" },
+ { "Katanas are very sharp; watch you don't cut yourself.",
+ "S2F0YW5hcyBhcmUgdmVyeSBzaGFycDsgd2F0Y2ggeW91IGRvbid0IGN1dCB5b3Vyc2VsZi4=" },
+ { "Keep a clear mind: quaff clear potions.",
+ "S2VlcCBhIGNsZWFyIG1pbmQ6IHF1YWZmIGNsZWFyIHBvdGlvbnMu" },
+ { "Kicking the terminal doesn't hurt the monsters.",
+ "S2lja2luZyB0aGUgdGVybWluYWwgZG9lc24ndCBodXJ0IHRoZSBtb25zdGVycy4=" },
+ { "Killer bees keep appearing till you kill their queen.",
+ "S2lsbGVyIGJlZXMga2VlcCBhcHBlYXJpbmcgdGlsbCB5b3Uga2lsbCB0aGVpciBxdWVlbi4=" },
+ { "Killer bunnies can be tamed with carrots only.",
+ "S2lsbGVyIGJ1bm5pZXMgY2FuIGJlIHRhbWVkIHdpdGggY2Fycm90cyBvbmx5Lg==" },
+ { "Latest news? Put `rec.games.roguelike.nethack' in your .newsrc!",
+ "TGF0ZXN0IG5ld3M/IFB1dCBgcmVjLmdhbWVzLnJvZ3VlbGlrZS5uZXRoYWNrJyBpbiB5b3VyIC5uZXdzcmMh" },
+ { "Learn how to spell. Play NetHack!",
+ "TGVhcm4gaG93IHRvIHNwZWxsLiBQbGF5IE5ldEhhY2sh" },
+ { "Leprechauns hide their gold in a secret room.",
+ "TGVwcmVjaGF1bnMgaGlkZSB0aGVpciBnb2xkIGluIGEgc2VjcmV0IHJvb20u" },
+ { "Let your fingers do the walking on the yulkjhnb keys.",
+ "TGV0IHlvdXIgZmluZ2VycyBkbyB0aGUgd2Fsa2luZyBvbiB0aGUgeXVsa2pobmIga2V5cy4=" },
+ { "Let's face it: this time you're not going to win.",
+ "TGV0J3MgZmFjZSBpdDogdGhpcyB0aW1lIHlvdSdyZSBub3QgZ29pbmcgdG8gd2luLg==" },
+ { "Let's have a party, drink a lot of booze.",
+ "TGV0J3MgaGF2ZSBhIHBhcnR5LCBkcmluayBhIGxvdCBvZiBib296ZS4=" },
+ { "Liquor sellers do not drink; they hate to see you twice.",
+ "TGlxdW9yIHNlbGxlcnMgZG8gbm90IGRyaW5rOyB0aGV5IGhhdGUgdG8gc2VlIHlvdSB0d2ljZS4=" },
+ { "Lunar eclipse tonight. May as well quit now!",
+ "THVuYXIgZWNsaXBzZSB0b25pZ2h0LiBNYXkgYXMgd2VsbCBxdWl0IG5vdyE=" },
+ { "Meeting your own ghost decreases your luck considerably!",
+ "TWVldGluZyB5b3VyIG93biBnaG9zdCBkZWNyZWFzZXMgeW91ciBsdWNrIGNvbnNpZGVyYWJseSE=" },
+ { "Money to invest? Take it to the local branch of the Magic Memory Vault!",
+ "TW9uZXkgdG8gaW52ZXN0PyBUYWtlIGl0IHRvIHRoZSBsb2NhbCBicmFuY2ggb2YgdGhlIE1hZ2ljIE1lbW9yeSBWYXVsdCE=" },
+ { "Monsters come from nowhere to hit you everywhere.",
+ "TW9uc3RlcnMgY29tZSBmcm9tIG5vd2hlcmUgdG8gaGl0IHlvdSBldmVyeXdoZXJlLg==" },
+ { "Monsters sleep because you are boring, not because they ever get tired.",
+ "TW9uc3RlcnMgc2xlZXAgYmVjYXVzZSB5b3UgYXJlIGJvcmluZywgbm90IGJlY2F1c2UgdGhleSBldmVyIGdldCB0aXJlZC4=" },
+ { "Most monsters prefer minced meat. That's why they are hitting you!",
+ "TW9zdCBtb25zdGVycyBwcmVmZXIgbWluY2VkIG1lYXQuIFRoYXQncyB3aHkgdGhleSBhcmUgaGl0dGluZyB5b3Uh" },
+ { "Most of the bugs in NetHack are on the floor.",
+ "TW9zdCBvZiB0aGUgYnVncyBpbiBOZXRIYWNrIGFyZSBvbiB0aGUgZmxvb3Iu" },
+ { "Much ado Nothing Happens.",
+ "TXVjaCBhZG8gTm90aGluZyBIYXBwZW5zLg==" },
+ { "Multi-player NetHack is a myth.",
+ "TXVsdGktcGxheWVyIE5ldEhhY2sgaXMgYSBteXRoLg==" },
+ { "NetHack is addictive. Too late, you're already hooked.",
+ "TmV0SGFjayBpcyBhZGRpY3RpdmUuIFRvbyBsYXRlLCB5b3UncmUgYWxyZWFkeSBob29rZWQu" },
+ { "Never ask a shopkeeper for a price list.",
+ "TmV2ZXIgYXNrIGEgc2hvcGtlZXBlciBmb3IgYSBwcmljZSBsaXN0Lg==" },
+ { "Never burn a tree, unless you like getting whacked with a +5 shovel.",
+ "TmV2ZXIgYnVybiBhIHRyZWUsIHVubGVzcyB5b3UgbGlrZSBnZXR0aW5nIHdoYWNrZWQgd2l0aCBhICs1IHNob3ZlbC4=" },
+ { "Never eat with glowing hands!",
+ "TmV2ZXIgZWF0IHdpdGggZ2xvd2luZyBoYW5kcyE=" },
+ { "Never mind the monsters hitting you: they just replace the charwomen.",
+ "TmV2ZXIgbWluZCB0aGUgbW9uc3RlcnMgaGl0dGluZyB5b3U6IHRoZXkganVzdCByZXBsYWNlIHRoZSBjaGFyd29tZW4u" },
+ { "Never play leapfrog with a unicorn.",
+ "TmV2ZXIgcGxheSBsZWFwZnJvZyB3aXRoIGEgdW5pY29ybi4=" },
+ { "Never step on a cursed engraving.",
+ "TmV2ZXIgc3RlcCBvbiBhIGN1cnNlZCBlbmdyYXZpbmcu" },
+ { "Never swim with a camera: there's nothing to take pictures of.",
+ "TmV2ZXIgc3dpbSB3aXRoIGEgY2FtZXJhOiB0aGVyZSdzIG5vdGhpbmcgdG8gdGFrZSBwaWN0dXJlcyBvZi4=" },
+ { "Never teach your pet rust monster to fetch.",
+ "TmV2ZXIgdGVhY2ggeW91ciBwZXQgcnVzdCBtb25zdGVyIHRvIGZldGNoLg==" },
+ { "Never trust a random generator in magic fields.",
+ "TmV2ZXIgdHJ1c3QgYSByYW5kb20gZ2VuZXJhdG9yIGluIG1hZ2ljIGZpZWxkcy4=" },
+ { "Never use a wand of death.",
+ "TmV2ZXIgdXNlIGEgd2FuZCBvZiBkZWF0aC4=" },
+ { "No level contains two shops. The maze is no level. So...",
+ "Tm8gbGV2ZWwgY29udGFpbnMgdHdvIHNob3BzLiBUaGUgbWF6ZSBpcyBubyBsZXZlbC4gU28uLi4=" },
+ { "No part of this fortune may be reproduced, stored in a retrieval system, ...",
+ "Tm8gcGFydCBvZiB0aGlzIGZvcnR1bmUgbWF5IGJlIHJlcHJvZHVjZWQsIHN0b3JlZCBpbiBhIHJldHJpZXZhbCBzeXN0ZW0sIC4uLg==" },
+ { "Not all rumors are as misleading as this one.",
+ "Tm90IGFsbCBydW1vcnMgYXJlIGFzIG1pc2xlYWRpbmcgYXMgdGhpcyBvbmUu" },
+ { "Nymphs and nurses like beautiful rings.",
+ "TnltcGhzIGFuZCBudXJzZXMgbGlrZSBiZWF1dGlmdWwgcmluZ3Mu" },
+ { "Nymphs are blondes. Are you a gentleman?",
+ "TnltcGhzIGFyZSBibG9uZGVzLiBBcmUgeW91IGEgZ2VudGxlbWFuPw==" },
+ { "Offering a unicorn a worthless piece of glass might prove to be fatal!",
+ "T2ZmZXJpbmcgYSB1bmljb3JuIGEgd29ydGhsZXNzIHBpZWNlIG9mIGdsYXNzIG1pZ2h0IHByb3ZlIHRvIGJlIGZhdGFsIQ==" },
+ { "Old hackers never die: young ones do.",
+ "T2xkIGhhY2tlcnMgbmV2ZXIgZGllOiB5b3VuZyBvbmVzIGRvLg==" },
+ { "One has to leave shops before closing time.",
+ "T25lIGhhcyB0byBsZWF2ZSBzaG9wcyBiZWZvcmUgY2xvc2luZyB0aW1lLg==" },
+ { "One homunculus a day keeps the doctor away.",
+ "T25lIGhvbXVuY3VsdXMgYSBkYXkga2VlcHMgdGhlIGRvY3RvciBhd2F5Lg==" },
+ { "One level further down somebody is getting killed, right now.",
+ "T25lIGxldmVsIGZ1cnRoZXIgZG93biBzb21lYm9keSBpcyBnZXR0aW5nIGtpbGxlZCwgcmlnaHQgbm93Lg==" },
+ { "Only a wizard can use a magic whistle.",
+ "T25seSBhIHdpemFyZCBjYW4gdXNlIGEgbWFnaWMgd2hpc3RsZS4=" },
+ { "Only adventurers of evil alignment think of killing their dog.",
+ "T25seSBhZHZlbnR1cmVycyBvZiBldmlsIGFsaWdubWVudCB0aGluayBvZiBraWxsaW5nIHRoZWlyIGRvZy4=" },
+ { "Only chaotic evils kill sleeping monsters.",
+ "T25seSBjaGFvdGljIGV2aWxzIGtpbGwgc2xlZXBpbmcgbW9uc3RlcnMu" },
+ { "Only real trappers escape traps.",
+ "T25seSByZWFsIHRyYXBwZXJzIGVzY2FwZSB0cmFwcy4=" },
+ { "Only real wizards can write scrolls.",
+ "T25seSByZWFsIHdpemFyZHMgY2FuIHdyaXRlIHNjcm9sbHMu" },
+ { "Operation OVERKILL has started now.",
+ "T3BlcmF0aW9uIE9WRVJLSUxMIGhhcyBzdGFydGVkIG5vdy4=" },
+ { "PLEASE ignore previous rumor.",
+ "UExFQVNFIGlnbm9yZSBwcmV2aW91cyBydW1vci4=" },
+ { "Polymorph into an ettin; meet your opponents face to face to face.",
+ "UG9seW1vcnBoIGludG8gYW4gZXR0aW47IG1lZXQgeW91ciBvcHBvbmVudHMgZmFjZSB0byBmYWNlIHRvIGZhY2Uu" },
+ { "Praying will frighten demons.",
+ "UHJheWluZyB3aWxsIGZyaWdodGVuIGRlbW9ucy4=" },
+ { "Row (3x) that boat gently down the stream, Charon (4x), death is but a dream.",
+ "Um93ICgzeCkgdGhhdCBib2F0IGdlbnRseSBkb3duIHRoZSBzdHJlYW0sIENoYXJvbiAoNHgpLCBkZWF0aCBpcyBidXQgYSBkcmVhbS4=" },
+ { "Running is good for your legs.",
+ "UnVubmluZyBpcyBnb29kIGZvciB5b3VyIGxlZ3Mu" },
+ { "Screw up your courage! You've screwed up everything else.",
+ "U2NyZXcgdXAgeW91ciBjb3VyYWdlISBZb3UndmUgc2NyZXdlZCB1cCBldmVyeXRoaW5nIGVsc2Uu" },
+ { "Seepage? Leaky pipes? Rising damp? Summon the plumber!",
+ "U2VlcGFnZT8gTGVha3kgcGlwZXM/IFJpc2luZyBkYW1wPyBTdW1tb24gdGhlIHBsdW1iZXIh" },
+ { "Segmentation fault (core dumped).",
+ "U2VnbWVudGF0aW9uIGZhdWx0IChjb3JlIGR1bXBlZCku" },
+ { "Shopkeepers sometimes die from old age.",
+ "U2hvcGtlZXBlcnMgc29tZXRpbWVzIGRpZSBmcm9tIG9sZCBhZ2Uu" },
+ { "Some mazes (especially small ones) have no solutions, says man 6 maze.",
+ "U29tZSBtYXplcyAoZXNwZWNpYWxseSBzbWFsbCBvbmVzKSBoYXZlIG5vIHNvbHV0aW9ucywgc2F5cyBtYW4gNiBtYXplLg==" },
+ { "Some questions the Sphynx asks just *don't* have any answers.",
+ "U29tZSBxdWVzdGlvbnMgdGhlIFNwaHlueCBhc2tzIGp1c3QgKmRvbid0KiBoYXZlIGFueSBhbnN3ZXJzLg==" },
+ { "Sometimes \"mu\" is the answer.",
+ "U29tZXRpbWVzICJtdSIgaXMgdGhlIGFuc3dlci4=" },
+ { "Sorry, no fortune this time. Better luck next cookie!",
+ "U29ycnksIG5vIGZvcnR1bmUgdGhpcyB0aW1lLiBCZXR0ZXIgbHVjayBuZXh0IGNvb2tpZSE=" },
+ { "Spare your scrolls of make-edible until it's really necessary!",
+ "U3BhcmUgeW91ciBzY3JvbGxzIG9mIG1ha2UtZWRpYmxlIHVudGlsIGl0J3MgcmVhbGx5IG5lY2Vzc2FyeSE=" },
+ { "Suddenly, the dungeon will collapse...",
+ "U3VkZGVubHksIHRoZSBkdW5nZW9uIHdpbGwgY29sbGFwc2UuLi4=" },
+ { "Taming a mail daemon may cause a system security violation.",
+ "VGFtaW5nIGEgbWFpbCBkYWVtb24gbWF5IGNhdXNlIGEgc3lzdGVtIHNlY3VyaXR5IHZpb2xhdGlvbi4=" },
+ { "The crowd was so tough, the Stooges won't play the Dungeon anymore, nyuk nyuk.",
+ "VGhlIGNyb3dkIHdhcyBzbyB0b3VnaCwgdGhlIFN0b29nZXMgd29uJ3QgcGxheSB0aGUgRHVuZ2VvbiBhbnltb3JlLCBueXVrIG55dWsu" },
+ { "The leprechauns hide their treasure in a small hidden room.",
+ "VGhlIGxlcHJlY2hhdW5zIGhpZGUgdGhlaXIgdHJlYXN1cmUgaW4gYSBzbWFsbCBoaWRkZW4gcm9vbS4=" },
+ { "The longer the wand the better.",
+ "VGhlIGxvbmdlciB0aGUgd2FuZCB0aGUgYmV0dGVyLg==" },
+ { "The magic word is \"XYZZY\".",
+ "VGhlIG1hZ2ljIHdvcmQgaXMgIlhZWlpZIi4=" },
+ { "The meek shall inherit your bones files.",
+ "VGhlIG1lZWsgc2hhbGwgaW5oZXJpdCB5b3VyIGJvbmVzIGZpbGVzLg==" },
+ { "The mines are dark and deep, and I have levels to go before I sleep.",
+ "VGhlIG1pbmVzIGFyZSBkYXJrIGFuZCBkZWVwLCBhbmQgSSBoYXZlIGxldmVscyB0byBnbyBiZWZvcmUgSSBzbGVlcC4=" },
+ { "The use of dynamite is dangerous.",
+ "VGhlIHVzZSBvZiBkeW5hbWl0ZSBpcyBkYW5nZXJvdXMu" },
+ { "There are no worms in the UNIX version.",
+ "VGhlcmUgYXJlIG5vIHdvcm1zIGluIHRoZSBVTklYIHZlcnNpb24u" },
+ { "There is a trap on this level!",
+ "VGhlcmUgaXMgYSB0cmFwIG9uIHRoaXMgbGV2ZWwh" },
+ { "They say that Demogorgon, Asmodeus, Orcus, Yeenoghu & Juiblex is no law firm.",
+ "VGhleSBzYXkgdGhhdCBEZW1vZ29yZ29uLCBBc21vZGV1cywgT3JjdXMsIFllZW5vZ2h1ICYgSnVpYmxleCBpcyBubyBsYXcgZmlybS4=" },
+ { "They say that Geryon has an evil twin, beware!",
+ "VGhleSBzYXkgdGhhdCBHZXJ5b24gaGFzIGFuIGV2aWwgdHdpbiwgYmV3YXJlIQ==" },
+ { "They say that Medusa would make a terrible pet.",
+ "VGhleSBzYXkgdGhhdCBNZWR1c2Egd291bGQgbWFrZSBhIHRlcnJpYmxlIHBldC4=" },
+ { "They say that NetHack bugs are Seldon planned.",
+ "VGhleSBzYXkgdGhhdCBOZXRIYWNrIGJ1Z3MgYXJlIFNlbGRvbiBwbGFubmVkLg==" },
+ { "They say that NetHack comes in 256 flavors.",
+ "VGhleSBzYXkgdGhhdCBOZXRIYWNrIGNvbWVzIGluIDI1NiBmbGF2b3JzLg==" },
+ { "They say that NetHack is just a computer game.",
+ "VGhleSBzYXkgdGhhdCBOZXRIYWNrIGlzIGp1c3QgYSBjb21wdXRlciBnYW1lLg==" },
+ { "They say that NetHack is more than just a computer game.",
+ "VGhleSBzYXkgdGhhdCBOZXRIYWNrIGlzIG1vcmUgdGhhbiBqdXN0IGEgY29tcHV0ZXIgZ2FtZS4=" },
+ { "They say that NetHack is never what it used to be.",
+ "VGhleSBzYXkgdGhhdCBOZXRIYWNrIGlzIG5ldmVyIHdoYXQgaXQgdXNlZCB0byBiZS4=" },
+ { "They say that a baby dragon is too small to hurt or help you.",
+ "VGhleSBzYXkgdGhhdCBhIGJhYnkgZHJhZ29uIGlzIHRvbyBzbWFsbCB0byBodXJ0IG9yIGhlbHAgeW91Lg==" },
+ { "They say that a black pudding is simply a brown pudding gone bad.",
+ "VGhleSBzYXkgdGhhdCBhIGJsYWNrIHB1ZGRpbmcgaXMgc2ltcGx5IGEgYnJvd24gcHVkZGluZyBnb25lIGJhZC4=" },
+ { "They say that a black sheep has 3 bags full of wool.",
+ "VGhleSBzYXkgdGhhdCBhIGJsYWNrIHNoZWVwIGhhcyAzIGJhZ3MgZnVsbCBvZiB3b29sLg==" },
+ { "They say that a blank scroll is like a blank check.",
+ "VGhleSBzYXkgdGhhdCBhIGJsYW5rIHNjcm9sbCBpcyBsaWtlIGEgYmxhbmsgY2hlY2su" },
+ { "They say that a cat named Morris has nine lives.",
+ "VGhleSBzYXkgdGhhdCBhIGNhdCBuYW1lZCBNb3JyaXMgaGFzIG5pbmUgbGl2ZXMu" },
+ { "They say that a desperate shopper might pay any price in a shop.",
+ "VGhleSBzYXkgdGhhdCBhIGRlc3BlcmF0ZSBzaG9wcGVyIG1pZ2h0IHBheSBhbnkgcHJpY2UgaW4gYSBzaG9wLg==" },
+ { "They say that a diamond dog is everybody's best friend.",
+ "VGhleSBzYXkgdGhhdCBhIGRpYW1vbmQgZG9nIGlzIGV2ZXJ5Ym9keSdzIGJlc3QgZnJpZW5kLg==" },
+ { "They say that a dwarf lord can carry a pick-axe because his armor is light.",
+ "VGhleSBzYXkgdGhhdCBhIGR3YXJmIGxvcmQgY2FuIGNhcnJ5IGEgcGljay1heGUgYmVjYXVzZSBoaXMgYXJtb3IgaXMgbGlnaHQu" },
+ { "They say that a floating eye can defeat Medusa.",
+ "VGhleSBzYXkgdGhhdCBhIGZsb2F0aW5nIGV5ZSBjYW4gZGVmZWF0IE1lZHVzYS4=" },
+ { "They say that a fortune only has 1 line and you can't read between it.",
+ "VGhleSBzYXkgdGhhdCBhIGZvcnR1bmUgb25seSBoYXMgMSBsaW5lIGFuZCB5b3UgY2FuJ3QgcmVhZCBiZXR3ZWVuIGl0Lg==" },
+ { "They say that a fortune only has 1 line, but you can read between it.",
+ "VGhleSBzYXkgdGhhdCBhIGZvcnR1bmUgb25seSBoYXMgMSBsaW5lLCBidXQgeW91IGNhbiByZWFkIGJldHdlZW4gaXQu" },
+ { "They say that a fountain looks nothing like a regularly erupting geyser.",
+ "VGhleSBzYXkgdGhhdCBhIGZvdW50YWluIGxvb2tzIG5vdGhpbmcgbGlrZSBhIHJlZ3VsYXJseSBlcnVwdGluZyBnZXlzZXIu" },
+ { "They say that a gold doubloon is worth more than its weight in gold.",
+ "VGhleSBzYXkgdGhhdCBhIGdvbGQgZG91Ymxvb24gaXMgd29ydGggbW9yZSB0aGFuIGl0cyB3ZWlnaHQgaW4gZ29sZC4=" },
+ { "They say that a grid bug won't pay a shopkeeper for zapping you in a shop.",
+ "VGhleSBzYXkgdGhhdCBhIGdyaWQgYnVnIHdvbid0IHBheSBhIHNob3BrZWVwZXIgZm9yIHphcHBpbmcgeW91IGluIGEgc2hvcC4=" },
+ { "They say that a gypsy could tell your fortune for a price.",
+ "VGhleSBzYXkgdGhhdCBhIGd5cHN5IGNvdWxkIHRlbGwgeW91ciBmb3J0dW5lIGZvciBhIHByaWNlLg==" },
+ { "They say that a hacker named Alice once level teleported by using a mirror.",
+ "VGhleSBzYXkgdGhhdCBhIGhhY2tlciBuYW1lZCBBbGljZSBvbmNlIGxldmVsIHRlbGVwb3J0ZWQgYnkgdXNpbmcgYSBtaXJyb3Iu" },
+ { "They say that a hacker named David once slew a giant with a sling and a rock.",
+ "VGhleSBzYXkgdGhhdCBhIGhhY2tlciBuYW1lZCBEYXZpZCBvbmNlIHNsZXcgYSBnaWFudCB3aXRoIGEgc2xpbmcgYW5kIGEgcm9jay4=" },
+ { "They say that a hacker named Dorothy once rode a fog cloud to Oz.",
+ "VGhleSBzYXkgdGhhdCBhIGhhY2tlciBuYW1lZCBEb3JvdGh5IG9uY2Ugcm9kZSBhIGZvZyBjbG91ZCB0byBPei4=" },
+ { "They say that a hacker named Mary once lost a white sheep in the mazes.",
+ "VGhleSBzYXkgdGhhdCBhIGhhY2tlciBuYW1lZCBNYXJ5IG9uY2UgbG9zdCBhIHdoaXRlIHNoZWVwIGluIHRoZSBtYXplcy4=" },
+ { "They say that a helm of brilliance is not to be taken lightly.",
+ "VGhleSBzYXkgdGhhdCBhIGhlbG0gb2YgYnJpbGxpYW5jZSBpcyBub3QgdG8gYmUgdGFrZW4gbGlnaHRseS4=" },
+ { "They say that a hot dog and a hell hound are the same thing.",
+ "VGhleSBzYXkgdGhhdCBhIGhvdCBkb2cgYW5kIGEgaGVsbCBob3VuZCBhcmUgdGhlIHNhbWUgdGhpbmcu" },
+ { "They say that a lamp named Aladdin's Lamp contains a djinni with 3 wishes.",
+ "VGhleSBzYXkgdGhhdCBhIGxhbXAgbmFtZWQgQWxhZGRpbidzIExhbXAgY29udGFpbnMgYSBkamlubmkgd2l0aCAzIHdpc2hlcy4=" },
+ { "They say that a large dog named Lassie will lead you to the amulet.",
+ "VGhleSBzYXkgdGhhdCBhIGxhcmdlIGRvZyBuYW1lZCBMYXNzaWUgd2lsbCBsZWFkIHlvdSB0byB0aGUgYW11bGV0Lg==" },
+ { "They say that a long sword is not a light sword.",
+ "VGhleSBzYXkgdGhhdCBhIGxvbmcgc3dvcmQgaXMgbm90IGEgbGlnaHQgc3dvcmQu" },
+ { "They say that a manes won't mince words with you.",
+ "VGhleSBzYXkgdGhhdCBhIG1hbmVzIHdvbid0IG1pbmNlIHdvcmRzIHdpdGggeW91Lg==" },
+ { "They say that a mind is a terrible thing to waste.",
+ "VGhleSBzYXkgdGhhdCBhIG1pbmQgaXMgYSB0ZXJyaWJsZSB0aGluZyB0byB3YXN0ZS4=" },
+ { "They say that a plain nymph will only wear a wire ring in one ear.",
+ "VGhleSBzYXkgdGhhdCBhIHBsYWluIG55bXBoIHdpbGwgb25seSB3ZWFyIGEgd2lyZSByaW5nIGluIG9uZSBlYXIu" },
+ { "They say that a plumed hat could be a previously used crested helmet.",
+ "VGhleSBzYXkgdGhhdCBhIHBsdW1lZCBoYXQgY291bGQgYmUgYSBwcmV2aW91c2x5IHVzZWQgY3Jlc3RlZCBoZWxtZXQu" },
+ { "They say that a potion of oil is difficult to grasp.",
+ "VGhleSBzYXkgdGhhdCBhIHBvdGlvbiBvZiBvaWwgaXMgZGlmZmljdWx0IHRvIGdyYXNwLg==" },
+ { "They say that a potion of yogurt is a cancelled potion of sickness.",
+ "VGhleSBzYXkgdGhhdCBhIHBvdGlvbiBvZiB5b2d1cnQgaXMgYSBjYW5jZWxsZWQgcG90aW9uIG9mIHNpY2tuZXNzLg==" },
+ { "They say that a purple worm is not a baby purple dragon.",
+ "VGhleSBzYXkgdGhhdCBhIHB1cnBsZSB3b3JtIGlzIG5vdCBhIGJhYnkgcHVycGxlIGRyYWdvbi4=" },
+ { "They say that a quivering blob tastes different than a gelatinous cube.",
+ "VGhleSBzYXkgdGhhdCBhIHF1aXZlcmluZyBibG9iIHRhc3RlcyBkaWZmZXJlbnQgdGhhbiBhIGdlbGF0aW5vdXMgY3ViZS4=" },
+ { "They say that a runed broadsword named Stormbringer attracts vortices.",
+ "VGhleSBzYXkgdGhhdCBhIHJ1bmVkIGJyb2Fkc3dvcmQgbmFtZWQgU3Rvcm1icmluZ2VyIGF0dHJhY3RzIHZvcnRpY2VzLg==" },
+ { "They say that a scroll of summoning has other names.",
+ "VGhleSBzYXkgdGhhdCBhIHNjcm9sbCBvZiBzdW1tb25pbmcgaGFzIG90aGVyIG5hbWVzLg==" },
+ { "They say that a shaman can bestow blessings but usually doesn't.",
+ "VGhleSBzYXkgdGhhdCBhIHNoYW1hbiBjYW4gYmVzdG93IGJsZXNzaW5ncyBidXQgdXN1YWxseSBkb2Vzbid0Lg==" },
+ { "They say that a shaman will bless you for an eye of newt and wing of bat.",
+ "VGhleSBzYXkgdGhhdCBhIHNoYW1hbiB3aWxsIGJsZXNzIHlvdSBmb3IgYW4gZXllIG9mIG5ld3QgYW5kIHdpbmcgb2YgYmF0Lg==" },
+ { "They say that a shimmering gold shield is not a polished silver shield.",
+ "VGhleSBzYXkgdGhhdCBhIHNoaW1tZXJpbmcgZ29sZCBzaGllbGQgaXMgbm90IGEgcG9saXNoZWQgc2lsdmVyIHNoaWVsZC4=" },
+ { "They say that a spear will hit a neo-otyugh. (Do YOU know what that is?)",
+ "VGhleSBzYXkgdGhhdCBhIHNwZWFyIHdpbGwgaGl0IGEgbmVvLW90eXVnaC4gKERvIFlPVSBrbm93IHdoYXQgdGhhdCBpcz8p" },
+ { "They say that a spotted dragon is the ultimate shape changer.",
+ "VGhleSBzYXkgdGhhdCBhIHNwb3R0ZWQgZHJhZ29uIGlzIHRoZSB1bHRpbWF0ZSBzaGFwZSBjaGFuZ2VyLg==" },
+ { "They say that a stethoscope is no good if you can only hear your heartbeat.",
+ "VGhleSBzYXkgdGhhdCBhIHN0ZXRob3Njb3BlIGlzIG5vIGdvb2QgaWYgeW91IGNhbiBvbmx5IGhlYXIgeW91ciBoZWFydGJlYXQu" },
+ { "They say that a succubus named Suzy will sometimes warn you of danger.",
+ "VGhleSBzYXkgdGhhdCBhIHN1Y2N1YnVzIG5hbWVkIFN1enkgd2lsbCBzb21ldGltZXMgd2FybiB5b3Ugb2YgZGFuZ2VyLg==" },
+ { "They say that a wand of cancellation is not like a wand of polymorph.",
+ "VGhleSBzYXkgdGhhdCBhIHdhbmQgb2YgY2FuY2VsbGF0aW9uIGlzIG5vdCBsaWtlIGEgd2FuZCBvZiBwb2x5bW9ycGgu" },
+ { "They say that a wood golem named Pinocchio would be easy to control.",
+ "VGhleSBzYXkgdGhhdCBhIHdvb2QgZ29sZW0gbmFtZWQgUGlub2NjaGlvIHdvdWxkIGJlIGVhc3kgdG8gY29udHJvbC4=" },
+ { "They say that after killing a dragon it's time for a change of scenery.",
+ "VGhleSBzYXkgdGhhdCBhZnRlciBraWxsaW5nIGEgZHJhZ29uIGl0J3MgdGltZSBmb3IgYSBjaGFuZ2Ugb2Ygc2NlbmVyeS4=" },
+ { "They say that an amulet of strangulation is worse than ring around the collar.",
+ "VGhleSBzYXkgdGhhdCBhbiBhbXVsZXQgb2Ygc3RyYW5ndWxhdGlvbiBpcyB3b3JzZSB0aGFuIHJpbmcgYXJvdW5kIHRoZSBjb2xsYXIu" },
+ { "They say that an attic is the best place to hide your toys.",
+ "VGhleSBzYXkgdGhhdCBhbiBhdHRpYyBpcyB0aGUgYmVzdCBwbGFjZSB0byBoaWRlIHlvdXIgdG95cy4=" },
+ { "They say that an axe named Cleaver once belonged to a hacker named Beaver.",
+ "VGhleSBzYXkgdGhhdCBhbiBheGUgbmFtZWQgQ2xlYXZlciBvbmNlIGJlbG9uZ2VkIHRvIGEgaGFja2VyIG5hbWVkIEJlYXZlci4=" },
+ { "They say that an eye of newt and a wing of bat are double the trouble.",
+ "VGhleSBzYXkgdGhhdCBhbiBleWUgb2YgbmV3dCBhbmQgYSB3aW5nIG9mIGJhdCBhcmUgZG91YmxlIHRoZSB0cm91YmxlLg==" },
+ { "They say that an incubus named Izzy sometimes makes women feel sensitive.",
+ "VGhleSBzYXkgdGhhdCBhbiBpbmN1YnVzIG5hbWVkIEl6enkgc29tZXRpbWVzIG1ha2VzIHdvbWVuIGZlZWwgc2Vuc2l0aXZlLg==" },
+ { "They say that an opulent throne room is rarely a place to wish you'd be in.",
+ "VGhleSBzYXkgdGhhdCBhbiBvcHVsZW50IHRocm9uZSByb29tIGlzIHJhcmVseSBhIHBsYWNlIHRvIHdpc2ggeW91J2QgYmUgaW4u" },
+ { "They say that an unlucky hacker once had a nose bleed at an altar and died.",
+ "VGhleSBzYXkgdGhhdCBhbiB1bmx1Y2t5IGhhY2tlciBvbmNlIGhhZCBhIG5vc2UgYmxlZWQgYXQgYW4gYWx0YXIgYW5kIGRpZWQu" },
+ { "They say that and they say this but they never say never, never!",
+ "VGhleSBzYXkgdGhhdCBhbmQgdGhleSBzYXkgdGhpcyBidXQgdGhleSBuZXZlciBzYXkgbmV2ZXIsIG5ldmVyIQ==" },
+ { "They say that any quantum mechanic knows that speed kills.",
+ "VGhleSBzYXkgdGhhdCBhbnkgcXVhbnR1bSBtZWNoYW5pYyBrbm93cyB0aGF0IHNwZWVkIGtpbGxzLg==" },
+ { "They say that applying a unicorn horn means you've missed the point.",
+ "VGhleSBzYXkgdGhhdCBhcHBseWluZyBhIHVuaWNvcm4gaG9ybiBtZWFucyB5b3UndmUgbWlzc2VkIHRoZSBwb2ludC4=" },
+ { "They say that blue stones are radioactive, beware.",
+ "VGhleSBzYXkgdGhhdCBibHVlIHN0b25lcyBhcmUgcmFkaW9hY3RpdmUsIGJld2FyZS4=" },
+ { "They say that building a dungeon is a team effort.",
+ "VGhleSBzYXkgdGhhdCBidWlsZGluZyBhIGR1bmdlb24gaXMgYSB0ZWFtIGVmZm9ydC4=" },
+ { "They say that chaotic characters never get a kick out of altars.",
+ "VGhleSBzYXkgdGhhdCBjaGFvdGljIGNoYXJhY3RlcnMgbmV2ZXIgZ2V0IGEga2ljayBvdXQgb2YgYWx0YXJzLg==" },
+ { "They say that collapsing a dungeon often creates a panic.",
+ "VGhleSBzYXkgdGhhdCBjb2xsYXBzaW5nIGEgZHVuZ2VvbiBvZnRlbiBjcmVhdGVzIGEgcGFuaWMu" },
+ { "They say that counting your eggs before they hatch shows that you care.",
+ "VGhleSBzYXkgdGhhdCBjb3VudGluZyB5b3VyIGVnZ3MgYmVmb3JlIHRoZXkgaGF0Y2ggc2hvd3MgdGhhdCB5b3UgY2FyZS4=" },
+ { "They say that dipping a bag of tricks in a fountain won't make it an icebox.",
+ "VGhleSBzYXkgdGhhdCBkaXBwaW5nIGEgYmFnIG9mIHRyaWNrcyBpbiBhIGZvdW50YWluIHdvbid0IG1ha2UgaXQgYW4gaWNlYm94Lg==" },
+ { "They say that dipping an eel and brown mold in hot water makes bouillabaisse.",
+ "VGhleSBzYXkgdGhhdCBkaXBwaW5nIGFuIGVlbCBhbmQgYnJvd24gbW9sZCBpbiBob3Qgd2F0ZXIgbWFrZXMgYm91aWxsYWJhaXNzZS4=" },
+ { "They say that donating a doubloon is extremely pious charity.",
+ "VGhleSBzYXkgdGhhdCBkb25hdGluZyBhIGRvdWJsb29uIGlzIGV4dHJlbWVseSBwaW91cyBjaGFyaXR5Lg==" },
+ { "They say that eating royal jelly attracts grizzly owlbears.",
+ "VGhleSBzYXkgdGhhdCBlYXRpbmcgcm95YWwgamVsbHkgYXR0cmFjdHMgZ3JpenpseSBvd2xiZWFycy4=" },
+ { "They say that eggs, pancakes and juice are just a mundane breakfast.",
+ "VGhleSBzYXkgdGhhdCBlZ2dzLCBwYW5jYWtlcyBhbmQganVpY2UgYXJlIGp1c3QgYSBtdW5kYW5lIGJyZWFrZmFzdC4=" },
+ { "They say that everyone knows why Medusa stands alone in the dark.",
+ "VGhleSBzYXkgdGhhdCBldmVyeW9uZSBrbm93cyB3aHkgTWVkdXNhIHN0YW5kcyBhbG9uZSBpbiB0aGUgZGFyay4=" },
+ { "They say that everyone wanted rec.games.hack to undergo a name change.",
+ "VGhleSBzYXkgdGhhdCBldmVyeW9uZSB3YW50ZWQgcmVjLmdhbWVzLmhhY2sgdG8gdW5kZXJnbyBhIG5hbWUgY2hhbmdlLg==" },
+ { "They say that finding a winning strategy is a deliberate move on your part.",
+ "VGhleSBzYXkgdGhhdCBmaW5kaW5nIGEgd2lubmluZyBzdHJhdGVneSBpcyBhIGRlbGliZXJhdGUgbW92ZSBvbiB5b3VyIHBhcnQu" },
+ { "They say that finding worthless glass is worth something.",
+ "VGhleSBzYXkgdGhhdCBmaW5kaW5nIHdvcnRobGVzcyBnbGFzcyBpcyB3b3J0aCBzb21ldGhpbmcu" },
+ { "They say that fortune cookies are food for thought.",
+ "VGhleSBzYXkgdGhhdCBmb3J0dW5lIGNvb2tpZXMgYXJlIGZvb2QgZm9yIHRob3VnaHQu" },
+ { "They say that gold is only wasted on a pet dragon.",
+ "VGhleSBzYXkgdGhhdCBnb2xkIGlzIG9ubHkgd2FzdGVkIG9uIGEgcGV0IGRyYWdvbi4=" },
+ { "They say that good things come to those that wait.",
+ "VGhleSBzYXkgdGhhdCBnb29kIHRoaW5ncyBjb21lIHRvIHRob3NlIHRoYXQgd2FpdC4=" },
+ { "They say that greased objects will slip out of monsters' hands.",
+ "VGhleSBzYXkgdGhhdCBncmVhc2VkIG9iamVjdHMgd2lsbCBzbGlwIG91dCBvZiBtb25zdGVycycgaGFuZHMu" },
+ { "They say that if you can't spell then you'll wish you had a spell book.",
+ "VGhleSBzYXkgdGhhdCBpZiB5b3UgY2FuJ3Qgc3BlbGwgdGhlbiB5b3UnbGwgd2lzaCB5b3UgaGFkIGEgc3BlbGwgYm9vay4=" },
+ { "They say that if you live by the sword, you'll die by the sword.",
+ "VGhleSBzYXkgdGhhdCBpZiB5b3UgbGl2ZSBieSB0aGUgc3dvcmQsIHlvdSdsbCBkaWUgYnkgdGhlIHN3b3JkLg==" },
+ { "They say that if you play like a monster you'll have a better game.",
+ "VGhleSBzYXkgdGhhdCBpZiB5b3UgcGxheSBsaWtlIGEgbW9uc3RlciB5b3UnbGwgaGF2ZSBhIGJldHRlciBnYW1lLg==" },
+ { "They say that if you sleep with a demon you might awake with a headache.",
+ "VGhleSBzYXkgdGhhdCBpZiB5b3Ugc2xlZXAgd2l0aCBhIGRlbW9uIHlvdSBtaWdodCBhd2FrZSB3aXRoIGEgaGVhZGFjaGUu" },
+ { "They say that if you step on a crack you could break your mother's back.",
+ "VGhleSBzYXkgdGhhdCBpZiB5b3Ugc3RlcCBvbiBhIGNyYWNrIHlvdSBjb3VsZCBicmVhayB5b3VyIG1vdGhlcidzIGJhY2su" },
+ { "They say that if you're invisible you can still be heard!",
+ "VGhleSBzYXkgdGhhdCBpZiB5b3UncmUgaW52aXNpYmxlIHlvdSBjYW4gc3RpbGwgYmUgaGVhcmQh" },
+ { "They say that if you're lucky you can feel the runes on a scroll.",
+ "VGhleSBzYXkgdGhhdCBpZiB5b3UncmUgbHVja3kgeW91IGNhbiBmZWVsIHRoZSBydW5lcyBvbiBhIHNjcm9sbC4=" },
+ { "They say that in the big picture gold is only small change.",
+ "VGhleSBzYXkgdGhhdCBpbiB0aGUgYmlnIHBpY3R1cmUgZ29sZCBpcyBvbmx5IHNtYWxsIGNoYW5nZS4=" },
+ { "They say that in the dungeon it's not what you know that really matters.",
+ "VGhleSBzYXkgdGhhdCBpbiB0aGUgZHVuZ2VvbiBpdCdzIG5vdCB3aGF0IHlvdSBrbm93IHRoYXQgcmVhbGx5IG1hdHRlcnMu" },
+ { "They say that in the dungeon moon rocks are really dilithium crystals.",
+ "VGhleSBzYXkgdGhhdCBpbiB0aGUgZHVuZ2VvbiBtb29uIHJvY2tzIGFyZSByZWFsbHkgZGlsaXRoaXVtIGNyeXN0YWxzLg==" },
+ { "They say that in the dungeon the boorish customer is never right.",
+ "VGhleSBzYXkgdGhhdCBpbiB0aGUgZHVuZ2VvbiB0aGUgYm9vcmlzaCBjdXN0b21lciBpcyBuZXZlciByaWdodC4=" },
+ { "They say that in the dungeon you don't need a watch to tell time.",
+ "VGhleSBzYXkgdGhhdCBpbiB0aGUgZHVuZ2VvbiB5b3UgZG9uJ3QgbmVlZCBhIHdhdGNoIHRvIHRlbGwgdGltZS4=" },
+ { "They say that in the dungeon you need something old, new, burrowed and blue.",
+ "VGhleSBzYXkgdGhhdCBpbiB0aGUgZHVuZ2VvbiB5b3UgbmVlZCBzb21ldGhpbmcgb2xkLCBuZXcsIGJ1cnJvd2VkIGFuZCBibHVlLg==" },
+ { "They say that in the dungeon you should always count your blessings.",
+ "VGhleSBzYXkgdGhhdCBpbiB0aGUgZHVuZ2VvbiB5b3Ugc2hvdWxkIGFsd2F5cyBjb3VudCB5b3VyIGJsZXNzaW5ncy4=" },
+ { "They say that iron golem plate mail isn't worth wishing for.",
+ "VGhleSBzYXkgdGhhdCBpcm9uIGdvbGVtIHBsYXRlIG1haWwgaXNuJ3Qgd29ydGggd2lzaGluZyBmb3Iu" },
+ { "They say that it takes four quarterstaffs to make one staff.",
+ "VGhleSBzYXkgdGhhdCBpdCB0YWtlcyBmb3VyIHF1YXJ0ZXJzdGFmZnMgdG8gbWFrZSBvbmUgc3RhZmYu" },
+ { "They say that it's not over till the fat ladies sing.",
+ "VGhleSBzYXkgdGhhdCBpdCdzIG5vdCBvdmVyIHRpbGwgdGhlIGZhdCBsYWRpZXMgc2luZy4=" },
+ { "They say that it's not over till the fat lady shouts `Off with its head'.",
+ "VGhleSBzYXkgdGhhdCBpdCdzIG5vdCBvdmVyIHRpbGwgdGhlIGZhdCBsYWR5IHNob3V0cyBgT2ZmIHdpdGggaXRzIGhlYWQnLg==" },
+ { "They say that kicking a heavy statue is really a dumb move.",
+ "VGhleSBzYXkgdGhhdCBraWNraW5nIGEgaGVhdnkgc3RhdHVlIGlzIHJlYWxseSBhIGR1bWIgbW92ZS4=" },
+ { "They say that kicking a valuable gem doesn't seem to make sense.",
+ "VGhleSBzYXkgdGhhdCBraWNraW5nIGEgdmFsdWFibGUgZ2VtIGRvZXNuJ3Qgc2VlbSB0byBtYWtlIHNlbnNlLg==" },
+ { "They say that leprechauns know Latin and you should too.",
+ "VGhleSBzYXkgdGhhdCBsZXByZWNoYXVucyBrbm93IExhdGluIGFuZCB5b3Ugc2hvdWxkIHRvby4=" },
+ { "They say that minotaurs get lost outside of the mazes.",
+ "VGhleSBzYXkgdGhhdCBtaW5vdGF1cnMgZ2V0IGxvc3Qgb3V0c2lkZSBvZiB0aGUgbWF6ZXMu" },
+ { "They say that most trolls are born again.",
+ "VGhleSBzYXkgdGhhdCBtb3N0IHRyb2xscyBhcmUgYm9ybiBhZ2Fpbi4=" },
+ { "They say that naming your cat Garfield will make you more attractive.",
+ "VGhleSBzYXkgdGhhdCBuYW1pbmcgeW91ciBjYXQgR2FyZmllbGQgd2lsbCBtYWtlIHlvdSBtb3JlIGF0dHJhY3RpdmUu" },
+ { "They say that no one knows everything about everything in the dungeon.",
+ "VGhleSBzYXkgdGhhdCBubyBvbmUga25vd3MgZXZlcnl0aGluZyBhYm91dCBldmVyeXRoaW5nIGluIHRoZSBkdW5nZW9uLg==" },
+ { "They say that no one plays NetHack just for the fun of it.",
+ "VGhleSBzYXkgdGhhdCBubyBvbmUgcGxheXMgTmV0SGFjayBqdXN0IGZvciB0aGUgZnVuIG9mIGl0Lg==" },
+ { "They say that no one really subscribes to rec.games.roguelike.nethack.",
+ "VGhleSBzYXkgdGhhdCBubyBvbmUgcmVhbGx5IHN1YnNjcmliZXMgdG8gcmVjLmdhbWVzLnJvZ3VlbGlrZS5uZXRoYWNrLg==" },
+ { "They say that no one will admit to starting a rumor.",
+ "VGhleSBzYXkgdGhhdCBubyBvbmUgd2lsbCBhZG1pdCB0byBzdGFydGluZyBhIHJ1bW9yLg==" },
+ { "They say that nurses sometimes carry scalpels and never use them.",
+ "VGhleSBzYXkgdGhhdCBudXJzZXMgc29tZXRpbWVzIGNhcnJ5IHNjYWxwZWxzIGFuZCBuZXZlciB1c2UgdGhlbS4=" },
+ { "They say that once you've met one wizard you've met them all.",
+ "VGhleSBzYXkgdGhhdCBvbmNlIHlvdSd2ZSBtZXQgb25lIHdpemFyZCB5b3UndmUgbWV0IHRoZW0gYWxsLg==" },
+ { "They say that one troll is worth 10,000 newts.",
+ "VGhleSBzYXkgdGhhdCBvbmUgdHJvbGwgaXMgd29ydGggMTAsMDAwIG5ld3RzLg==" },
+ { "They say that only David can find the zoo!",
+ "VGhleSBzYXkgdGhhdCBvbmx5IERhdmlkIGNhbiBmaW5kIHRoZSB6b28h" },
+ { "They say that only angels play their harps for their pets.",
+ "VGhleSBzYXkgdGhhdCBvbmx5IGFuZ2VscyBwbGF5IHRoZWlyIGhhcnBzIGZvciB0aGVpciBwZXRzLg==" },
+ { "They say that only big spenders carry gold.",
+ "VGhleSBzYXkgdGhhdCBvbmx5IGJpZyBzcGVuZGVycyBjYXJyeSBnb2xkLg==" },
+ { "They say that orc shamans are healthy, wealthy and wise.",
+ "VGhleSBzYXkgdGhhdCBvcmMgc2hhbWFucyBhcmUgaGVhbHRoeSwgd2VhbHRoeSBhbmQgd2lzZS4=" },
+ { "They say that playing NetHack is like walking into a death trap.",
+ "VGhleSBzYXkgdGhhdCBwbGF5aW5nIE5ldEhhY2sgaXMgbGlrZSB3YWxraW5nIGludG8gYSBkZWF0aCB0cmFwLg==" },
+ { "They say that problem breathing is best treated by a proper diet.",
+ "VGhleSBzYXkgdGhhdCBwcm9ibGVtIGJyZWF0aGluZyBpcyBiZXN0IHRyZWF0ZWQgYnkgYSBwcm9wZXIgZGlldC4=" },
+ { "They say that quaffing many potions of levitation can give you a headache.",
+ "VGhleSBzYXkgdGhhdCBxdWFmZmluZyBtYW55IHBvdGlvbnMgb2YgbGV2aXRhdGlvbiBjYW4gZ2l2ZSB5b3UgYSBoZWFkYWNoZS4=" },
+ { "They say that queen bees get that way by eating royal jelly.",
+ "VGhleSBzYXkgdGhhdCBxdWVlbiBiZWVzIGdldCB0aGF0IHdheSBieSBlYXRpbmcgcm95YWwgamVsbHku" },
+ { "They say that reading a scare monster scroll is the same as saying Elbereth.",
+ "VGhleSBzYXkgdGhhdCByZWFkaW5nIGEgc2NhcmUgbW9uc3RlciBzY3JvbGwgaXMgdGhlIHNhbWUgYXMgc2F5aW5nIEVsYmVyZXRoLg==" },
+ { "They say that real hackers always are controlled.",
+ "VGhleSBzYXkgdGhhdCByZWFsIGhhY2tlcnMgYWx3YXlzIGFyZSBjb250cm9sbGVkLg==" },
+ { "They say that real hackers never sleep.",
+ "VGhleSBzYXkgdGhhdCByZWFsIGhhY2tlcnMgbmV2ZXIgc2xlZXAu" },
+ { "They say that shopkeepers are insured by Croesus himself!",
+ "VGhleSBzYXkgdGhhdCBzaG9wa2VlcGVycyBhcmUgaW5zdXJlZCBieSBDcm9lc3VzIGhpbXNlbGYh" },
+ { "They say that shopkeepers never carry more than 20 gold pieces, at night.",
+ "VGhleSBzYXkgdGhhdCBzaG9wa2VlcGVycyBuZXZlciBjYXJyeSBtb3JlIHRoYW4gMjAgZ29sZCBwaWVjZXMsIGF0IG5pZ2h0Lg==" },
+ { "They say that shopkeepers never sell blessed potions of invisibility.",
+ "VGhleSBzYXkgdGhhdCBzaG9wa2VlcGVycyBuZXZlciBzZWxsIGJsZXNzZWQgcG90aW9ucyBvZiBpbnZpc2liaWxpdHku" },
+ { "They say that soldiers wear kid gloves and silly helmets.",
+ "VGhleSBzYXkgdGhhdCBzb2xkaWVycyB3ZWFyIGtpZCBnbG92ZXMgYW5kIHNpbGx5IGhlbG1ldHMu" },
+ { "They say that some Kops are on the take.",
+ "VGhleSBzYXkgdGhhdCBzb21lIEtvcHMgYXJlIG9uIHRoZSB0YWtlLg==" },
+ { "They say that some guards' palms can be greased.",
+ "VGhleSBzYXkgdGhhdCBzb21lIGd1YXJkcycgcGFsbXMgY2FuIGJlIGdyZWFzZWQu" },
+ { "They say that some monsters may kiss your boots to stop your drum playing.",
+ "VGhleSBzYXkgdGhhdCBzb21lIG1vbnN0ZXJzIG1heSBraXNzIHlvdXIgYm9vdHMgdG8gc3RvcCB5b3VyIGRydW0gcGxheWluZy4=" },
+ { "They say that sometimes you can be the hit of the party when playing a horn.",
+ "VGhleSBzYXkgdGhhdCBzb21ldGltZXMgeW91IGNhbiBiZSB0aGUgaGl0IG9mIHRoZSBwYXJ0eSB3aGVuIHBsYXlpbmcgYSBob3JuLg==" },
+ { "They say that the NetHack gods generally welcome your sacrifices.",
+ "VGhleSBzYXkgdGhhdCB0aGUgTmV0SGFjayBnb2RzIGdlbmVyYWxseSB3ZWxjb21lIHlvdXIgc2FjcmlmaWNlcy4=" },
+ { "They say that the Three Rings are named Vilya, Nenya and Narya.",
+ "VGhleSBzYXkgdGhhdCB0aGUgVGhyZWUgUmluZ3MgYXJlIG5hbWVkIFZpbHlhLCBOZW55YSBhbmQgTmFyeWEu" },
+ { "They say that the Wizard of Yendor has a death wish.",
+ "VGhleSBzYXkgdGhhdCB0aGUgV2l6YXJkIG9mIFllbmRvciBoYXMgYSBkZWF0aCB3aXNoLg==" },
+ { "They say that the `hair of the dog' is sometimes an effective remedy.",
+ "VGhleSBzYXkgdGhhdCB0aGUgYGhhaXIgb2YgdGhlIGRvZycgaXMgc29tZXRpbWVzIGFuIGVmZmVjdGl2ZSByZW1lZHku" },
+ { "They say that the best time to save your game is now before its too late.",
+ "VGhleSBzYXkgdGhhdCB0aGUgYmVzdCB0aW1lIHRvIHNhdmUgeW91ciBnYW1lIGlzIG5vdyBiZWZvcmUgaXRzIHRvbyBsYXRlLg==" },
+ { "They say that the biggest obstacle in NetHack is your mind.",
+ "VGhleSBzYXkgdGhhdCB0aGUgYmlnZ2VzdCBvYnN0YWNsZSBpbiBOZXRIYWNrIGlzIHlvdXIgbWluZC4=" },
+ { "They say that the gods are angry when they hit you with objects.",
+ "VGhleSBzYXkgdGhhdCB0aGUgZ29kcyBhcmUgYW5ncnkgd2hlbiB0aGV5IGhpdCB5b3Ugd2l0aCBvYmplY3RzLg==" },
+ { "They say that the priesthood are specially favored by the gods.",
+ "VGhleSBzYXkgdGhhdCB0aGUgcHJpZXN0aG9vZCBhcmUgc3BlY2lhbGx5IGZhdm9yZWQgYnkgdGhlIGdvZHMu" },
+ { "They say that the way to make a unicorn happy is to give it what it wants.",
+ "VGhleSBzYXkgdGhhdCB0aGUgd2F5IHRvIG1ha2UgYSB1bmljb3JuIGhhcHB5IGlzIHRvIGdpdmUgaXQgd2hhdCBpdCB3YW50cy4=" },
+ { "They say that there are no black or white stones, only gray.",
+ "VGhleSBzYXkgdGhhdCB0aGVyZSBhcmUgbm8gYmxhY2sgb3Igd2hpdGUgc3RvbmVzLCBvbmx5IGdyYXku" },
+ { "They say that there are no skeletons hence there are no skeleton keys.",
+ "VGhleSBzYXkgdGhhdCB0aGVyZSBhcmUgbm8gc2tlbGV0b25zIGhlbmNlIHRoZXJlIGFyZSBubyBza2VsZXRvbiBrZXlzLg==" },
+ { "They say that there is a clever rogue in every hacker just dying to escape.",
+ "VGhleSBzYXkgdGhhdCB0aGVyZSBpcyBhIGNsZXZlciByb2d1ZSBpbiBldmVyeSBoYWNrZXIganVzdCBkeWluZyB0byBlc2NhcGUu" },
+ { "They say that there is no such thing as free advice.",
+ "VGhleSBzYXkgdGhhdCB0aGVyZSBpcyBubyBzdWNoIHRoaW5nIGFzIGZyZWUgYWR2aWNlLg==" },
+ { "They say that there is only one way to win at NetHack.",
+ "VGhleSBzYXkgdGhhdCB0aGVyZSBpcyBvbmx5IG9uZSB3YXkgdG8gd2luIGF0IE5ldEhhY2su" },
+ { "They say that there once was a fearsome chaotic samurai named Luk No.",
+ "VGhleSBzYXkgdGhhdCB0aGVyZSBvbmNlIHdhcyBhIGZlYXJzb21lIGNoYW90aWMgc2FtdXJhaSBuYW1lZCBMdWsgTm8u" },
+ { "They say that there was a time when cursed holy water wasn't water.",
+ "VGhleSBzYXkgdGhhdCB0aGVyZSB3YXMgYSB0aW1lIHdoZW4gY3Vyc2VkIGhvbHkgd2F0ZXIgd2Fzbid0IHdhdGVyLg==" },
+ { "They say that there's no point in crying over a gray ooze.",
+ "VGhleSBzYXkgdGhhdCB0aGVyZSdzIG5vIHBvaW50IGluIGNyeWluZyBvdmVyIGEgZ3JheSBvb3plLg==" },
+ { "They say that there's only hope left after you've opened Pandora's box.",
+ "VGhleSBzYXkgdGhhdCB0aGVyZSdzIG9ubHkgaG9wZSBsZWZ0IGFmdGVyIHlvdSd2ZSBvcGVuZWQgUGFuZG9yYSdzIGJveC4=" },
+ { "They say that trapdoors should always be marked `Caution: Trap Door'.",
+ "VGhleSBzYXkgdGhhdCB0cmFwZG9vcnMgc2hvdWxkIGFsd2F5cyBiZSBtYXJrZWQgYENhdXRpb246IFRyYXAgRG9vcicu" },
+ { "They say that using an amulet of change isn't a difficult operation.",
+ "VGhleSBzYXkgdGhhdCB1c2luZyBhbiBhbXVsZXQgb2YgY2hhbmdlIGlzbid0IGEgZGlmZmljdWx0IG9wZXJhdGlvbi4=" },
+ { "They say that water walking boots are better if you are fast like Hermes.",
+ "VGhleSBzYXkgdGhhdCB3YXRlciB3YWxraW5nIGJvb3RzIGFyZSBiZXR0ZXIgaWYgeW91IGFyZSBmYXN0IGxpa2UgSGVybWVzLg==" },
+ { "They say that when you wear a circular amulet you might resemble a troll.",
+ "VGhleSBzYXkgdGhhdCB3aGVuIHlvdSB3ZWFyIGEgY2lyY3VsYXIgYW11bGV0IHlvdSBtaWdodCByZXNlbWJsZSBhIHRyb2xsLg==" },
+ { "They say that when you're hungry you can get a pizza in 30 moves or it's free.",
+ "VGhleSBzYXkgdGhhdCB3aGVuIHlvdSdyZSBodW5ncnkgeW91IGNhbiBnZXQgYSBwaXp6YSBpbiAzMCBtb3ZlcyBvciBpdCdzIGZyZWUu" },
+ { "They say that when your god is angry you should try another one.",
+ "VGhleSBzYXkgdGhhdCB3aGVuIHlvdXIgZ29kIGlzIGFuZ3J5IHlvdSBzaG91bGQgdHJ5IGFub3RoZXIgb25lLg==" },
+ { "They say that wielding a unicorn horn takes strength.",
+ "VGhleSBzYXkgdGhhdCB3aWVsZGluZyBhIHVuaWNvcm4gaG9ybiB0YWtlcyBzdHJlbmd0aC4=" },
+ { "They say that with speed boots you never worry about hit and run accidents.",
+ "VGhleSBzYXkgdGhhdCB3aXRoIHNwZWVkIGJvb3RzIHlvdSBuZXZlciB3b3JyeSBhYm91dCBoaXQgYW5kIHJ1biBhY2NpZGVudHMu" },
+ { "They say that you can defeat a killer bee with a unicorn horn.",
+ "VGhleSBzYXkgdGhhdCB5b3UgY2FuIGRlZmVhdCBhIGtpbGxlciBiZWUgd2l0aCBhIHVuaWNvcm4gaG9ybi4=" },
+ { "They say that you can only cross the River Styx in Charon's boat.",
+ "VGhleSBzYXkgdGhhdCB5b3UgY2FuIG9ubHkgY3Jvc3MgdGhlIFJpdmVyIFN0eXggaW4gQ2hhcm9uJ3MgYm9hdC4=" },
+ { "They say that you can only kill a lich once and then you'd better be careful.",
+ "VGhleSBzYXkgdGhhdCB5b3UgY2FuIG9ubHkga2lsbCBhIGxpY2ggb25jZSBhbmQgdGhlbiB5b3UnZCBiZXR0ZXIgYmUgY2FyZWZ1bC4=" },
+ { "They say that you can only wish for things you've already had.",
+ "VGhleSBzYXkgdGhhdCB5b3UgY2FuIG9ubHkgd2lzaCBmb3IgdGhpbmdzIHlvdSd2ZSBhbHJlYWR5IGhhZC4=" },
+ { "They say that you can train a cat by talking gently to it.",
+ "VGhleSBzYXkgdGhhdCB5b3UgY2FuIHRyYWluIGEgY2F0IGJ5IHRhbGtpbmcgZ2VudGx5IHRvIGl0Lg==" },
+ { "They say that you can train a dog by talking firmly to it.",
+ "VGhleSBzYXkgdGhhdCB5b3UgY2FuIHRyYWluIGEgZG9nIGJ5IHRhbGtpbmcgZmlybWx5IHRvIGl0Lg==" },
+ { "They say that you can trust your gold with the king.",
+ "VGhleSBzYXkgdGhhdCB5b3UgY2FuIHRydXN0IHlvdXIgZ29sZCB3aXRoIHRoZSBraW5nLg==" },
+ { "They say that you can't wipe your greasy bare hands on a blank scroll.",
+ "VGhleSBzYXkgdGhhdCB5b3UgY2FuJ3Qgd2lwZSB5b3VyIGdyZWFzeSBiYXJlIGhhbmRzIG9uIGEgYmxhbmsgc2Nyb2xsLg==" },
+ { "They say that you cannot trust scrolls of rumor.",
+ "VGhleSBzYXkgdGhhdCB5b3UgY2Fubm90IHRydXN0IHNjcm9sbHMgb2YgcnVtb3Iu" },
+ { "They say that you could fall head over heels for an energy vortex.",
+ "VGhleSBzYXkgdGhhdCB5b3UgY291bGQgZmFsbCBoZWFkIG92ZXIgaGVlbHMgZm9yIGFuIGVuZXJneSB2b3J0ZXgu" },
+ { "They say that you need a key in order to open locked doors.",
+ "VGhleSBzYXkgdGhhdCB5b3UgbmVlZCBhIGtleSBpbiBvcmRlciB0byBvcGVuIGxvY2tlZCBkb29ycy4=" },
+ { "They say that you need a mirror to notice a mimic in an antique shop.",
+ "VGhleSBzYXkgdGhhdCB5b3UgbmVlZCBhIG1pcnJvciB0byBub3RpY2UgYSBtaW1pYyBpbiBhbiBhbnRpcXVlIHNob3Au" },
+ { "They say that you really can use a pick-axe unless you really can't.",
+ "VGhleSBzYXkgdGhhdCB5b3UgcmVhbGx5IGNhbiB1c2UgYSBwaWNrLWF4ZSB1bmxlc3MgeW91IHJlYWxseSBjYW4ndC4=" },
+ { "They say that you should always store your tools in the cellar.",
+ "VGhleSBzYXkgdGhhdCB5b3Ugc2hvdWxkIGFsd2F5cyBzdG9yZSB5b3VyIHRvb2xzIGluIHRoZSBjZWxsYXIu" },
+ { "They say that you should be careful while climbing the ladder to success.",
+ "VGhleSBzYXkgdGhhdCB5b3Ugc2hvdWxkIGJlIGNhcmVmdWwgd2hpbGUgY2xpbWJpbmcgdGhlIGxhZGRlciB0byBzdWNjZXNzLg==" },
+ { "They say that you should call your armor `rustproof'.",
+ "VGhleSBzYXkgdGhhdCB5b3Ugc2hvdWxkIGNhbGwgeW91ciBhcm1vciBgcnVzdHByb29mJy4=" },
+ { "They say that you should name your dog Spuds to have a cool pet.",
+ "VGhleSBzYXkgdGhhdCB5b3Ugc2hvdWxkIG5hbWUgeW91ciBkb2cgU3B1ZHMgdG8gaGF2ZSBhIGNvb2wgcGV0Lg==" },
+ { "They say that you should name your weapon after your first monster kill.",
+ "VGhleSBzYXkgdGhhdCB5b3Ugc2hvdWxkIG5hbWUgeW91ciB3ZWFwb24gYWZ0ZXIgeW91ciBmaXJzdCBtb25zdGVyIGtpbGwu" },
+ { "They say that you should never introduce a rope golem to a succubus.",
+ "VGhleSBzYXkgdGhhdCB5b3Ugc2hvdWxkIG5ldmVyIGludHJvZHVjZSBhIHJvcGUgZ29sZW0gdG8gYSBzdWNjdWJ1cy4=" },
+ { "They say that you should never sleep near invisible ring wraiths.",
+ "VGhleSBzYXkgdGhhdCB5b3Ugc2hvdWxkIG5ldmVyIHNsZWVwIG5lYXIgaW52aXNpYmxlIHJpbmcgd3JhaXRocy4=" },
+ { "They say that you should never try to leave the dungeon with a bag of gems.",
+ "VGhleSBzYXkgdGhhdCB5b3Ugc2hvdWxkIG5ldmVyIHRyeSB0byBsZWF2ZSB0aGUgZHVuZ2VvbiB3aXRoIGEgYmFnIG9mIGdlbXMu" },
+ { "They say that you should remove your armor before sitting on a throne.",
+ "VGhleSBzYXkgdGhhdCB5b3Ugc2hvdWxkIHJlbW92ZSB5b3VyIGFybW9yIGJlZm9yZSBzaXR0aW5nIG9uIGEgdGhyb25lLg==" },
+ { "This fortune cookie is copy protected.",
+ "VGhpcyBmb3J0dW5lIGNvb2tpZSBpcyBjb3B5IHByb3RlY3RlZC4=" },
+ { "This fortune cookie is the property of Fortune Cookies, Inc.",
+ "VGhpcyBmb3J0dW5lIGNvb2tpZSBpcyB0aGUgcHJvcGVydHkgb2YgRm9ydHVuZSBDb29raWVzLCBJbmMu" },
+ { "Tired? Try a scroll of charging on yourself.",
+ "VGlyZWQ/IFRyeSBhIHNjcm9sbCBvZiBjaGFyZ2luZyBvbiB5b3Vyc2VsZi4=" },
+ { "To achieve the next higher rating, you need 3 more points.",
+ "VG8gYWNoaWV2ZSB0aGUgbmV4dCBoaWdoZXIgcmF0aW5nLCB5b3UgbmVlZCAzIG1vcmUgcG9pbnRzLg==" },
+ { "To reach heaven, escape the dungeon while wearing a ring of levitation.",
+ "VG8gcmVhY2ggaGVhdmVuLCBlc2NhcGUgdGhlIGR1bmdlb24gd2hpbGUgd2VhcmluZyBhIHJpbmcgb2YgbGV2aXRhdGlvbi4=" },
+ { "Tourists wear shirts loud enough to wake the dead.",
+ "VG91cmlzdHMgd2VhciBzaGlydHMgbG91ZCBlbm91Z2ggdG8gd2FrZSB0aGUgZGVhZC4=" },
+ { "Try calling your katana Moulinette.",
+ "VHJ5IGNhbGxpbmcgeW91ciBrYXRhbmEgTW91bGluZXR0ZS4=" },
+ { "Ulch! That meat was painted!",
+ "VWxjaCEgVGhhdCBtZWF0IHdhcyBwYWludGVkIQ==" },
+ { "Unfortunately, this message was left intentionally blank.",
+ "VW5mb3J0dW5hdGVseSwgdGhpcyBtZXNzYWdlIHdhcyBsZWZ0IGludGVudGlvbmFsbHkgYmxhbmsu" },
+ { "Using a morning star in the evening has no effect.",
+ "VXNpbmcgYSBtb3JuaW5nIHN0YXIgaW4gdGhlIGV2ZW5pbmcgaGFzIG5vIGVmZmVjdC4=" },
+ { "Want a hint? Zap a wand of make invisible on your weapon!",
+ "V2FudCBhIGhpbnQ/IFphcCBhIHdhbmQgb2YgbWFrZSBpbnZpc2libGUgb24geW91ciB3ZWFwb24h" },
+ { "Want to ascend in a hurry? Apply at Gizmonic Institute.",
+ "V2FudCB0byBhc2NlbmQgaW4gYSBodXJyeT8gQXBwbHkgYXQgR2l6bW9uaWMgSW5zdGl0dXRlLg==" },
+ { "Wanted: shopkeepers. Send a scroll of mail to Mage of Yendor/Level 35/Dungeon.",
+ "V2FudGVkOiBzaG9wa2VlcGVycy4gU2VuZCBhIHNjcm9sbCBvZiBtYWlsIHRvIE1hZ2Ugb2YgWWVuZG9yL0xldmVsIDM1L0R1bmdlb24u" },
+ { "Warning: fortune reading can be hazardous to your health.",
+ "V2FybmluZzogZm9ydHVuZSByZWFkaW5nIGNhbiBiZSBoYXphcmRvdXMgdG8geW91ciBoZWFsdGgu" },
+ { "We have new ways of detecting treachery...",
+ "V2UgaGF2ZSBuZXcgd2F5cyBvZiBkZXRlY3RpbmcgdHJlYWNoZXJ5Li4u" },
+ { "Wet towels make great weapons!",
+ "V2V0IHRvd2VscyBtYWtlIGdyZWF0IHdlYXBvbnMh" },
+ { "What a pity, you cannot read it!",
+ "V2hhdCBhIHBpdHksIHlvdSBjYW5ub3QgcmVhZCBpdCE=" },
+ { "When a piercer drops in on you, you will be tempted to hit the ceiling!",
+ "V2hlbiBhIHBpZXJjZXIgZHJvcHMgaW4gb24geW91LCB5b3Ugd2lsbCBiZSB0ZW1wdGVkIHRvIGhpdCB0aGUgY2VpbGluZyE=" },
+ { "When in a maze follow the right wall and you will never get lost.",
+ "V2hlbiBpbiBhIG1hemUgZm9sbG93IHRoZSByaWdodCB3YWxsIGFuZCB5b3Ugd2lsbCBuZXZlciBnZXQgbG9zdC4=" },
+ { "When you have a key, you don't have to wait for the guard.",
+ "V2hlbiB5b3UgaGF2ZSBhIGtleSwgeW91IGRvbid0IGhhdmUgdG8gd2FpdCBmb3IgdGhlIGd1YXJkLg==" },
+ { "Why are you wasting time reading fortunes?",
+ "V2h5IGFyZSB5b3Ugd2FzdGluZyB0aW1lIHJlYWRpbmcgZm9ydHVuZXM/" },
+ { "Wish for a master key and open the Magic Memory Vault!",
+ "V2lzaCBmb3IgYSBtYXN0ZXIga2V5IGFuZCBvcGVuIHRoZSBNYWdpYyBNZW1vcnkgVmF1bHQh" },
+ { "Wizard expects every monster to do its duty.",
+ "V2l6YXJkIGV4cGVjdHMgZXZlcnkgbW9uc3RlciB0byBkbyBpdHMgZHV0eS4=" },
+ { "Wow! You could've had a potion of fruit juice!",
+ "V293ISBZb3UgY291bGQndmUgaGFkIGEgcG90aW9uIG9mIGZydWl0IGp1aWNlIQ==" },
+ { "Yet Another Silly Message (YASM).",
+ "WWV0IEFub3RoZXIgU2lsbHkgTWVzc2FnZSAoWUFTTSku" },
+ { "You are destined to be misled by a fortune.",
+ "WW91IGFyZSBkZXN0aW5lZCB0byBiZSBtaXNsZWQgYnkgYSBmb3J0dW5lLg==" },
+ { "You can get a genuine Amulet of Yendor by doing the following: --More--",
+ "WW91IGNhbiBnZXQgYSBnZW51aW5lIEFtdWxldCBvZiBZZW5kb3IgYnkgZG9pbmcgdGhlIGZvbGxvd2luZzogLS1Nb3JlLS0=" },
+ { "You can protect yourself from black dragons by doing the following: --More--",
+ "WW91IGNhbiBwcm90ZWN0IHlvdXJzZWxmIGZyb20gYmxhY2sgZHJhZ29ucyBieSBkb2luZyB0aGUgZm9sbG93aW5nOiAtLU1vcmUtLQ==" },
+ { "You can't get by the snake.",
+ "WW91IGNhbid0IGdldCBieSB0aGUgc25ha2Uu" },
+ { "You feel like someone is pulling your leg.",
+ "WW91IGZlZWwgbGlrZSBzb21lb25lIGlzIHB1bGxpbmcgeW91ciBsZWcu" },
+ { "You have to outwit the Sphynx or pay her.",
+ "WW91IGhhdmUgdG8gb3V0d2l0IHRoZSBTcGh5bnggb3IgcGF5IGhlci4=" },
+ { "You hear the fortune cookie's hissing!",
+ "WW91IGhlYXIgdGhlIGZvcnR1bmUgY29va2llJ3MgaGlzc2luZyE=" },
+ { "You may get rich selling letters, but beware of being blackmailed!",
+ "WW91IG1heSBnZXQgcmljaCBzZWxsaW5nIGxldHRlcnMsIGJ1dCBiZXdhcmUgb2YgYmVpbmcgYmxhY2ttYWlsZWQh" },
+ { "You offend Shai-Hulud by sheathing your crysknife without having drawn blood.",
+ "WW91IG9mZmVuZCBTaGFpLUh1bHVkIGJ5IHNoZWF0aGluZyB5b3VyIGNyeXNrbmlmZSB3aXRob3V0IGhhdmluZyBkcmF3biBibG9vZC4=" },
+ { "You swallowed the fortune!",
+ "WW91IHN3YWxsb3dlZCB0aGUgZm9ydHVuZSE=" },
+ { "You want to regain strength? Two levels ahead is a guesthouse!",
+ "WW91IHdhbnQgdG8gcmVnYWluIHN0cmVuZ3RoPyBUd28gbGV2ZWxzIGFoZWFkIGlzIGEgZ3Vlc3Rob3VzZSE=" },
+ { "You will encounter a tall, dark, and gruesome creature...",
+ "WW91IHdpbGwgZW5jb3VudGVyIGEgdGFsbCwgZGFyaywgYW5kIGdydWVzb21lIGNyZWF0dXJlLi4u" },
+
+ { "The End", "VGhlIEVuZA==" }
+ };
+
+/* PL_Base64Encode, random strings */
+PRBool test_004(void)
+{
+ int i;
+ char result[ 4096 ];
+
+ printf("Test 004 (PL_Base64Encode, random strings) ..."); fflush(stdout);
+
+ for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+ {
+ PRUint32 plen = PL_strlen(array[i].plaintext);
+ PRUint32 clen = ((plen + 2)/3)*4;
+
+ char *rv = PL_Base64Encode(array[i].plaintext, plen, result);
+
+ if( rv != result )
+ {
+ printf("FAIL\n\t(%d): return value\n", i);
+ return PR_FALSE;
+ }
+
+ if( 0 != PL_strncmp(result, array[i].cyphertext, clen) )
+ {
+ printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%.*s.\"\n",
+ i, array[i].plaintext, array[i].cyphertext, clen, result);
+ return PR_FALSE;
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_Base64Encode, single characters, malloc */
+PRBool test_005(void)
+{
+ PRUint32 a, b;
+ unsigned char plain[ 4 ];
+ unsigned char cypher[ 5 ];
+ char *rv;
+
+ printf("Test 005 (PL_Base64Encode, single characters, malloc) ..."); fflush(stdout);
+
+ plain[1] = plain[2] = plain[3] = (unsigned char)0;
+ cypher[2] = cypher[3] = (unsigned char)'=';
+ cypher[4] = (unsigned char)0;
+
+ for( a = 0; a < 64; a++ )
+ {
+ cypher[0] = base[a];
+
+ for( b = 0; b < 4; b++ )
+ {
+ plain[0] = (unsigned char)(a * 4 + b);
+ cypher[1] = base[(b * 16)];
+
+ rv = PL_Base64Encode((char *)plain, 1, (char *)0);
+ if( (char *)0 == rv )
+ {
+ printf("FAIL\n\t(%d, %d): no return value\n", a, b);
+ return PR_FALSE;
+ }
+
+ if( 0 != PL_strcmp((char *)cypher, rv) )
+ {
+ printf("FAIL\n\t(%d, %d): expected \"%s,\" got \"%s.\"\n",
+ a, b, cypher, rv);
+ PR_DELETE(rv);
+ return PR_FALSE;
+ }
+
+ PR_DELETE(rv);
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_Base64Encode, double characters, malloc */
+PRBool test_006(void)
+{
+ PRUint32 a, b, c, d;
+ unsigned char plain[ 4 ];
+ unsigned char cypher[ 5 ];
+ char *rv;
+
+ printf("Test 006 (PL_Base64Encode, double characters, malloc) ..."); fflush(stdout);
+
+ plain[2] = plain[3] = (unsigned char)0;
+ cypher[3] = (unsigned char)'=';
+ cypher[4] = (unsigned char)0;
+
+ for( a = 0; a < 64; a++ )
+ {
+ cypher[0] = base[a];
+ for( b = 0; b < 4; b++ )
+ {
+ plain[0] = (a*4) + b;
+ for( c = 0; c < 16; c++ )
+ {
+ cypher[1] = base[b*16 + c];
+ for( d = 0; d < 16; d++ )
+ {
+ plain[1] = c*16 + d;
+ cypher[2] = base[d*4];
+
+ rv = PL_Base64Encode((char *)plain, 2, (char *)0);
+ if( (char *)0 == rv )
+ {
+ printf("FAIL\n\t(%d, %d, %d, %d): no return value\n", a, b, c, d);
+ return PR_FALSE;
+ }
+
+ if( 0 != PL_strcmp((char *)cypher, rv) )
+ {
+ printf("FAIL\n\t(%d, %d, %d, %d): expected \"%s,\" got \"%s.\"\n",
+ a, b, c, d, cypher, rv);
+ PR_DELETE(rv);
+ return PR_FALSE;
+ }
+
+ PR_DELETE(rv);
+ }
+ }
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_Base64Encode, triple characters, malloc */
+PRBool test_007(void)
+{
+ PRUint32 a, b, c, d, e, f;
+ unsigned char plain[ 4 ];
+ unsigned char cypher[ 5 ];
+ char *rv;
+
+ printf("Test 007 (PL_Base64Encode, triple characters, malloc) ..."); fflush(stdout);
+
+ cypher[4] = (unsigned char)0;
+
+ for( a = 0; a < 64; a++ )
+ {
+ cypher[0] = base[a];
+ for( b = 0; b < 4; b++ )
+ {
+ plain[0] = (a*4) + b;
+ for( c = 0; c < 16; c++ )
+ {
+ cypher[1] = base[b*16 + c];
+ for( d = 0; d < 16; d++ )
+ {
+ plain[1] = c*16 + d;
+ for( e = 0; e < 4; e++ )
+ {
+ cypher[2] = base[d*4 + e];
+ for( f = 0; f < 64; f++ )
+ {
+ plain[2] = e * 64 + f;
+ cypher[3] = base[f];
+
+ rv = PL_Base64Encode((char *)plain, 3, (char *)0);
+ if( (char *)0 == rv )
+ {
+ printf("FAIL\n\t(%d, %d, %d, %d, %d, %d): no return value\n", a, b, c, d, e, f);
+ return PR_FALSE;
+ }
+
+ if( 0 != PL_strcmp((char *)cypher, rv) )
+ {
+ printf("FAIL\n\t(%d, %d, %d, %d, %d, %d): expected \"%s,\" got \"%.4s.\"\n",
+ a, b, c, d, e, f, cypher, rv);
+ PR_DELETE(rv);
+ return PR_FALSE;
+ }
+
+ PR_DELETE(rv);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_Base64Encode, random strings, malloc */
+PRBool test_008(void)
+{
+ int i;
+
+ printf("Test 008 (PL_Base64Encode, random strings, malloc) ..."); fflush(stdout);
+
+ for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+ {
+ PRUint32 plen = PL_strlen(array[i].plaintext);
+ PRUint32 clen = ((plen + 2)/3)*4;
+
+ char *rv = PL_Base64Encode(array[i].plaintext, plen, (char *)0);
+
+ if( (char *)0 == rv )
+ {
+ printf("FAIL\n\t(%d): no return value\n", i);
+ return PR_FALSE;
+ }
+
+ if( 0 != PL_strcmp(rv, array[i].cyphertext) )
+ {
+ printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%s.\"\n",
+ i, array[i].plaintext, array[i].cyphertext, rv);
+ return PR_FALSE;
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_Base64Decode, single characters */
+PRBool test_009(void)
+{
+ PRUint32 a, b;
+ unsigned char plain[ 4 ];
+ unsigned char cypher[ 5 ];
+ char result[ 8 ];
+ char *rv;
+
+ printf("Test 009 (PL_Base64Decode, single characters, equals) ..."); fflush(stdout);
+
+ plain[1] = plain[2] = plain[3] = (unsigned char)0;
+ cypher[2] = cypher[3] = (unsigned char)'=';
+ cypher[4] = (unsigned char)0;
+
+ for( a = 0; a < 64; a++ )
+ {
+ cypher[0] = base[a];
+
+ for( b = 0; b < 4; b++ )
+ {
+ plain[0] = (unsigned char)(a * 4 + b);
+ cypher[1] = base[(b * 16)];
+
+ rv = PL_Base64Decode((char *)cypher, 4, result);
+ if( rv != result )
+ {
+ printf("FAIL\n\t(%d, %d): return value\n", a, b);
+ return PR_FALSE;
+ }
+
+ if( 0 != PL_strncmp((char *)plain, result, 1) )
+ {
+ printf("FAIL\n\t(%d, %d): expected \"%s,\" got \"%.1s.\"\n",
+ a, b, plain, result);
+ return PR_FALSE;
+ }
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_Base64Decode, single characters */
+PRBool test_010(void)
+{
+ PRUint32 a, b;
+ unsigned char plain[ 4 ];
+ unsigned char cypher[ 5 ];
+ char result[ 8 ];
+ char *rv;
+
+ printf("Test 010 (PL_Base64Decode, single characters, no equals) ..."); fflush(stdout);
+
+ plain[1] = plain[2] = plain[3] = (unsigned char)0;
+ cypher[2] = cypher[3] = (unsigned char)0;
+ cypher[4] = (unsigned char)0;
+
+ for( a = 0; a < 64; a++ )
+ {
+ cypher[0] = base[a];
+
+ for( b = 0; b < 4; b++ )
+ {
+ plain[0] = (unsigned char)(a * 4 + b);
+ cypher[1] = base[(b * 16)];
+
+ rv = PL_Base64Decode((char *)cypher, 2, result);
+ if( rv != result )
+ {
+ printf("FAIL\n\t(%d, %d): return value\n", a, b);
+ return PR_FALSE;
+ }
+
+ if( 0 != PL_strncmp((char *)plain, result, 1) )
+ {
+ printf("FAIL\n\t(%d, %d): expected \"%s,\" got \"%.1s.\"\n",
+ a, b, plain, result);
+ return PR_FALSE;
+ }
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_Base64Decode, double characters */
+PRBool test_011(void)
+{
+ PRUint32 a, b, c, d;
+ unsigned char plain[ 4 ];
+ unsigned char cypher[ 5 ];
+ char result[ 8 ];
+ char *rv;
+
+ printf("Test 011 (PL_Base64Decode, double characters, equals) ..."); fflush(stdout);
+
+ plain[2] = plain[3] = (unsigned char)0;
+ cypher[3] = (unsigned char)'=';
+ cypher[4] = (unsigned char)0;
+
+ for( a = 0; a < 64; a++ )
+ {
+ cypher[0] = base[a];
+ for( b = 0; b < 4; b++ )
+ {
+ plain[0] = (a*4) + b;
+ for( c = 0; c < 16; c++ )
+ {
+ cypher[1] = base[b*16 + c];
+ for( d = 0; d < 16; d++ )
+ {
+ plain[1] = c*16 + d;
+ cypher[2] = base[d*4];
+
+ rv = PL_Base64Decode((char *)cypher, 4, result);
+ if( rv != result )
+ {
+ printf("FAIL\n\t(%d, %d, %d, %d): return value\n", a, b, c, d);
+ return PR_FALSE;
+ }
+
+ if( 0 != PL_strncmp((char *)plain, result, 2) )
+ {
+ printf("FAIL\n\t(%d, %d, %d, %d): expected \"%s,\" got \"%.2s.\"\n",
+ a, b, c, d, plain, result);
+ return PR_FALSE;
+ }
+ }
+ }
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_Base64Decode, double characters */
+PRBool test_012(void)
+{
+ PRUint32 a, b, c, d;
+ unsigned char plain[ 4 ];
+ unsigned char cypher[ 5 ];
+ char result[ 8 ];
+ char *rv;
+
+ printf("Test 012 (PL_Base64Decode, double characters, no equals) ..."); fflush(stdout);
+
+ plain[2] = plain[3] = (unsigned char)0;
+ cypher[3] = (unsigned char)0;
+ cypher[4] = (unsigned char)0;
+
+ for( a = 0; a < 64; a++ )
+ {
+ cypher[0] = base[a];
+ for( b = 0; b < 4; b++ )
+ {
+ plain[0] = (a*4) + b;
+ for( c = 0; c < 16; c++ )
+ {
+ cypher[1] = base[b*16 + c];
+ for( d = 0; d < 16; d++ )
+ {
+ plain[1] = c*16 + d;
+ cypher[2] = base[d*4];
+
+ rv = PL_Base64Decode((char *)cypher, 3, result);
+ if( rv != result )
+ {
+ printf("FAIL\n\t(%d, %d, %d, %d): return value\n", a, b, c, d);
+ return PR_FALSE;
+ }
+
+ if( 0 != PL_strncmp((char *)plain, result, 2) )
+ {
+ printf("FAIL\n\t(%d, %d, %d, %d): expected \"%s,\" got \"%.2s.\"\n",
+ a, b, c, d, cypher, result);
+ return PR_FALSE;
+ }
+ }
+ }
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_Base64Decode, triple characters */
+PRBool test_013(void)
+{
+ PRUint32 a, b, c, d, e, f;
+ unsigned char plain[ 4 ];
+ unsigned char cypher[ 5 ];
+ char result[ 8 ];
+ char *rv;
+
+ printf("Test 013 (PL_Base64Decode, triple characters) ..."); fflush(stdout);
+
+ cypher[4] = (unsigned char)0;
+
+ for( a = 0; a < 64; a++ )
+ {
+ cypher[0] = base[a];
+ for( b = 0; b < 4; b++ )
+ {
+ plain[0] = (a*4) + b;
+ for( c = 0; c < 16; c++ )
+ {
+ cypher[1] = base[b*16 + c];
+ for( d = 0; d < 16; d++ )
+ {
+ plain[1] = c*16 + d;
+ for( e = 0; e < 4; e++ )
+ {
+ cypher[2] = base[d*4 + e];
+ for( f = 0; f < 64; f++ )
+ {
+ plain[2] = e * 64 + f;
+ cypher[3] = base[f];
+
+ rv = PL_Base64Decode((char *)cypher, 4, result);
+ if( rv != result )
+ {
+ printf("FAIL\n\t(%d, %d, %d, %d, %d, %d): return value\n", a, b, c, d, e, f);
+ return PR_FALSE;
+ }
+
+ if( 0 != PL_strncmp((char *)plain, result, 3) )
+ {
+ printf("FAIL\n\t(%d, %d, %d, %d, %d, %d): expected \"%s,\" got \"%.3s.\"\n",
+ a, b, c, d, e, f, plain, result);
+ return PR_FALSE;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_Base64Decode, random strings */
+PRBool test_014(void)
+{
+ int i;
+ char result[ 4096 ];
+
+ printf("Test 014 (PL_Base64Decode, random strings, equals) ..."); fflush(stdout);
+
+ for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+ {
+ PRUint32 clen = PL_strlen(array[i].cyphertext);
+ PRUint32 plen = (clen * 3) / 4;
+
+ char *rv = PL_Base64Decode(array[i].cyphertext, clen, result);
+
+ if( rv != result )
+ {
+ printf("FAIL\n\t(%d): return value\n", i);
+ return PR_FALSE;
+ }
+
+ if( 0 == (clen & 3) )
+ {
+ if( '=' == array[i].cyphertext[clen-1] )
+ {
+ if( '=' == array[i].cyphertext[clen-2] )
+ {
+ plen -= 2;
+ }
+ else
+ {
+ plen -= 1;
+ }
+ }
+ }
+
+ if( 0 != PL_strncmp(result, array[i].plaintext, plen) )
+ {
+ printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%.*s.\"\n",
+ i, array[i].cyphertext, array[i].plaintext, plen, result);
+ return PR_FALSE;
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_Base64Decode, random strings */
+PRBool test_015(void)
+{
+ int i;
+ char buffer[ 4096 ];
+ char result[ 4096 ];
+ char *rv;
+
+ printf("Test 015 (PL_Base64Decode, random strings, no equals) ..."); fflush(stdout);
+
+ for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+ {
+ PRUint32 clen, plen;
+
+ PL_strcpy(buffer, array[i].cyphertext);
+ clen = PL_strlen(buffer);
+
+ if( 0 == (clen & 3) )
+ {
+ if( '=' == buffer[clen-1] )
+ {
+ if( '=' == buffer[clen-2] )
+ {
+ buffer[clen-2] = buffer[clen-1] = (char)0;
+ clen -= 2;
+ }
+ else
+ {
+ buffer[clen-1] = (char)0;
+ clen -= 1;
+ }
+ }
+ }
+
+ plen = (clen * 3) / 4;
+
+ rv = PL_Base64Decode(buffer, clen, result);
+
+ if( rv != result )
+ {
+ printf("FAIL\n\t(%d): return value\n", i);
+ return PR_FALSE;
+ }
+
+ if( 0 != PL_strncmp(result, array[i].plaintext, plen) )
+ {
+ printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%.*s.\"\n",
+ i, array[i].cyphertext, array[i].plaintext, plen, result);
+ return PR_FALSE;
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_Base64Decode, single characters, malloc */
+PRBool test_016(void)
+{
+ PRUint32 a, b;
+ unsigned char plain[ 4 ];
+ unsigned char cypher[ 5 ];
+ char *rv;
+
+ printf("Test 016 (PL_Base64Decode, single characters, equals, malloc) ..."); fflush(stdout);
+
+ plain[1] = plain[2] = plain[3] = (unsigned char)0;
+ cypher[2] = cypher[3] = (unsigned char)'=';
+ cypher[4] = (unsigned char)0;
+
+ for( a = 0; a < 64; a++ )
+ {
+ cypher[0] = base[a];
+
+ for( b = 0; b < 4; b++ )
+ {
+ plain[0] = (unsigned char)(a * 4 + b);
+ cypher[1] = base[(b * 16)];
+
+ rv = PL_Base64Decode((char *)cypher, 4, (char *)0);
+ if( (char *)0 == rv )
+ {
+ printf("FAIL\n\t(%d, %d): no return value\n", a, b);
+ return PR_FALSE;
+ }
+
+ if( 0 != PL_strcmp((char *)plain, rv) )
+ {
+ printf("FAIL\n\t(%d, %d): expected \"%s,\" got \"%s.\"\n",
+ a, b, plain, rv);
+ PR_DELETE(rv);
+ return PR_FALSE;
+ }
+
+ PR_DELETE(rv);
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_Base64Decode, single characters, malloc */
+PRBool test_017(void)
+{
+ PRUint32 a, b;
+ unsigned char plain[ 4 ];
+ unsigned char cypher[ 5 ];
+ char *rv;
+
+ printf("Test 017 (PL_Base64Decode, single characters, no equals, malloc) ..."); fflush(stdout);
+
+ plain[1] = plain[2] = plain[3] = (unsigned char)0;
+ cypher[2] = cypher[3] = (unsigned char)0;
+ cypher[4] = (unsigned char)0;
+
+ for( a = 0; a < 64; a++ )
+ {
+ cypher[0] = base[a];
+
+ for( b = 0; b < 4; b++ )
+ {
+ plain[0] = (unsigned char)(a * 4 + b);
+ cypher[1] = base[(b * 16)];
+
+ rv = PL_Base64Decode((char *)cypher, 2, (char *)0);
+ if( (char *)0 == rv )
+ {
+ printf("FAIL\n\t(%d, %d): no return value\n", a, b);
+ return PR_FALSE;
+ }
+
+ if( 0 != PL_strcmp((char *)plain, rv) )
+ {
+ printf("FAIL\n\t(%d, %d): expected \"%s,\" got \"%s.\"\n",
+ a, b, plain, rv);
+ PR_DELETE(rv);
+ return PR_FALSE;
+ }
+
+ PR_DELETE(rv);
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_Base64Decode, double characters, malloc */
+PRBool test_018(void)
+{
+ PRUint32 a, b, c, d;
+ unsigned char plain[ 4 ];
+ unsigned char cypher[ 5 ];
+ char *rv;
+
+ printf("Test 018 (PL_Base64Decode, double characters, equals, malloc) ..."); fflush(stdout);
+
+ plain[2] = plain[3] = (unsigned char)0;
+ cypher[3] = (unsigned char)'=';
+ cypher[4] = (unsigned char)0;
+
+ for( a = 0; a < 64; a++ )
+ {
+ cypher[0] = base[a];
+ for( b = 0; b < 4; b++ )
+ {
+ plain[0] = (a*4) + b;
+ for( c = 0; c < 16; c++ )
+ {
+ cypher[1] = base[b*16 + c];
+ for( d = 0; d < 16; d++ )
+ {
+ plain[1] = c*16 + d;
+ cypher[2] = base[d*4];
+
+ rv = PL_Base64Decode((char *)cypher, 4, (char *)0);
+ if( (char *)0 == rv )
+ {
+ printf("FAIL\n\t(%d, %d, %d, %d): no return value\n", a, b, c, d);
+ return PR_FALSE;
+ }
+
+ if( 0 != PL_strcmp((char *)plain, rv) )
+ {
+ printf("FAIL\n\t(%d, %d, %d, %d): expected \"%s,\" got \"%s.\"\n",
+ a, b, c, d, plain, rv);
+ PR_DELETE(rv);
+ return PR_FALSE;
+ }
+
+ PR_DELETE(rv);
+ }
+ }
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_Base64Decode, double characters, malloc */
+PRBool test_019(void)
+{
+ PRUint32 a, b, c, d;
+ unsigned char plain[ 4 ];
+ unsigned char cypher[ 5 ];
+ char *rv;
+
+ printf("Test 019 (PL_Base64Decode, double characters, no equals, malloc) ..."); fflush(stdout);
+
+ plain[2] = plain[3] = (unsigned char)0;
+ cypher[3] = (unsigned char)0;
+ cypher[4] = (unsigned char)0;
+
+ for( a = 0; a < 64; a++ )
+ {
+ cypher[0] = base[a];
+ for( b = 0; b < 4; b++ )
+ {
+ plain[0] = (a*4) + b;
+ for( c = 0; c < 16; c++ )
+ {
+ cypher[1] = base[b*16 + c];
+ for( d = 0; d < 16; d++ )
+ {
+ plain[1] = c*16 + d;
+ cypher[2] = base[d*4];
+
+ rv = PL_Base64Decode((char *)cypher, 3, (char *)0);
+ if( (char *)0 == rv )
+ {
+ printf("FAIL\n\t(%d, %d, %d, %d): no return value\n", a, b, c, d);
+ return PR_FALSE;
+ }
+
+ if( 0 != PL_strcmp((char *)plain, rv) )
+ {
+ printf("FAIL\n\t(%d, %d, %d, %d): expected \"%s,\" got \"%s.\"\n",
+ a, b, c, d, cypher, rv);
+ PR_DELETE(rv);
+ return PR_FALSE;
+ }
+
+ PR_DELETE(rv);
+ }
+ }
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_Base64Decode, triple characters, malloc */
+PRBool test_020(void)
+{
+ PRUint32 a, b, c, d, e, f;
+ unsigned char plain[ 4 ];
+ unsigned char cypher[ 5 ];
+ char *rv;
+
+ printf("Test 020 (PL_Base64Decode, triple characters, malloc) ..."); fflush(stdout);
+
+ cypher[4] = (unsigned char)0;
+ plain[3] = (unsigned char)0;
+
+ for( a = 0; a < 64; a++ )
+ {
+ cypher[0] = base[a];
+ for( b = 0; b < 4; b++ )
+ {
+ plain[0] = (a*4) + b;
+ for( c = 0; c < 16; c++ )
+ {
+ cypher[1] = base[b*16 + c];
+ for( d = 0; d < 16; d++ )
+ {
+ plain[1] = c*16 + d;
+ for( e = 0; e < 4; e++ )
+ {
+ cypher[2] = base[d*4 + e];
+ for( f = 0; f < 64; f++ )
+ {
+ plain[2] = e * 64 + f;
+ cypher[3] = base[f];
+
+ rv = PL_Base64Decode((char *)cypher, 4, (char *)0);
+ if( (char *)0 == rv )
+ {
+ printf("FAIL\n\t(%d, %d, %d, %d, %d, %d): no return value\n", a, b, c, d, e, f);
+ return PR_FALSE;
+ }
+
+ if( 0 != PL_strcmp((char *)plain, rv) )
+ {
+ printf("FAIL\n\t(%d, %d, %d, %d, %d, %d): expected \"%s,\" got \"%.3s.\"\n",
+ a, b, c, d, e, f, plain, rv);
+ PR_DELETE(rv);
+ return PR_FALSE;
+ }
+
+ PR_DELETE(rv);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_Base64Decode, random strings, malloc */
+PRBool test_021(void)
+{
+ int i;
+
+ printf("Test 021 (PL_Base64Decode, random strings, equals, malloc) ..."); fflush(stdout);
+
+ for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+ {
+ PRUint32 clen = PL_strlen(array[i].cyphertext);
+
+ char *rv = PL_Base64Decode(array[i].cyphertext, clen, (char *)0);
+
+ if( (char *)0 == rv )
+ {
+ printf("FAIL\n\t(%d): no return value\n", i);
+ return PR_FALSE;
+ }
+
+ if( 0 != PL_strcmp(rv, array[i].plaintext) )
+ {
+ printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%s.\"\n",
+ i, array[i].cyphertext, array[i].plaintext, rv);
+ PR_DELETE(rv);
+ return PR_FALSE;
+ }
+
+ PR_DELETE(rv);
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_Base64Encode, random strings, malloc */
+PRBool test_022(void)
+{
+ int i;
+ char buffer[ 4096 ];
+ char *rv;
+
+ printf("Test 022 (PL_Base64Decode, random strings, no equals, malloc) ..."); fflush(stdout);
+
+ for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+ {
+ PRUint32 clen;
+
+ PL_strcpy(buffer, array[i].cyphertext);
+ clen = PL_strlen(buffer);
+
+ if( 0 == (clen & 3) )
+ {
+ if( '=' == buffer[clen-1] )
+ {
+ if( '=' == buffer[clen-2] )
+ {
+ buffer[clen-2] = buffer[clen-1] = (char)0;
+ clen -= 2;
+ }
+ else
+ {
+ buffer[clen-1] = (char)0;
+ clen -= 1;
+ }
+ }
+ }
+
+ rv = PL_Base64Decode(buffer, clen, (char *)0);
+
+ if( (char *)0 == rv )
+ {
+ printf("FAIL\n\t(%d): no return value\n", i);
+ return PR_FALSE;
+ }
+
+ if( 0 != PL_strcmp(rv, array[i].plaintext) )
+ {
+ printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%s.\"\n",
+ i, array[i].cyphertext, array[i].plaintext, rv);
+ return PR_FALSE;
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_Base64Encode, random strings */
+PRBool test_023(void)
+{
+ int i;
+ char result[ 4096 ];
+
+ printf("Test 023 (PL_Base64Encode, random strings, strlen) ..."); fflush(stdout);
+
+ for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+ {
+ PRUint32 plen = PL_strlen(array[i].plaintext);
+ PRUint32 clen = ((plen + 2)/3)*4;
+
+ char *rv = PL_Base64Encode(array[i].plaintext, 0, result);
+
+ if( rv != result )
+ {
+ printf("FAIL\n\t(%d): return value\n", i);
+ return PR_FALSE;
+ }
+
+ if( 0 != PL_strncmp(result, array[i].cyphertext, clen) )
+ {
+ printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%.*s.\"\n",
+ i, array[i].plaintext, array[i].cyphertext, clen, result);
+ return PR_FALSE;
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_Base64Encode, random strings, malloc */
+PRBool test_024(void)
+{
+ int i;
+
+ printf("Test 024 (PL_Base64Encode, random strings, malloc, strlen) ..."); fflush(stdout);
+
+ for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+ {
+ PRUint32 plen = PL_strlen(array[i].plaintext);
+ PRUint32 clen = ((plen + 2)/3)*4;
+
+ char *rv = PL_Base64Encode(array[i].plaintext, 0, (char *)0);
+
+ if( (char *)0 == rv )
+ {
+ printf("FAIL\n\t(%d): no return value\n", i);
+ return PR_FALSE;
+ }
+
+ if( 0 != PL_strcmp(rv, array[i].cyphertext) )
+ {
+ printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%s.\"\n",
+ i, array[i].plaintext, array[i].cyphertext, rv);
+ return PR_FALSE;
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_Base64Decode, random strings */
+PRBool test_025(void)
+{
+ int i;
+ char result[ 4096 ];
+
+ printf("Test 025 (PL_Base64Decode, random strings, equals, strlen) ..."); fflush(stdout);
+
+ for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+ {
+ PRUint32 clen = PL_strlen(array[i].cyphertext);
+ PRUint32 plen = (clen * 3) / 4;
+
+ char *rv = PL_Base64Decode(array[i].cyphertext, 0, result);
+
+ if( rv != result )
+ {
+ printf("FAIL\n\t(%d): return value\n", i);
+ return PR_FALSE;
+ }
+
+ if( 0 == (clen & 3) )
+ {
+ if( '=' == array[i].cyphertext[clen-1] )
+ {
+ if( '=' == array[i].cyphertext[clen-2] )
+ {
+ plen -= 2;
+ }
+ else
+ {
+ plen -= 1;
+ }
+ }
+ }
+
+ if( 0 != PL_strncmp(result, array[i].plaintext, plen) )
+ {
+ printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%.*s.\"\n",
+ i, array[i].cyphertext, array[i].plaintext, plen, result);
+ return PR_FALSE;
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_Base64Decode, random strings */
+PRBool test_026(void)
+{
+ int i;
+ char buffer[ 4096 ];
+ char result[ 4096 ];
+ char *rv;
+
+ printf("Test 026 (PL_Base64Decode, random strings, no equals, strlen) ..."); fflush(stdout);
+
+ for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+ {
+ PRUint32 clen, plen;
+
+ PL_strcpy(buffer, array[i].cyphertext);
+ clen = PL_strlen(buffer);
+
+ if( 0 == (clen & 3) )
+ {
+ if( '=' == buffer[clen-1] )
+ {
+ if( '=' == buffer[clen-2] )
+ {
+ buffer[clen-2] = buffer[clen-1] = (char)0;
+ clen -= 2;
+ }
+ else
+ {
+ buffer[clen-1] = (char)0;
+ clen -= 1;
+ }
+ }
+ }
+
+ plen = (clen * 3) / 4;
+
+ rv = PL_Base64Decode(buffer, 0, result);
+
+ if( rv != result )
+ {
+ printf("FAIL\n\t(%d): return value\n", i);
+ return PR_FALSE;
+ }
+
+ if( 0 != PL_strncmp(result, array[i].plaintext, plen) )
+ {
+ printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%.*s.\"\n",
+ i, array[i].cyphertext, array[i].plaintext, plen, result);
+ return PR_FALSE;
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_Base64Decode, random strings, malloc */
+PRBool test_027(void)
+{
+ int i;
+
+ printf("Test 027 (PL_Base64Decode, random strings, equals, malloc, strlen) ..."); fflush(stdout);
+
+ for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+ {
+ PRUint32 clen = PL_strlen(array[i].cyphertext);
+
+ char *rv = PL_Base64Decode(array[i].cyphertext, 0, (char *)0);
+
+ if( (char *)0 == rv )
+ {
+ printf("FAIL\n\t(%d): no return value\n", i);
+ return PR_FALSE;
+ }
+
+ if( 0 != PL_strcmp(rv, array[i].plaintext) )
+ {
+ printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%s.\"\n",
+ i, array[i].cyphertext, array[i].plaintext, rv);
+ PR_DELETE(rv);
+ return PR_FALSE;
+ }
+
+ PR_DELETE(rv);
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_Base64Encode, random strings, malloc */
+PRBool test_028(void)
+{
+ int i;
+ char buffer[ 4096 ];
+ char *rv;
+
+ printf("Test 028 (PL_Base64Decode, random strings, no equals, malloc, strlen) ..."); fflush(stdout);
+
+ for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+ {
+ PRUint32 clen;
+
+ PL_strcpy(buffer, array[i].cyphertext);
+ clen = PL_strlen(buffer);
+
+ if( 0 == (clen & 3) )
+ {
+ if( '=' == buffer[clen-1] )
+ {
+ if( '=' == buffer[clen-2] )
+ {
+ buffer[clen-2] = buffer[clen-1] = (char)0;
+ clen -= 2;
+ }
+ else
+ {
+ buffer[clen-1] = (char)0;
+ clen -= 1;
+ }
+ }
+ }
+
+ rv = PL_Base64Decode(buffer, 0, (char *)0);
+
+ if( (char *)0 == rv )
+ {
+ printf("FAIL\n\t(%d): no return value\n", i);
+ return PR_FALSE;
+ }
+
+ if( 0 != PL_strcmp(rv, array[i].plaintext) )
+ {
+ printf("FAIL\n\t(%d, \"%s\"): expected \n\"%s,\" got \n\"%s.\"\n",
+ i, array[i].cyphertext, array[i].plaintext, rv);
+ return PR_FALSE;
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+int
+main
+(
+ int argc,
+ char *argv[]
+)
+{
+ printf("Testing the Portable Library base64 functions:\n");
+ printf("(warning: the \"triple characters\" tests are slow)\n");
+
+ if( 1
+ && test_001()
+ && test_002()
+ && test_003()
+ && test_004()
+ && test_005()
+ && test_006()
+ && test_007()
+ && test_008()
+ && test_009()
+ && test_010()
+ && test_011()
+ && test_012()
+ && test_013()
+ && test_014()
+ && test_015()
+ && test_016()
+ && test_017()
+ && test_018()
+ && test_019()
+ && test_020()
+ && test_021()
+ && test_022()
+ && test_023()
+ && test_024()
+ && test_025()
+ && test_026()
+ && test_027()
+ && test_028()
+ )
+ {
+ printf("Suite passed.\n");
+ return 0;
+ }
+ else
+ {
+ printf("Suite failed.\n");
+ return 1;
+ }
+
+ /*NOTREACHED*/
+}
diff --git a/src/libs/xpcom18a4/nsprpub/lib/tests/string.c b/src/libs/xpcom18a4/nsprpub/lib/tests/string.c
new file mode 100644
index 00000000..482e17b5
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/tests/string.c
@@ -0,0 +1,3116 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "plstr.h"
+#include "nspr.h"
+
+#include <stdio.h>
+
+/* PL_strlen */
+PRBool test_001(void)
+{
+ static struct
+ {
+ const char *str;
+ PRUint32 len;
+ } array[] =
+ {
+ { (const char *)0, 0 },
+ { "", 0 },
+ { "a", 1 },
+ { "abcdefg", 7 },
+ { "abcdefg\0hijk", 7 }
+ };
+
+ int i;
+
+ printf("Test 001 (PL_strlen) ..."); fflush(stdout);
+
+ for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+ {
+ if( PL_strlen(array[i].str) != array[i].len )
+ {
+ printf("FAIL (%d: %s->%d, %d)\n", i,
+ array[i].str ? array[i].str : "(null)",
+ PL_strlen(array[i].str), array[i].len);
+ return PR_FALSE;
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_strnlen */
+PRBool test_002(void)
+{
+ static struct
+ {
+ const char *str;
+ PRUint32 max;
+ PRUint32 len;
+ } array[] =
+ {
+ { (const char *)0, 0, 0 },
+ { (const char *)0, 12, 0 },
+ { "", 0, 0 },
+ { "", 12, 0 },
+ { "a", 0, 0 },
+ { "a", 1, 1 },
+ { "a", 12, 1 },
+ { "abcdefg", 0, 0 },
+ { "abcdefg", 1, 1 },
+ { "abcdefg", 7, 7 },
+ { "abcdefg", 12, 7 },
+ { "abcdefg\0hijk", 0, 0 },
+ { "abcdefg\0hijk", 1, 1 },
+ { "abcdefg\0hijk", 7, 7 },
+ { "abcdefg\0hijk", 12, 7 },
+ };
+
+ int i;
+
+ printf("Test 002 (PL_strnlen) ..."); fflush(stdout);
+
+ for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+ {
+ if( PL_strnlen(array[i].str, array[i].max) != array[i].len )
+ {
+ printf("FAIL (%d: %s,%d->%d, %d)\n", i,
+ array[i].str ? array[i].str : "(null)", array[i].max,
+ PL_strnlen(array[i].str, array[i].max), array[i].len);
+ return PR_FALSE;
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_strcpy */
+PRBool test_003(void)
+{
+ static char buffer[ 1024 ];
+
+ static struct
+ {
+ const char *str;
+ char *dest;
+ char *rv;
+ PRBool comp;
+ } array[] =
+ {
+ { (const char *)0, (char *)0, (char *)0, PR_FALSE },
+ { (const char *)0, buffer, (char *)0, PR_FALSE },
+ { "", (char *)0, (char *)0, PR_FALSE },
+ { "", buffer, buffer, PR_TRUE },
+ { "a", (char *)0, (char *)0, PR_FALSE },
+ { "a", buffer, buffer, PR_TRUE },
+ { "abcdefg", (char *)0, (char *)0, PR_FALSE },
+ { "abcdefg", buffer, buffer, PR_TRUE },
+ { "wxyz\0abcdefg", (char *)0, (char *)0, PR_FALSE },
+ { "wxyz\0abcdefg", buffer, buffer, PR_TRUE }
+ };
+
+ int i;
+
+ printf("Test 003 (PL_strcpy) ..."); fflush(stdout);
+
+ for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+ {
+ char *rv;
+ const char *a = array[i].str;
+ const char *b = (const char *)array[i].dest;
+
+ rv = PL_strcpy(array[i].dest, array[i].str);
+ if( array[i].rv != rv )
+ {
+ printf("FAIL %d: (0x%x, %s)->0x%x\n", i, array[i].dest,
+ array[i].str ? array[i].str : "(null)", rv);
+ return PR_FALSE;
+ }
+
+ if( array[i].comp )
+ {
+ while( 1 )
+ {
+ if( *a != *b )
+ {
+ printf("FAIL %d: %s->%.32s\n", i,
+ array[i].str ? array[i].str : "(null)",
+ array[i].dest ? array[i].dest : "(null)");
+ return PR_FALSE;
+ }
+
+ if( (char)0 == *a ) break;
+
+ a++;
+ b++;
+ }
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_strncpy */
+PRBool test_004(void)
+{
+ static char buffer[ 1024 ];
+
+ static struct
+ {
+ const char *str;
+ PRUint32 len;
+ char *dest;
+ char *rv;
+ PRBool comp;
+ const char *result;
+ PRBool nulled;
+ } array[] =
+ {
+ { (const char *)0, 0, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+ { (const char *)0, 0, buffer, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+ { (const char *)0, 1, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+ { (const char *)0, 7, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+ { (const char *)0, 1, buffer, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+ { (const char *)0, 7, buffer, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+ { "", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+ { "", 0, buffer, buffer, PR_FALSE, (const char *)0, PR_FALSE },
+ { "", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+ { "", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+ { "", 1, buffer, buffer, PR_TRUE, "", PR_TRUE },
+ { "", 7, buffer, buffer, PR_TRUE, "", PR_TRUE },
+ { "a", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+ { "a", 0, buffer, buffer, PR_FALSE, (const char *)0, PR_FALSE },
+ { "a", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+ { "a", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+ { "b", 1, buffer, buffer, PR_TRUE, "b", PR_FALSE },
+ { "c", 7, buffer, buffer, PR_TRUE, "c", PR_TRUE },
+ { "de", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+ { "de", 0, buffer, buffer, PR_FALSE, (const char *)0, PR_FALSE },
+ { "de", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+ { "de", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+ { "fg", 1, buffer, buffer, PR_TRUE, "f", PR_FALSE },
+ { "hi", 7, buffer, buffer, PR_TRUE, "hi", PR_TRUE },
+ { "jklmnopq", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+ { "jklmnopq", 0, buffer, buffer, PR_FALSE, (const char *)0, PR_FALSE },
+ { "jklmnopq", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+ { "jklmnopq", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+ { "rstuvwxy", 1, buffer, buffer, PR_TRUE, "r", PR_FALSE },
+ { "zABCDEFG", 7, buffer, buffer, PR_TRUE, "zABCDEF", PR_FALSE },
+ { "a\0XXX", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+ { "a\0XXX", 0, buffer, buffer, PR_FALSE, (const char *)0, PR_FALSE },
+ { "a\0XXX", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+ { "a\0XXX", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+ { "b\0XXX", 1, buffer, buffer, PR_TRUE, "b", PR_FALSE },
+ { "c\0XXX", 7, buffer, buffer, PR_TRUE, "c", PR_TRUE },
+ { "de\0XXX", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+ { "de\0XXX", 0, buffer, buffer, PR_FALSE, (const char *)0, PR_FALSE },
+ { "de\0XXX", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+ { "de\0XXX", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+ { "fg\0XXX", 1, buffer, buffer, PR_TRUE, "f", PR_FALSE },
+ { "hi\0XXX", 7, buffer, buffer, PR_TRUE, "hi", PR_TRUE },
+ { "jklmnopq\0XXX", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+ { "jklmnopq\0XXX", 0, buffer, buffer, PR_FALSE, (const char *)0, PR_FALSE },
+ { "jklmnopq\0XXX", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+ { "jklmnopq\0XXX", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0, PR_FALSE },
+ { "rstuvwxy\0XXX", 1, buffer, buffer, PR_TRUE, "r", PR_FALSE },
+ { "zABCDEFG\0XXX", 7, buffer, buffer, PR_TRUE, "zABCDEF", PR_FALSE },
+ };
+
+ int i;
+
+ printf("Test 004 (PL_strncpy) ..."); fflush(stdout);
+
+ for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+ {
+ char *rv;
+ int j;
+
+ for( j = 0; j < sizeof(buffer); j++ )
+ buffer[j] = '-';
+
+ rv = PL_strncpy(array[i].dest, array[i].str, array[i].len);
+ if( array[i].rv != rv )
+ {
+ printf("FAIL %d: (0x%x, %s, %lu)->0x%x\n", i, array[i].dest,
+ array[i].str ? array[i].str : "(null)", array[i].len, rv);
+ return PR_FALSE;
+ }
+
+ if( array[i].comp )
+ {
+ const char *a = array[i].result;
+ const char *b = array[i].dest;
+
+ while( *a )
+ {
+ if( *a != *b )
+ {
+ printf("FAIL %d: %s != %.32s\n", i,
+ array[i].result, array[i].dest);
+ return PR_FALSE;
+ }
+
+ a++;
+ b++;
+ }
+
+ if( array[i].nulled )
+ {
+ if( *b != '\0' )
+ {
+ printf("FAIL %d: not terminated\n", i);
+ return PR_FALSE;
+ }
+ }
+ else
+ {
+ if( *b != '-' )
+ {
+ printf("FAIL %d: overstepped\n", i);
+ return PR_FALSE;
+ }
+ }
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_strncpyz */
+PRBool test_005(void)
+{
+ static char buffer[ 1024 ];
+
+ static struct
+ {
+ const char *str;
+ PRUint32 len;
+ char *dest;
+ char *rv;
+ PRBool comp;
+ const char *result;
+ } array[] =
+ {
+ { (const char *)0, 0, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+ { (const char *)0, 0, buffer, (char *)0, PR_FALSE, (const char *)0 },
+ { (const char *)0, 1, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+ { (const char *)0, 7, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+ { (const char *)0, 1, buffer, (char *)0, PR_FALSE, (const char *)0 },
+ { (const char *)0, 7, buffer, (char *)0, PR_FALSE, (const char *)0 },
+ { "", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+ { "", 0, buffer, (char *)0, PR_FALSE, (const char *)0 },
+ { "", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+ { "", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+ { "", 1, buffer, buffer, PR_TRUE, "" },
+ { "", 7, buffer, buffer, PR_TRUE, "" },
+ { "a", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+ { "a", 0, buffer, (char *)0, PR_FALSE, (const char *)0 },
+ { "a", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+ { "a", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+ { "b", 1, buffer, buffer, PR_TRUE, "" },
+ { "c", 7, buffer, buffer, PR_TRUE, "c" },
+ { "de", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+ { "de", 0, buffer, (char *)0, PR_FALSE, (const char *)0 },
+ { "de", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+ { "de", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+ { "fg", 1, buffer, buffer, PR_TRUE, "" },
+ { "hi", 7, buffer, buffer, PR_TRUE, "hi" },
+ { "jklmnopq", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+ { "jklmnopq", 0, buffer, (char *)0, PR_FALSE, (const char *)0 },
+ { "jklmnopq", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+ { "jklmnopq", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+ { "rstuvwxy", 1, buffer, buffer, PR_TRUE, "" },
+ { "zABCDEFG", 7, buffer, buffer, PR_TRUE, "zABCDE" },
+ { "a\0XXX", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+ { "a\0XXX", 0, buffer, (char *)0, PR_FALSE, (const char *)0 },
+ { "a\0XXX", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+ { "a\0XXX", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+ { "b\0XXX", 1, buffer, buffer, PR_TRUE, "" },
+ { "c\0XXX", 7, buffer, buffer, PR_TRUE, "c" },
+ { "de\0XXX", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+ { "de\0XXX", 0, buffer, (char *)0, PR_FALSE, (const char *)0 },
+ { "de\0XXX", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+ { "de\0XXX", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+ { "fg\0XXX", 1, buffer, buffer, PR_TRUE, "" },
+ { "hi\0XXX", 7, buffer, buffer, PR_TRUE, "hi" },
+ { "jklmnopq\0XXX", 0, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+ { "jklmnopq\0XXX", 0, buffer, (char *)0, PR_FALSE, (const char *)0 },
+ { "jklmnopq\0XXX", 1, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+ { "jklmnopq\0XXX", 7, (char *)0, (char *)0, PR_FALSE, (const char *)0 },
+ { "rstuvwxy\0XXX", 1, buffer, buffer, PR_TRUE, "" },
+ { "zABCDEFG\0XXX", 7, buffer, buffer, PR_TRUE, "zABCDE" },
+ };
+
+ int i;
+
+ printf("Test 005 (PL_strncpyz) ..."); fflush(stdout);
+
+ for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+ {
+ char *rv;
+ int j;
+
+ for( j = 0; j < sizeof(buffer); j++ )
+ buffer[j] = '-';
+
+ rv = PL_strncpyz(array[i].dest, array[i].str, array[i].len);
+ if( array[i].rv != rv )
+ {
+ printf("FAIL %d: (0x%x, %s, %lu)->0x%x\n", i, array[i].dest,
+ array[i].str ? array[i].str : "(null)", array[i].len, rv);
+ return PR_FALSE;
+ }
+
+ if( array[i].comp )
+ {
+ const char *a = array[i].result;
+ const char *b = array[i].dest;
+
+ while( 1 )
+ {
+ if( *a != *b )
+ {
+ printf("FAIL %d: %s != %.32s\n", i,
+ array[i].result, array[i].dest);
+ return PR_FALSE;
+ }
+
+ if( (char)0 == *a ) break;
+
+ a++;
+ b++;
+ }
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_strdup */
+PRBool test_006(void)
+{
+ static const char *array[] =
+ {
+ (const char *)0,
+ "",
+ "a",
+ "abcdefg"
+ };
+
+ int i;
+
+ printf("Test 006 (PL_strdup) ..."); fflush(stdout);
+
+ for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+ {
+ char *rv = PL_strdup(array[i]);
+
+ if( (char *)0 == rv )
+ {
+ printf("FAIL %d: 0x%x -> 0\n", i, array[i]);
+ return PR_FALSE;
+ }
+
+ if( (const char *)0 == array[i] )
+ {
+ if( (char)0 != *rv )
+ {
+ printf("FAIL %d: (const char *)0 -> %.32s\n", i, rv);
+ return PR_FALSE;
+ }
+ }
+ else
+ {
+ const char *a = array[i];
+ const char *b = (const char *)rv;
+
+ while( 1 )
+ {
+ if( *a != *b )
+ {
+ printf("FAIL %d: %s != %.32s\n", i, array[i], rv);
+ return PR_FALSE;
+ }
+
+ if( (char)0 == *a ) break;
+
+ a++;
+ b++;
+ }
+
+ }
+ PL_strfree(rv);
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_strndup */
+PRBool test_007(void)
+{
+ static struct
+ {
+ const char *str;
+ PRUint32 len;
+ const char *result;
+ } array[] =
+ {
+ { (const char *)0, 0, "" },
+ { (const char *)0, 1, "" },
+ { (const char *)0, 7, "" },
+ { "", 0, "" },
+ { "", 1, "" },
+ { "", 7, "" },
+ { "a", 0, "" },
+ { "a", 1, "a" },
+ { "a", 7, "a" },
+ { "ab", 0, "" },
+ { "ab", 1, "a" },
+ { "ab", 7, "ab" },
+ { "abcdefg", 0, "" },
+ { "abcdefg", 1, "a" },
+ { "abcdefg", 7, "abcdefg" },
+ { "abcdefghijk", 0, "" },
+ { "abcdefghijk", 1, "a" },
+ { "abcdefghijk", 7, "abcdefg" },
+ { "abcdef\0ghijk", 0, "" },
+ { "abcdef\0ghijk", 1, "a" },
+ { "abcdef\0ghijk", 7, "abcdef" }
+ };
+
+ int i;
+
+ printf("Test 007 (PL_strndup) ..."); fflush(stdout);
+
+ for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+ {
+ char *rv = PL_strndup(array[i].str, array[i].len);
+ const char *a;
+ const char *b;
+
+ if( (char *)0 == rv )
+ {
+ printf("FAIL %d: %s,%lu -> 0\n", i,
+ array[i].str ? array[i].str : "(null)", array[i].len);
+ return PR_FALSE;
+ }
+
+ a = array[i].result;
+ b = (const char *)rv;
+
+ while( 1 )
+ {
+ if( *a != *b )
+ {
+ printf("FAIL %d: %s != %.32s\n", i, array[i].result, rv);
+ return PR_FALSE;
+ }
+
+ if( (char)0 == *a ) break;
+
+ a++;
+ b++;
+ }
+
+ free(rv);
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_strcat */
+PRBool test_008(void)
+{
+ static struct
+ {
+ const char *first;
+ const char *second;
+ const char *result;
+ } array[] =
+ {
+ { (const char *)0, (const char *)0, (const char *)0 },
+ { (const char *)0, "xyz", (const char *)0 },
+ { "", (const char *)0, "" },
+ { "", "", "" },
+ { "ab", "", "ab" },
+ { "cd", "ef", "cdef" },
+ { "gh\0X", "", "gh" },
+ { "ij\0X", "kl", "ijkl" },
+ { "mn\0X", "op\0X", "mnop" },
+ { "qr", "st\0X", "qrst" },
+ { "uv\0X", "wx\0X", "uvwx" }
+ };
+
+ int i;
+
+ printf("Test 008 (PL_strcat) ..."); fflush(stdout);
+
+ for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+ {
+ char buffer[ 1024 ];
+ int j;
+ char *rv;
+
+ for( j = 0; j < sizeof(buffer); j++ )
+ buffer[j] = '-';
+
+ if( (const char *)0 != array[i].first )
+ (void)PL_strcpy(buffer, array[i].first);
+
+ rv = PL_strcat(((const char *)0 == array[i].first) ? (char *)0 : buffer,
+ array[i].second);
+
+ if( (const char *)0 == array[i].result )
+ {
+ if( (char *)0 != rv )
+ {
+ printf("FAIL %d: %s+%s -> %.32s, not zero\n", i,
+ array[i].first ? array[i].first : "(null)",
+ array[i].second ? array[i].second : "(null)",
+ rv);
+ return PR_FALSE;
+ }
+ }
+ else
+ {
+ if( (char *)0 == rv )
+ {
+ printf("FAIL %d: %s+%s -> null, not %s\n", i,
+ array[i].first ? array[i].first : "(null)",
+ array[i].second ? array[i].second : "(null)",
+ array[i].result);
+ return PR_FALSE;
+ }
+ else
+ {
+ const char *a = array[i].result;
+ const char *b = (const char *)rv;
+
+ while( 1 )
+ {
+ if( *a != *b )
+ {
+ printf("FAIL %d: %s+%s -> %.32s, not %s\n", i,
+ array[i].first ? array[i].first : "(null)",
+ array[i].second ? array[i].second : "(null)",
+ rv, array[i].result);
+ return PR_FALSE;
+ }
+
+ if( (char)0 == *a ) break;
+
+ a++;
+ b++;
+ }
+ }
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_strncat */
+PRBool test_009(void)
+{
+ static struct
+ {
+ const char *first;
+ const char *second;
+ PRUint32 length;
+ PRBool nulled;
+ const char *result;
+ } array[] =
+ {
+ { (const char *)0, (const char *)0, 0, PR_FALSE, (const char *)0 },
+ { (const char *)0, (const char *)0, 1, PR_FALSE, (const char *)0 },
+ { (const char *)0, (const char *)0, 7, PR_FALSE, (const char *)0 },
+ { (const char *)0, "", 0, PR_FALSE, (const char *)0 },
+ { (const char *)0, "", 1, PR_FALSE, (const char *)0 },
+ { (const char *)0, "", 7, PR_FALSE, (const char *)0 },
+ { (const char *)0, "stuff", 0, PR_FALSE, (const char *)0 },
+ { (const char *)0, "stuff", 1, PR_FALSE, (const char *)0 },
+ { (const char *)0, "stuff", 7, PR_FALSE, (const char *)0 },
+ { "", (const char *)0, 0, PR_TRUE, "" },
+ { "", (const char *)0, 1, PR_TRUE, "" },
+ { "", (const char *)0, 7, PR_TRUE, "" },
+ { "", "", 0, PR_TRUE, "" },
+ { "", "", 1, PR_TRUE, "" },
+ { "", "", 7, PR_TRUE, "" },
+ { "", "abcdefgh", 0, PR_TRUE, "" },
+ { "", "abcdefgh", 1, PR_FALSE, "a" },
+ { "", "abcdefgh", 7, PR_FALSE, "abcdefg" },
+ { "xyz", (const char *)0, 0, PR_TRUE, "xyz" },
+ { "xyz", (const char *)0, 1, PR_TRUE, "xyz" },
+ { "xyz", (const char *)0, 7, PR_TRUE, "xyz" },
+ { "xyz", "", 0, PR_TRUE, "xyz" },
+ { "xyz", "", 1, PR_TRUE, "xyz" },
+ { "xyz", "", 7, PR_TRUE, "xyz" },
+ { "xyz", "abcdefgh", 0, PR_TRUE, "xyz" },
+ { "xyz", "abcdefgh", 1, PR_FALSE, "xyza" },
+ { "xyz", "abcdefgh", 7, PR_FALSE, "xyzabcdefg" }
+ };
+
+ int i;
+
+ printf("Test 009 (PL_strncat) ..."); fflush(stdout);
+
+ for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+ {
+ char buffer[ 1024 ];
+ int j;
+ char *rv;
+
+ for( j = 0; j < sizeof(buffer); j++ )
+ buffer[j] = '-';
+
+ if( (const char *)0 != array[i].first )
+ (void)PL_strcpy(buffer, array[i].first);
+
+ rv = PL_strncat(((const char *)0 == array[i].first) ? (char *)0 : buffer,
+ array[i].second, array[i].length);
+
+ if( (const char *)0 == array[i].result )
+ {
+ if( (char *)0 != rv )
+ {
+ printf("FAIL %d: %s+%s/%lu -> %.32s, not zero\n", i,
+ array[i].first ? array[i].first : "(null)",
+ array[i].second ? array[i].second : "(null)",
+ array[i].length, rv);
+ return PR_FALSE;
+ }
+ }
+ else
+ {
+ if( (char *)0 == rv )
+ {
+ printf("FAIL %d: %s+%s/%lu -> null, not %s\n", i,
+ array[i].first ? array[i].first : "(null)",
+ array[i].second ? array[i].second : "(null)",
+ array[i].length, array[i].result);
+ return PR_FALSE;
+ }
+ else
+ {
+ const char *a = array[i].result;
+ const char *b = (const char *)rv;
+
+ while( *a )
+ {
+ if( *a != *b )
+ {
+ printf("FAIL %d: %s+%s/%lu -> %.32s, not %s\n", i,
+ array[i].first ? array[i].first : "(null)",
+ array[i].second ? array[i].second : "(null)",
+ array[i].length, rv, array[i].result);
+ return PR_FALSE;
+ }
+
+ a++;
+ b++;
+ }
+
+ if( array[i].nulled )
+ {
+ if( (char)0 != *b )
+ {
+ printf("FAIL %d: %s+%s/%lu -> not nulled\n", i,
+ array[i].first ? array[i].first : "(null)",
+ array[i].second ? array[i].second : "(null)",
+ array[i].length);
+ return PR_FALSE;
+ }
+ }
+ else
+ {
+ if( (char)0 == *b )
+ {
+ printf("FAIL %d: %s+%s/%lu -> overrun\n", i,
+ array[i].first ? array[i].first : "(null)",
+ array[i].second ? array[i].second : "(null)",
+ array[i].length);
+ return PR_FALSE;
+ }
+ }
+ }
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_strcatn */
+PRBool test_010(void)
+{
+ static struct
+ {
+ const char *first;
+ const char *second;
+ PRUint32 length;
+ const char *result;
+ } array[] =
+ {
+ { (const char *)0, (const char *)0, 0, (const char *)0 },
+ { (const char *)0, (const char *)0, 1, (const char *)0 },
+ { (const char *)0, (const char *)0, 7, (const char *)0 },
+ { (const char *)0, "", 0, (const char *)0 },
+ { (const char *)0, "", 1, (const char *)0 },
+ { (const char *)0, "", 7, (const char *)0 },
+ { (const char *)0, "stuff", 0, (const char *)0 },
+ { (const char *)0, "stuff", 1, (const char *)0 },
+ { (const char *)0, "stuff", 7, (const char *)0 },
+ { "", (const char *)0, 0, "" },
+ { "", (const char *)0, 1, "" },
+ { "", (const char *)0, 7, "" },
+ { "", "", 0, "" },
+ { "", "", 1, "" },
+ { "", "", 7, "" },
+ { "", "abcdefgh", 0, "" },
+ { "", "abcdefgh", 1, "" },
+ { "", "abcdefgh", 7, "abcdef" },
+ { "xyz", (const char *)0, 0, "xyz" },
+ { "xyz", (const char *)0, 1, "xyz" },
+ { "xyz", (const char *)0, 7, "xyz" },
+ { "xyz", "", 0, "xyz" },
+ { "xyz", "", 1, "xyz" },
+ { "xyz", "", 7, "xyz" },
+ { "xyz", "abcdefgh", 0, "xyz" },
+ { "xyz", "abcdefgh", 1, "xyz" },
+ { "xyz", "abcdefgh", 7, "xyzabc" }
+ };
+
+ int i;
+
+ printf("Test 010 (PL_strcatn) ..."); fflush(stdout);
+
+ for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+ {
+ char buffer[ 1024 ];
+ int j;
+ char *rv;
+
+ for( j = 0; j < sizeof(buffer); j++ )
+ buffer[j] = '-';
+
+ if( (const char *)0 != array[i].first )
+ (void)PL_strcpy(buffer, array[i].first);
+
+ rv = PL_strcatn(((const char *)0 == array[i].first) ? (char *)0 : buffer,
+ array[i].length, array[i].second);
+
+ if( (const char *)0 == array[i].result )
+ {
+ if( (char *)0 != rv )
+ {
+ printf("FAIL %d: %s+%s/%lu -> %.32s, not zero\n", i,
+ array[i].first ? array[i].first : "(null)",
+ array[i].second ? array[i].second : "(null)",
+ array[i].length, rv);
+ return PR_FALSE;
+ }
+ }
+ else
+ {
+ if( (char *)0 == rv )
+ {
+ printf("FAIL %d: %s+%s/%lu -> null, not %s\n", i,
+ array[i].first ? array[i].first : "(null)",
+ array[i].second ? array[i].second : "(null)",
+ array[i].length, array[i].result);
+ return PR_FALSE;
+ }
+ else
+ {
+ const char *a = array[i].result;
+ const char *b = (const char *)rv;
+
+ while( 1 )
+ {
+ if( *a != *b )
+ {
+ printf("FAIL %d: %s+%s/%lu -> %.32s, not %s\n", i,
+ array[i].first ? array[i].first : "(null)",
+ array[i].second ? array[i].second : "(null)",
+ array[i].length, rv, array[i].result);
+ return PR_FALSE;
+ }
+
+ if( (char)0 == *a ) break;
+
+ a++;
+ b++;
+ }
+ }
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_strcmp */
+PRBool test_011(void)
+{
+ static struct
+ {
+ const char *one;
+ const char *two;
+ PRIntn sign;
+ } array[] =
+ {
+ { (const char *)0, (const char *)0, 0 },
+ { (const char *)0, "word", -1 },
+ { "word", (const char *)0, 1 },
+ { "word", "word", 0 },
+ { "aZYXVUT", "bZYXVUT", -1 },
+ { "aZYXVUT", "bAAAAAA", -1 },
+ { "a", "aa", -1 },
+ { "a", "a", 0 },
+ { "a", "A", 1 },
+ { "aaaaa", "baaaa", -1 },
+ { "aaaaa", "abaaa", -1 },
+ { "aaaaa", "aabaa", -1 },
+ { "aaaaa", "aaaba", -1 },
+ { "aaaaa", "aaaab", -1 },
+ { "bZYXVUT", "aZYXVUT", 1 },
+ { "bAAAAAA", "aZYXVUT", 1 },
+ { "aa", "a", 1 },
+ { "A", "a", -1 },
+ { "baaaa", "aaaaa", 1 },
+ { "abaaa", "aaaaa", 1 },
+ { "aabaa", "aaaaa", 1 },
+ { "aaaba", "aaaaa", 1 },
+ { "aaaab", "aaaaa", 1 },
+ { "word", "Word", 1 },
+ { "word", "wOrd", 1 },
+ { "word", "woRd", 1 },
+ { "word", "worD", 1 },
+ { "WORD", "wORD", -1 },
+ { "WORD", "WoRD", -1 },
+ { "WORD", "WOrD", -1 },
+ { "WORD", "WORd", -1 }
+ };
+
+ int i;
+
+ printf("Test 011 (PL_strcmp) ..."); fflush(stdout);
+
+ for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+ {
+ PRIntn rv = PL_strcmp(array[i].one, array[i].two);
+
+ switch( array[i].sign )
+ {
+ case -1:
+ if( rv < 0 ) continue;
+ break;
+ case 1:
+ if( rv > 0 ) continue;
+ break;
+ case 0:
+ if( 0 == rv ) continue;
+ break;
+ default:
+ PR_NOT_REACHED("static data inconsistancy");
+ break;
+ }
+
+ printf("FAIL %d: %s-%s -> %d, not %d\n", i,
+ array[i].one ? array[i].one : "(null)",
+ array[i].two ? array[i].two : "(null)",
+ rv, array[i].sign);
+ return PR_FALSE;
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_strncmp */
+PRBool test_012(void)
+{
+ static struct
+ {
+ const char *one;
+ const char *two;
+ PRUint32 max;
+ PRIntn sign;
+ } array[] =
+ {
+ { (const char *)0, (const char *)0, 0, 0 },
+ { (const char *)0, (const char *)0, 1, 0 },
+ { (const char *)0, (const char *)0, 4, 0 },
+ { (const char *)0, "word", 0, -1 },
+ { (const char *)0, "word", 1, -1 },
+ { (const char *)0, "word", 4, -1 },
+ { "word", (const char *)0, 0, 1 },
+ { "word", (const char *)0, 1, 1 },
+ { "word", (const char *)0, 4, 1 },
+ { "word", "word", 0, 0 },
+ { "word", "word", 1, 0 },
+ { "word", "word", 3, 0 },
+ { "word", "word", 5, 0 },
+ { "aZYXVUT", "bZYXVUT", 0, 0 },
+ { "aZYXVUT", "bZYXVUT", 1, -1 },
+ { "aZYXVUT", "bZYXVUT", 4, -1 },
+ { "aZYXVUT", "bZYXVUT", 9, -1 },
+ { "aZYXVUT", "bAAAAAA", 0, 0 },
+ { "aZYXVUT", "bAAAAAA", 1, -1 },
+ { "aZYXVUT", "bAAAAAA", 4, -1 },
+ { "aZYXVUT", "bAAAAAA", 5, -1 },
+ { "a", "aa", 0, 0 },
+ { "a", "aa", 1, 0 },
+ { "a", "aa", 4, -1 },
+ { "a", "a", 0, 0 },
+ { "a", "a", 1, 0 },
+ { "a", "a", 4, 0 },
+ { "a", "A", 0, 0 },
+ { "a", "A", 1, 1 },
+ { "a", "A", 4, 1 },
+ { "aaaaa", "baaaa", 0, 0 },
+ { "aaaaa", "baaaa", 1, -1 },
+ { "aaaaa", "baaaa", 4, -1 },
+ { "aaaaa", "abaaa", 0, 0 },
+ { "aaaaa", "abaaa", 1, 0 },
+ { "aaaaa", "abaaa", 4, -1 },
+ { "aaaaa", "aabaa", 0, 0 },
+ { "aaaaa", "aabaa", 1, 0 },
+ { "aaaaa", "aabaa", 4, -1 },
+ { "aaaaa", "aaaba", 0, 0 },
+ { "aaaaa", "aaaba", 1, 0 },
+ { "aaaaa", "aaaba", 4, -1 },
+ { "aaaaa", "aaaab", 0, 0 },
+ { "aaaaa", "aaaab", 1, 0 },
+ { "aaaaa", "aaaab", 4, 0 },
+ { "bZYXVUT", "aZYXVUT", 0, 0 },
+ { "bZYXVUT", "aZYXVUT", 1, 1 },
+ { "bZYXVUT", "aZYXVUT", 4, 1 },
+ { "bAAAAAA", "aZYXVUT", 0, 0 },
+ { "bAAAAAA", "aZYXVUT", 1, 1 },
+ { "bAAAAAA", "aZYXVUT", 4, 1 },
+ { "aa", "a", 0, 0 },
+ { "aa", "a", 1, 0 },
+ { "aa", "a", 4, 1 },
+ { "A", "a", 0, 0 },
+ { "A", "a", 1, -1 },
+ { "A", "a", 4, -1 },
+ { "baaaa", "aaaaa", 0, 0 },
+ { "baaaa", "aaaaa", 1, 1 },
+ { "baaaa", "aaaaa", 4, 1 },
+ { "abaaa", "aaaaa", 0, 0 },
+ { "abaaa", "aaaaa", 1, 0 },
+ { "abaaa", "aaaaa", 4, 1 },
+ { "aabaa", "aaaaa", 0, 0 },
+ { "aabaa", "aaaaa", 1, 0 },
+ { "aabaa", "aaaaa", 4, 1 },
+ { "aaaba", "aaaaa", 0, 0 },
+ { "aaaba", "aaaaa", 1, 0 },
+ { "aaaba", "aaaaa", 4, 1 },
+ { "aaaab", "aaaaa", 0, 0 },
+ { "aaaab", "aaaaa", 1, 0 },
+ { "aaaab", "aaaaa", 4, 0 },
+ { "word", "Word", 0, 0 },
+ { "word", "Word", 1, 1 },
+ { "word", "Word", 3, 1 },
+ { "word", "wOrd", 0, 0 },
+ { "word", "wOrd", 1, 0 },
+ { "word", "wOrd", 3, 1 },
+ { "word", "woRd", 0, 0 },
+ { "word", "woRd", 1, 0 },
+ { "word", "woRd", 3, 1 },
+ { "word", "worD", 0, 0 },
+ { "word", "worD", 1, 0 },
+ { "word", "worD", 3, 0 },
+ { "WORD", "wORD", 0, 0 },
+ { "WORD", "wORD", 1, -1 },
+ { "WORD", "wORD", 3, -1 },
+ { "WORD", "WoRD", 0, 0 },
+ { "WORD", "WoRD", 1, 0 },
+ { "WORD", "WoRD", 3, -1 },
+ { "WORD", "WOrD", 0, 0 },
+ { "WORD", "WOrD", 1, 0 },
+ { "WORD", "WOrD", 3, -1 },
+ { "WORD", "WORd", 0, 0 },
+ { "WORD", "WORd", 1, 0 },
+ { "WORD", "WORd", 3, 0 }
+
+ };
+
+ int i;
+
+ printf("Test 012 (PL_strncmp) ..."); fflush(stdout);
+
+ for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+ {
+ PRIntn rv = PL_strncmp(array[i].one, array[i].two, array[i].max);
+
+ switch( array[i].sign )
+ {
+ case -1:
+ if( rv < 0 ) continue;
+ break;
+ case 1:
+ if( rv > 0 ) continue;
+ break;
+ case 0:
+ if( 0 == rv ) continue;
+ break;
+ default:
+ PR_NOT_REACHED("static data inconsistancy");
+ break;
+ }
+
+ printf("FAIL %d: %s-%s/%ld -> %d, not %d\n", i,
+ array[i].one ? array[i].one : "(null)",
+ array[i].two ? array[i].two : "(null)",
+ array[i].max, rv, array[i].sign);
+ return PR_FALSE;
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_strcasecmp */
+PRBool test_013(void)
+{
+ static struct
+ {
+ const char *one;
+ const char *two;
+ PRIntn sign;
+ } array[] =
+ {
+ { (const char *)0, (const char *)0, 0 },
+ { (const char *)0, "word", -1 },
+ { "word", (const char *)0, 1 },
+ { "word", "word", 0 },
+ { "aZYXVUT", "bZYXVUT", -1 },
+ { "aZYXVUT", "bAAAAAA", -1 },
+ { "a", "aa", -1 },
+ { "a", "a", 0 },
+ { "a", "A", 0 },
+ { "aaaaa", "baaaa", -1 },
+ { "aaaaa", "abaaa", -1 },
+ { "aaaaa", "aabaa", -1 },
+ { "aaaaa", "aaaba", -1 },
+ { "aaaaa", "aaaab", -1 },
+ { "bZYXVUT", "aZYXVUT", 1 },
+ { "bAAAAAA", "aZYXVUT", 1 },
+ { "aa", "a", 1 },
+ { "A", "a", 0 },
+ { "baaaa", "aaaaa", 1 },
+ { "abaaa", "aaaaa", 1 },
+ { "aabaa", "aaaaa", 1 },
+ { "aaaba", "aaaaa", 1 },
+ { "aaaab", "aaaaa", 1 },
+ { "word", "Word", 0 },
+ { "word", "wOrd", 0 },
+ { "word", "woRd", 0 },
+ { "word", "worD", 0 },
+ { "WORD", "wORD", 0 },
+ { "WORD", "WoRD", 0 },
+ { "WORD", "WOrD", 0 },
+ { "WORD", "WORd", 0 }
+ };
+
+ int i;
+
+ printf("Test 013 (PL_strcasecmp) ..."); fflush(stdout);
+
+ for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+ {
+ PRIntn rv = PL_strcasecmp(array[i].one, array[i].two);
+
+ switch( array[i].sign )
+ {
+ case -1:
+ if( rv < 0 ) continue;
+ break;
+ case 1:
+ if( rv > 0 ) continue;
+ break;
+ case 0:
+ if( 0 == rv ) continue;
+ break;
+ default:
+ PR_NOT_REACHED("static data inconsistancy");
+ break;
+ }
+
+ printf("FAIL %d: %s-%s -> %d, not %d\n", i,
+ array[i].one ? array[i].one : "(null)",
+ array[i].two ? array[i].two : "(null)",
+ rv, array[i].sign);
+ return PR_FALSE;
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_strncasecmp */
+PRBool test_014(void)
+{
+ static struct
+ {
+ const char *one;
+ const char *two;
+ PRUint32 max;
+ PRIntn sign;
+ } array[] =
+ {
+ { (const char *)0, (const char *)0, 0, 0 },
+ { (const char *)0, (const char *)0, 1, 0 },
+ { (const char *)0, (const char *)0, 4, 0 },
+ { (const char *)0, "word", 0, -1 },
+ { (const char *)0, "word", 1, -1 },
+ { (const char *)0, "word", 4, -1 },
+ { "word", (const char *)0, 0, 1 },
+ { "word", (const char *)0, 1, 1 },
+ { "word", (const char *)0, 4, 1 },
+ { "word", "word", 0, 0 },
+ { "word", "word", 1, 0 },
+ { "word", "word", 3, 0 },
+ { "word", "word", 5, 0 },
+ { "aZYXVUT", "bZYXVUT", 0, 0 },
+ { "aZYXVUT", "bZYXVUT", 1, -1 },
+ { "aZYXVUT", "bZYXVUT", 4, -1 },
+ { "aZYXVUT", "bZYXVUT", 9, -1 },
+ { "aZYXVUT", "bAAAAAA", 0, 0 },
+ { "aZYXVUT", "bAAAAAA", 1, -1 },
+ { "aZYXVUT", "bAAAAAA", 4, -1 },
+ { "aZYXVUT", "bAAAAAA", 5, -1 },
+ { "a", "aa", 0, 0 },
+ { "a", "aa", 1, 0 },
+ { "a", "aa", 4, -1 },
+ { "a", "a", 0, 0 },
+ { "a", "a", 1, 0 },
+ { "a", "a", 4, 0 },
+ { "a", "A", 0, 0 },
+ { "a", "A", 1, 0 },
+ { "a", "A", 4, 0 },
+ { "aaaaa", "baaaa", 0, 0 },
+ { "aaaaa", "baaaa", 1, -1 },
+ { "aaaaa", "baaaa", 4, -1 },
+ { "aaaaa", "abaaa", 0, 0 },
+ { "aaaaa", "abaaa", 1, 0 },
+ { "aaaaa", "abaaa", 4, -1 },
+ { "aaaaa", "aabaa", 0, 0 },
+ { "aaaaa", "aabaa", 1, 0 },
+ { "aaaaa", "aabaa", 4, -1 },
+ { "aaaaa", "aaaba", 0, 0 },
+ { "aaaaa", "aaaba", 1, 0 },
+ { "aaaaa", "aaaba", 4, -1 },
+ { "aaaaa", "aaaab", 0, 0 },
+ { "aaaaa", "aaaab", 1, 0 },
+ { "aaaaa", "aaaab", 4, 0 },
+ { "bZYXVUT", "aZYXVUT", 0, 0 },
+ { "bZYXVUT", "aZYXVUT", 1, 1 },
+ { "bZYXVUT", "aZYXVUT", 4, 1 },
+ { "bAAAAAA", "aZYXVUT", 0, 0 },
+ { "bAAAAAA", "aZYXVUT", 1, 1 },
+ { "bAAAAAA", "aZYXVUT", 4, 1 },
+ { "aa", "a", 0, 0 },
+ { "aa", "a", 1, 0 },
+ { "aa", "a", 4, 1 },
+ { "A", "a", 0, 0 },
+ { "A", "a", 1, 0 },
+ { "A", "a", 4, 0 },
+ { "baaaa", "aaaaa", 0, 0 },
+ { "baaaa", "aaaaa", 1, 1 },
+ { "baaaa", "aaaaa", 4, 1 },
+ { "abaaa", "aaaaa", 0, 0 },
+ { "abaaa", "aaaaa", 1, 0 },
+ { "abaaa", "aaaaa", 4, 1 },
+ { "aabaa", "aaaaa", 0, 0 },
+ { "aabaa", "aaaaa", 1, 0 },
+ { "aabaa", "aaaaa", 4, 1 },
+ { "aaaba", "aaaaa", 0, 0 },
+ { "aaaba", "aaaaa", 1, 0 },
+ { "aaaba", "aaaaa", 4, 1 },
+ { "aaaab", "aaaaa", 0, 0 },
+ { "aaaab", "aaaaa", 1, 0 },
+ { "aaaab", "aaaaa", 4, 0 },
+ { "word", "Word", 0, 0 },
+ { "word", "Word", 1, 0 },
+ { "word", "Word", 3, 0 },
+ { "word", "wOrd", 0, 0 },
+ { "word", "wOrd", 1, 0 },
+ { "word", "wOrd", 3, 0 },
+ { "word", "woRd", 0, 0 },
+ { "word", "woRd", 1, 0 },
+ { "word", "woRd", 3, 0 },
+ { "word", "worD", 0, 0 },
+ { "word", "worD", 1, 0 },
+ { "word", "worD", 3, 0 },
+ { "WORD", "wORD", 0, 0 },
+ { "WORD", "wORD", 1, 0 },
+ { "WORD", "wORD", 3, 0 },
+ { "WORD", "WoRD", 0, 0 },
+ { "WORD", "WoRD", 1, 0 },
+ { "WORD", "WoRD", 3, 0 },
+ { "WORD", "WOrD", 0, 0 },
+ { "WORD", "WOrD", 1, 0 },
+ { "WORD", "WOrD", 3, 0 },
+ { "WORD", "WORd", 0, 0 },
+ { "WORD", "WORd", 1, 0 },
+ { "WORD", "WORd", 3, 0 }
+ };
+
+ int i;
+
+ printf("Test 014 (PL_strncasecmp) ..."); fflush(stdout);
+
+ for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+ {
+ PRIntn rv = PL_strncasecmp(array[i].one, array[i].two, array[i].max);
+
+ switch( array[i].sign )
+ {
+ case -1:
+ if( rv < 0 ) continue;
+ break;
+ case 1:
+ if( rv > 0 ) continue;
+ break;
+ case 0:
+ if( 0 == rv ) continue;
+ break;
+ default:
+ PR_NOT_REACHED("static data inconsistancy");
+ break;
+ }
+
+ printf("FAIL %d: %s-%s/%ld -> %d, not %d\n", i,
+ array[i].one ? array[i].one : "(null)",
+ array[i].two ? array[i].two : "(null)",
+ array[i].max, rv, array[i].sign);
+ return PR_FALSE;
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_strchr */
+PRBool test_015(void)
+{
+ static struct
+ {
+ const char *str;
+ char chr;
+ PRBool ret;
+ PRUint32 off;
+ } array[] =
+ {
+ { (const char *)0, 'a', PR_FALSE, 0 },
+ { (const char *)0, '\0', PR_FALSE, 0 },
+ { "abcdefg", 'a', PR_TRUE, 0 },
+ { "abcdefg", 'b', PR_TRUE, 1 },
+ { "abcdefg", 'c', PR_TRUE, 2 },
+ { "abcdefg", 'd', PR_TRUE, 3 },
+ { "abcdefg", 'e', PR_TRUE, 4 },
+ { "abcdefg", 'f', PR_TRUE, 5 },
+ { "abcdefg", 'g', PR_TRUE, 6 },
+ { "abcdefg", 'h', PR_FALSE, 0 },
+ { "abcdefg", '\0', PR_TRUE, 7 },
+ { "abcdefg", 'A', PR_FALSE, 0 },
+ { "abcdefg", 'B', PR_FALSE, 0 },
+ { "abcdefg", 'C', PR_FALSE, 0 },
+ { "abcdefg", 'D', PR_FALSE, 0 },
+ { "abcdefg", 'E', PR_FALSE, 0 },
+ { "abcdefg", 'F', PR_FALSE, 0 },
+ { "abcdefg", 'G', PR_FALSE, 0 },
+ { "abcdefg", 'H', PR_FALSE, 0 },
+ { "abcdefgabcdefg", 'a', PR_TRUE, 0 },
+ { "abcdefgabcdefg", 'b', PR_TRUE, 1 },
+ { "abcdefgabcdefg", 'c', PR_TRUE, 2 },
+ { "abcdefgabcdefg", 'd', PR_TRUE, 3 },
+ { "abcdefgabcdefg", 'e', PR_TRUE, 4 },
+ { "abcdefgabcdefg", 'f', PR_TRUE, 5 },
+ { "abcdefgabcdefg", 'g', PR_TRUE, 6 },
+ { "abcdefgabcdefg", 'h', PR_FALSE, 0 },
+ { "abcdefgabcdefg", '\0', PR_TRUE, 14 }
+ };
+
+ int i;
+
+ printf("Test 015 (PL_strchr) ..."); fflush(stdout);
+
+ for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+ {
+ char *rv = PL_strchr(array[i].str, array[i].chr);
+
+ if( PR_FALSE == array[i].ret )
+ {
+ if( (char *)0 != rv )
+ {
+ printf("FAIL %d: %s,%c -> %.32s, not zero\n", i, array[i].str,
+ array[i].chr, rv);
+ return PR_FALSE;
+ }
+ }
+ else
+ {
+ if( (char *)0 == rv )
+ {
+ printf("FAIL %d: %s,%c -> null, not +%lu\n", i, array[i].str,
+ array[i].chr, array[i].off);
+ return PR_FALSE;
+ }
+
+ if( &array[i].str[ array[i].off ] != rv )
+ {
+ printf("FAIL %d: %s,%c -> 0x%x, not 0x%x+%lu\n", i, array[i].str,
+ array[i].chr, rv, array[i].str, array[i].off);
+ return PR_FALSE;
+ }
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_strrchr */
+PRBool test_016(void)
+{
+ static struct
+ {
+ const char *str;
+ char chr;
+ PRBool ret;
+ PRUint32 off;
+ } array[] =
+ {
+ { (const char *)0, 'a', PR_FALSE, 0 },
+ { (const char *)0, '\0', PR_FALSE, 0 },
+ { "abcdefg", 'a', PR_TRUE, 0 },
+ { "abcdefg", 'b', PR_TRUE, 1 },
+ { "abcdefg", 'c', PR_TRUE, 2 },
+ { "abcdefg", 'd', PR_TRUE, 3 },
+ { "abcdefg", 'e', PR_TRUE, 4 },
+ { "abcdefg", 'f', PR_TRUE, 5 },
+ { "abcdefg", 'g', PR_TRUE, 6 },
+ { "abcdefg", 'h', PR_FALSE, 0 },
+ { "abcdefg", '\0', PR_TRUE, 7 },
+ { "abcdefg", 'A', PR_FALSE, 0 },
+ { "abcdefg", 'B', PR_FALSE, 0 },
+ { "abcdefg", 'C', PR_FALSE, 0 },
+ { "abcdefg", 'D', PR_FALSE, 0 },
+ { "abcdefg", 'E', PR_FALSE, 0 },
+ { "abcdefg", 'F', PR_FALSE, 0 },
+ { "abcdefg", 'G', PR_FALSE, 0 },
+ { "abcdefg", 'H', PR_FALSE, 0 },
+ { "abcdefgabcdefg", 'a', PR_TRUE, 7 },
+ { "abcdefgabcdefg", 'b', PR_TRUE, 8 },
+ { "abcdefgabcdefg", 'c', PR_TRUE, 9 },
+ { "abcdefgabcdefg", 'd', PR_TRUE, 10 },
+ { "abcdefgabcdefg", 'e', PR_TRUE, 11 },
+ { "abcdefgabcdefg", 'f', PR_TRUE, 12 },
+ { "abcdefgabcdefg", 'g', PR_TRUE, 13 },
+ { "abcdefgabcdefg", 'h', PR_FALSE, 0 },
+ { "abcdefgabcdefg", '\0', PR_TRUE, 14 }
+ };
+
+ int i;
+
+ printf("Test 016 (PL_strrchr) ..."); fflush(stdout);
+
+ for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+ {
+ char *rv = PL_strrchr(array[i].str, array[i].chr);
+
+ if( PR_FALSE == array[i].ret )
+ {
+ if( (char *)0 != rv )
+ {
+ printf("FAIL %d: %s,%c -> %.32s, not zero\n", i, array[i].str,
+ array[i].chr, rv);
+ return PR_FALSE;
+ }
+ }
+ else
+ {
+ if( (char *)0 == rv )
+ {
+ printf("FAIL %d: %s,%c -> null, not +%lu\n", i, array[i].str,
+ array[i].chr, array[i].off);
+ return PR_FALSE;
+ }
+
+ if( &array[i].str[ array[i].off ] != rv )
+ {
+ printf("FAIL %d: %s,%c -> 0x%x, not 0x%x+%lu\n", i, array[i].str,
+ array[i].chr, rv, array[i].str, array[i].off);
+ return PR_FALSE;
+ }
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_strnchr */
+PRBool test_017(void)
+{
+ static struct
+ {
+ const char *str;
+ char chr;
+ PRUint32 max;
+ PRBool ret;
+ PRUint32 off;
+ } array[] =
+ {
+ { (const char *)0, 'a', 2, PR_FALSE, 0 },
+ { (const char *)0, '\0', 2, PR_FALSE, 0 },
+ { "abcdefg", 'a', 5, PR_TRUE, 0 },
+ { "abcdefg", 'b', 5, PR_TRUE, 1 },
+ { "abcdefg", 'c', 5, PR_TRUE, 2 },
+ { "abcdefg", 'd', 5, PR_TRUE, 3 },
+ { "abcdefg", 'e', 5, PR_TRUE, 4 },
+ { "abcdefg", 'f', 5, PR_FALSE, 0 },
+ { "abcdefg", 'g', 5, PR_FALSE, 0 },
+ { "abcdefg", 'h', 5, PR_FALSE, 0 },
+ { "abcdefg", '\0', 5, PR_FALSE, 0 },
+ { "abcdefg", '\0', 15, PR_TRUE, 7 },
+ { "abcdefg", 'A', 5, PR_FALSE, 0 },
+ { "abcdefg", 'B', 5, PR_FALSE, 0 },
+ { "abcdefg", 'C', 5, PR_FALSE, 0 },
+ { "abcdefg", 'D', 5, PR_FALSE, 0 },
+ { "abcdefg", 'E', 5, PR_FALSE, 0 },
+ { "abcdefg", 'F', 5, PR_FALSE, 0 },
+ { "abcdefg", 'G', 5, PR_FALSE, 0 },
+ { "abcdefg", 'H', 5, PR_FALSE, 0 },
+ { "abcdefgabcdefg", 'a', 10, PR_TRUE, 0 },
+ { "abcdefgabcdefg", 'b', 10, PR_TRUE, 1 },
+ { "abcdefgabcdefg", 'c', 10, PR_TRUE, 2 },
+ { "abcdefgabcdefg", 'd', 10, PR_TRUE, 3 },
+ { "abcdefgabcdefg", 'e', 10, PR_TRUE, 4 },
+ { "abcdefgabcdefg", 'f', 10, PR_TRUE, 5 },
+ { "abcdefgabcdefg", 'g', 10, PR_TRUE, 6 },
+ { "abcdefgabcdefg", 'h', 10, PR_FALSE, 0 },
+ { "abcdefgabcdefg", '\0', 10, PR_FALSE, 0 },
+ { "abcdefgabcdefg", '\0', 14, PR_FALSE, 0 },
+ { "abcdefgabcdefg", '\0', 15, PR_TRUE, 14 }
+ };
+
+ int i;
+
+ printf("Test 017 (PL_strnchr) ..."); fflush(stdout);
+
+ for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+ {
+ char *rv = PL_strnchr(array[i].str, array[i].chr, array[i].max);
+
+ if( PR_FALSE == array[i].ret )
+ {
+ if( (char *)0 != rv )
+ {
+ printf("FAIL %d: %s,%c/%lu -> %.32s, not zero\n", i, array[i].str,
+ array[i].chr, array[i].max, rv);
+ return PR_FALSE;
+ }
+ }
+ else
+ {
+ if( (char *)0 == rv )
+ {
+ printf("FAIL %d: %s,%c/%lu -> null, not +%lu\n", i, array[i].str,
+ array[i].chr, array[i].max, array[i].off);
+ return PR_FALSE;
+ }
+
+ if( &array[i].str[ array[i].off ] != rv )
+ {
+ printf("FAIL %d: %s,%c/%lu -> 0x%x, not 0x%x+%lu\n", i, array[i].str,
+ array[i].chr, array[i].max, rv, array[i].str, array[i].off);
+ return PR_FALSE;
+ }
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_strnrchr */
+PRBool test_018(void)
+{
+ static struct
+ {
+ const char *str;
+ char chr;
+ PRUint32 max;
+ PRBool ret;
+ PRUint32 off;
+ } array[] =
+ {
+ { (const char *)0, 'a', 2, PR_FALSE, 0 },
+ { (const char *)0, '\0', 2, PR_FALSE, 0 },
+ { "abcdefg", 'a', 5, PR_TRUE, 0 },
+ { "abcdefg", 'b', 5, PR_TRUE, 1 },
+ { "abcdefg", 'c', 5, PR_TRUE, 2 },
+ { "abcdefg", 'd', 5, PR_TRUE, 3 },
+ { "abcdefg", 'e', 5, PR_TRUE, 4 },
+ { "abcdefg", 'f', 5, PR_FALSE, 0 },
+ { "abcdefg", 'g', 5, PR_FALSE, 0 },
+ { "abcdefg", 'h', 5, PR_FALSE, 0 },
+ { "abcdefg", '\0', 5, PR_FALSE, 0 },
+ { "abcdefg", '\0', 15, PR_TRUE, 7 },
+ { "abcdefg", 'A', 5, PR_FALSE, 0 },
+ { "abcdefg", 'B', 5, PR_FALSE, 0 },
+ { "abcdefg", 'C', 5, PR_FALSE, 0 },
+ { "abcdefg", 'D', 5, PR_FALSE, 0 },
+ { "abcdefg", 'E', 5, PR_FALSE, 0 },
+ { "abcdefg", 'F', 5, PR_FALSE, 0 },
+ { "abcdefg", 'G', 5, PR_FALSE, 0 },
+ { "abcdefg", 'H', 5, PR_FALSE, 0 },
+ { "abcdefgabcdefg", 'a', 10, PR_TRUE, 7 },
+ { "abcdefgabcdefg", 'b', 10, PR_TRUE, 8 },
+ { "abcdefgabcdefg", 'c', 10, PR_TRUE, 9 },
+ { "abcdefgabcdefg", 'd', 10, PR_TRUE, 3 },
+ { "abcdefgabcdefg", 'e', 10, PR_TRUE, 4 },
+ { "abcdefgabcdefg", 'f', 10, PR_TRUE, 5 },
+ { "abcdefgabcdefg", 'g', 10, PR_TRUE, 6 },
+ { "abcdefgabcdefg", 'h', 10, PR_FALSE, 0 },
+ { "abcdefgabcdefg", '\0', 10, PR_FALSE, 0 },
+ { "abcdefgabcdefg", '\0', 14, PR_FALSE, 0 },
+ { "abcdefgabcdefg", '\0', 15, PR_TRUE, 14 }
+ };
+
+ int i;
+
+ printf("Test 018 (PL_strnrchr) ..."); fflush(stdout);
+
+ for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+ {
+ char *rv = PL_strnrchr(array[i].str, array[i].chr, array[i].max);
+
+ if( PR_FALSE == array[i].ret )
+ {
+ if( (char *)0 != rv )
+ {
+ printf("FAIL %d: %s,%c/%lu -> %.32s, not zero\n", i, array[i].str,
+ array[i].chr, array[i].max, rv);
+ return PR_FALSE;
+ }
+ }
+ else
+ {
+ if( (char *)0 == rv )
+ {
+ printf("FAIL %d: %s,%c/%lu -> null, not +%lu\n", i, array[i].str,
+ array[i].chr, array[i].max, array[i].off);
+ return PR_FALSE;
+ }
+
+ if( &array[i].str[ array[i].off ] != rv )
+ {
+ printf("FAIL %d: %s,%c/%lu -> 0x%x, not 0x%x+%lu\n", i, array[i].str,
+ array[i].chr, array[i].max, rv, array[i].str, array[i].off);
+ return PR_FALSE;
+ }
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_strpbrk */
+PRBool test_019(void)
+{
+ static struct
+ {
+ const char *str;
+ const char *chrs;
+ PRBool ret;
+ PRUint32 off;
+ } array[] =
+ {
+ { (const char *)0, (const char *)0, PR_FALSE, 0 },
+ { (const char *)0, "abc", PR_FALSE, 0 },
+ { "abc", (const char *)0, PR_FALSE, 0 },
+ { "abcdefg", "", PR_FALSE, 0 },
+ { "", "aeiou", PR_FALSE, 0 },
+ { "abcdefg", "ae", PR_TRUE, 0 },
+ { "abcdefg", "ei", PR_TRUE, 4 },
+ { "abcdefg", "io", PR_FALSE, 0 },
+ { "abcdefg", "bcd", PR_TRUE, 1 },
+ { "abcdefg", "cbd", PR_TRUE, 1 },
+ { "abcdefg", "dbc", PR_TRUE, 1 },
+ { "abcdefg", "ghi", PR_TRUE, 6 },
+ { "abcdefg", "AE", PR_FALSE, 0 },
+ { "abcdefg", "EI", PR_FALSE, 0 },
+ { "abcdefg", "IO", PR_FALSE, 0 },
+ { "abcdefg", "BCD", PR_FALSE, 0 },
+ { "abcdefg", "CBD", PR_FALSE, 0 },
+ { "abcdefg", "DBC", PR_FALSE, 0 },
+ { "abcdefg", "GHI", PR_FALSE, 0 },
+ { "abcdefgabcdefg", "ae", PR_TRUE, 0 },
+ { "abcdefgabcdefg", "ei", PR_TRUE, 4 },
+ { "abcdefgabcdefg", "io", PR_FALSE, 0 },
+ { "abcdefgabcdefg", "bcd", PR_TRUE, 1 },
+ { "abcdefgabcdefg", "cbd", PR_TRUE, 1 },
+ { "abcdefgabcdefg", "dbc", PR_TRUE, 1 },
+ { "abcdefgabcdefg", "ghi", PR_TRUE, 6 },
+ { "abcdefgabcdefg", "AE", PR_FALSE, 0 },
+ { "abcdefgabcdefg", "EI", PR_FALSE, 0 },
+ { "abcdefgabcdefg", "IO", PR_FALSE, 0 },
+ { "abcdefgabcdefg", "BCD", PR_FALSE, 0 },
+ { "abcdefgabcdefg", "CBD", PR_FALSE, 0 },
+ { "abcdefgabcdefg", "DBC", PR_FALSE, 0 },
+ { "abcdefgabcdefg", "GHI", PR_FALSE, 0 }
+ };
+
+ int i;
+
+ printf("Test 019 (PL_strpbrk) ..."); fflush(stdout);
+
+ for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+ {
+ char *rv = PL_strpbrk(array[i].str, array[i].chrs);
+
+ if( PR_FALSE == array[i].ret )
+ {
+ if( (char *)0 != rv )
+ {
+ printf("FAIL %d: %s,%s -> %.32s, not null\n", i,
+ array[i].str ? array[i].str : "(null)",
+ array[i].chrs ? array[i].chrs : "(null)",
+ rv);
+ return PR_FALSE;
+ }
+ }
+ else
+ {
+ if( (char *)0 == rv )
+ {
+ printf("FAIL %d: %s,%s -> null, not +%lu\n", i,
+ array[i].str ? array[i].str : "(null)",
+ array[i].chrs ? array[i].chrs : "(null)",
+ array[i].off);
+ return PR_FALSE;
+ }
+
+ if( &array[i].str[ array[i].off ] != rv )
+ {
+ printf("FAIL %d: %s,%s -> 0x%x, not 0x%x+%lu\n", i,
+ array[i].str ? array[i].str : "(null)",
+ array[i].chrs ? array[i].chrs : "(null)",
+ rv, array[i].str, array[i].off);
+ return PR_FALSE;
+ }
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_strprbrk */
+PRBool test_020(void)
+{
+ static struct
+ {
+ const char *str;
+ const char *chrs;
+ PRBool ret;
+ PRUint32 off;
+ } array[] =
+ {
+ { (const char *)0, (const char *)0, PR_FALSE, 0 },
+ { (const char *)0, "abc", PR_FALSE, 0 },
+ { "abc", (const char *)0, PR_FALSE, 0 },
+ { "abcdefg", "", PR_FALSE, 0 },
+ { "", "aeiou", PR_FALSE, 0 },
+ { "abcdefg", "ae", PR_TRUE, 4 },
+ { "abcdefg", "ei", PR_TRUE, 4 },
+ { "abcdefg", "io", PR_FALSE, 0 },
+ { "abcdefg", "bcd", PR_TRUE, 3 },
+ { "abcdefg", "cbd", PR_TRUE, 3 },
+ { "abcdefg", "dbc", PR_TRUE, 3 },
+ { "abcdefg", "ghi", PR_TRUE, 6 },
+ { "abcdefg", "AE", PR_FALSE, 0 },
+ { "abcdefg", "EI", PR_FALSE, 0 },
+ { "abcdefg", "IO", PR_FALSE, 0 },
+ { "abcdefg", "BCD", PR_FALSE, 0 },
+ { "abcdefg", "CBD", PR_FALSE, 0 },
+ { "abcdefg", "DBC", PR_FALSE, 0 },
+ { "abcdefg", "GHI", PR_FALSE, 0 },
+ { "abcdefgabcdefg", "ae", PR_TRUE, 11 },
+ { "abcdefgabcdefg", "ei", PR_TRUE, 11 },
+ { "abcdefgabcdefg", "io", PR_FALSE, 0 },
+ { "abcdefgabcdefg", "bcd", PR_TRUE, 10 },
+ { "abcdefgabcdefg", "cbd", PR_TRUE, 10 },
+ { "abcdefgabcdefg", "dbc", PR_TRUE, 10 },
+ { "abcdefgabcdefg", "ghi", PR_TRUE, 13 },
+ { "abcdefgabcdefg", "AE", PR_FALSE, 0 },
+ { "abcdefgabcdefg", "EI", PR_FALSE, 0 },
+ { "abcdefgabcdefg", "IO", PR_FALSE, 0 },
+ { "abcdefgabcdefg", "BCD", PR_FALSE, 0 },
+ { "abcdefgabcdefg", "CBD", PR_FALSE, 0 },
+ { "abcdefgabcdefg", "DBC", PR_FALSE, 0 },
+ { "abcdefgabcdefg", "GHI", PR_FALSE, 0 }
+ };
+
+ int i;
+
+ printf("Test 020 (PL_strprbrk) ..."); fflush(stdout);
+
+ for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+ {
+ char *rv = PL_strprbrk(array[i].str, array[i].chrs);
+
+ if( PR_FALSE == array[i].ret )
+ {
+ if( (char *)0 != rv )
+ {
+ printf("FAIL %d: %s,%s -> %.32s, not null\n", i,
+ array[i].str ? array[i].str : "(null)",
+ array[i].chrs ? array[i].chrs : "(null)",
+ rv);
+ return PR_FALSE;
+ }
+ }
+ else
+ {
+ if( (char *)0 == rv )
+ {
+ printf("FAIL %d: %s,%s -> null, not +%lu\n", i,
+ array[i].str ? array[i].str : "(null)",
+ array[i].chrs ? array[i].chrs : "(null)",
+ array[i].off);
+ return PR_FALSE;
+ }
+
+ if( &array[i].str[ array[i].off ] != rv )
+ {
+ printf("FAIL %d: %s,%s -> 0x%x, not 0x%x+%lu\n", i,
+ array[i].str ? array[i].str : "(null)",
+ array[i].chrs ? array[i].chrs : "(null)",
+ rv, array[i].str, array[i].off);
+ return PR_FALSE;
+ }
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_strnpbrk */
+PRBool test_021(void)
+{
+ static struct
+ {
+ const char *str;
+ const char *chrs;
+ PRUint32 max;
+ PRBool ret;
+ PRUint32 off;
+ } array[] =
+ {
+ { (const char *)0, (const char *)0, 3, PR_FALSE, 0 },
+ { (const char *)0, "abc", 3, PR_FALSE, 0 },
+ { "abc", (const char *)0, 3, PR_FALSE, 0 },
+ { "abcdefg", "", 3, PR_FALSE, 0 },
+ { "", "aeiou", 3, PR_FALSE, 0 },
+ { "abcdefg", "ae", 0, PR_FALSE, 0 },
+ { "abcdefg", "ae", 1, PR_TRUE, 0 },
+ { "abcdefg", "ae", 4, PR_TRUE, 0 },
+ { "abcdefg", "ae", 5, PR_TRUE, 0 },
+ { "abcdefg", "ae", 6, PR_TRUE, 0 },
+ { "abcdefg", "ei", 4, PR_FALSE, 0 },
+ { "abcdefg", "io", 10, PR_FALSE, 0 },
+ { "abcdefg", "bcd", 2, PR_TRUE, 1 },
+ { "abcdefg", "cbd", 2, PR_TRUE, 1 },
+ { "abcdefg", "dbc", 2, PR_TRUE, 1 },
+ { "abcdefg", "ghi", 6, PR_FALSE, 0 },
+ { "abcdefg", "ghi", 7, PR_TRUE, 6 },
+ { "abcdefg", "AE", 9, PR_FALSE, 0 },
+ { "abcdefg", "EI", 9, PR_FALSE, 0 },
+ { "abcdefg", "IO", 9, PR_FALSE, 0 },
+ { "abcdefg", "BCD", 9, PR_FALSE, 0 },
+ { "abcdefg", "CBD", 9, PR_FALSE, 0 },
+ { "abcdefg", "DBC", 9, PR_FALSE, 0 },
+ { "abcdefg", "GHI", 9, PR_FALSE, 0 },
+ { "abcdefgabcdefg", "ae", 10, PR_TRUE, 0 },
+ { "abcdefgabcdefg", "ei", 10, PR_TRUE, 4 },
+ { "abcdefgabcdefg", "io", 10, PR_FALSE, 0 },
+ { "abcdefgabcdefg", "bcd", 10, PR_TRUE, 1 },
+ { "abcdefgabcdefg", "cbd", 10, PR_TRUE, 1 },
+ { "abcdefgabcdefg", "dbc", 10, PR_TRUE, 1 },
+ { "abcdefgabcdefg", "ghi", 10, PR_TRUE, 6 },
+ { "abcdefgabcdefg", "AE", 10, PR_FALSE, 0 },
+ { "abcdefgabcdefg", "EI", 10, PR_FALSE, 0 },
+ { "abcdefgabcdefg", "IO", 10, PR_FALSE, 0 },
+ { "abcdefgabcdefg", "BCD", 10, PR_FALSE, 0 },
+ { "abcdefgabcdefg", "CBD", 10, PR_FALSE, 0 },
+ { "abcdefgabcdefg", "DBC", 10, PR_FALSE, 0 },
+ { "abcdefgabcdefg", "GHI", 10, PR_FALSE, 0 }
+ };
+
+ int i;
+
+ printf("Test 021 (PL_strnpbrk) ..."); fflush(stdout);
+
+ for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+ {
+ char *rv = PL_strnpbrk(array[i].str, array[i].chrs, array[i].max);
+
+ if( PR_FALSE == array[i].ret )
+ {
+ if( (char *)0 != rv )
+ {
+ printf("FAIL %d: %s,%s/%lu -> %.32s, not null\n", i,
+ array[i].str ? array[i].str : "(null)",
+ array[i].chrs ? array[i].chrs : "(null)",
+ array[i].max, rv);
+ return PR_FALSE;
+ }
+ }
+ else
+ {
+ if( (char *)0 == rv )
+ {
+ printf("FAIL %d: %s,%s/%lu -> null, not +%lu\n", i,
+ array[i].str ? array[i].str : "(null)",
+ array[i].chrs ? array[i].chrs : "(null)",
+ array[i].max, array[i].off);
+ return PR_FALSE;
+ }
+
+ if( &array[i].str[ array[i].off ] != rv )
+ {
+ printf("FAIL %d: %s,%s/%lu -> 0x%x, not 0x%x+%lu\n", i,
+ array[i].str ? array[i].str : "(null)",
+ array[i].chrs ? array[i].chrs : "(null)",
+ array[i].max, rv, array[i].str, array[i].off);
+ return PR_FALSE;
+ }
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_strnprbrk */
+PRBool test_022(void)
+{
+ static struct
+ {
+ const char *str;
+ const char *chrs;
+ PRUint32 max;
+ PRBool ret;
+ PRUint32 off;
+ } array[] =
+ {
+ { (const char *)0, (const char *)0, 3, PR_FALSE, 0 },
+ { (const char *)0, "abc", 3, PR_FALSE, 0 },
+ { "abc", (const char *)0, 3, PR_FALSE, 0 },
+ { "abcdefg", "", 3, PR_FALSE, 0 },
+ { "", "aeiou", 3, PR_FALSE, 0 },
+ { "abcdefg", "ae", 0, PR_FALSE, 0 },
+ { "abcdefg", "ae", 1, PR_TRUE, 0 },
+ { "abcdefg", "ae", 4, PR_TRUE, 0 },
+ { "abcdefg", "ae", 5, PR_TRUE, 4 },
+ { "abcdefg", "ae", 6, PR_TRUE, 4 },
+ { "abcdefg", "ei", 4, PR_FALSE, 0 },
+ { "abcdefg", "io", 10, PR_FALSE, 0 },
+ { "abcdefg", "bcd", 2, PR_TRUE, 1 },
+ { "abcdefg", "cbd", 2, PR_TRUE, 1 },
+ { "abcdefg", "dbc", 2, PR_TRUE, 1 },
+ { "abcdefg", "bcd", 3, PR_TRUE, 2 },
+ { "abcdefg", "cbd", 3, PR_TRUE, 2 },
+ { "abcdefg", "dbc", 3, PR_TRUE, 2 },
+ { "abcdefg", "bcd", 5, PR_TRUE, 3 },
+ { "abcdefg", "cbd", 5, PR_TRUE, 3 },
+ { "abcdefg", "dbc", 5, PR_TRUE, 3 },
+ { "abcdefg", "bcd", 15, PR_TRUE, 3 },
+ { "abcdefg", "cbd", 15, PR_TRUE, 3 },
+ { "abcdefg", "dbc", 15, PR_TRUE, 3 },
+ { "abcdefg", "ghi", 6, PR_FALSE, 0 },
+ { "abcdefg", "ghi", 7, PR_TRUE, 6 },
+ { "abcdefg", "AE", 9, PR_FALSE, 0 },
+ { "abcdefg", "EI", 9, PR_FALSE, 0 },
+ { "abcdefg", "IO", 9, PR_FALSE, 0 },
+ { "abcdefg", "BCD", 9, PR_FALSE, 0 },
+ { "abcdefg", "CBD", 9, PR_FALSE, 0 },
+ { "abcdefg", "DBC", 9, PR_FALSE, 0 },
+ { "abcdefg", "GHI", 9, PR_FALSE, 0 },
+ { "abcdefgabcdefg", "ae", 10, PR_TRUE, 7 },
+ { "abcdefgabcdefg", "ei", 10, PR_TRUE, 4 },
+ { "abcdefgabcdefg", "io", 10, PR_FALSE, 0 },
+ { "abcdefgabcdefg", "bcd", 10, PR_TRUE, 9 },
+ { "abcdefgabcdefg", "cbd", 10, PR_TRUE, 9 },
+ { "abcdefgabcdefg", "dbc", 10, PR_TRUE, 9 },
+ { "abcdefgabcdefg", "ghi", 10, PR_TRUE, 6 },
+ { "abcdefgabcdefg", "AE", 10, PR_FALSE, 0 },
+ { "abcdefgabcdefg", "EI", 10, PR_FALSE, 0 },
+ { "abcdefgabcdefg", "IO", 10, PR_FALSE, 0 },
+ { "abcdefgabcdefg", "BCD", 10, PR_FALSE, 0 },
+ { "abcdefgabcdefg", "CBD", 10, PR_FALSE, 0 },
+ { "abcdefgabcdefg", "DBC", 10, PR_FALSE, 0 },
+ { "abcdefgabcdefg", "GHI", 10, PR_FALSE, 0 }
+ };
+
+ int i;
+
+ printf("Test 022 (PL_strnprbrk) ..."); fflush(stdout);
+
+ for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+ {
+ char *rv = PL_strnprbrk(array[i].str, array[i].chrs, array[i].max);
+
+ if( PR_FALSE == array[i].ret )
+ {
+ if( (char *)0 != rv )
+ {
+ printf("FAIL %d: %s,%s/%lu -> %.32s, not null\n", i,
+ array[i].str ? array[i].str : "(null)",
+ array[i].chrs ? array[i].chrs : "(null)",
+ array[i].max, rv);
+ return PR_FALSE;
+ }
+ }
+ else
+ {
+ if( (char *)0 == rv )
+ {
+ printf("FAIL %d: %s,%s/%lu -> null, not +%lu\n", i,
+ array[i].str ? array[i].str : "(null)",
+ array[i].chrs ? array[i].chrs : "(null)",
+ array[i].max, array[i].off);
+ return PR_FALSE;
+ }
+
+ if( &array[i].str[ array[i].off ] != rv )
+ {
+ printf("FAIL %d: %s,%s/%lu -> 0x%x, not 0x%x+%lu\n", i,
+ array[i].str ? array[i].str : "(null)",
+ array[i].chrs ? array[i].chrs : "(null)",
+ array[i].max, rv, array[i].str, array[i].off);
+ return PR_FALSE;
+ }
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_strstr */
+PRBool test_023(void)
+{
+ static struct
+ {
+ const char *str;
+ const char *sub;
+ PRBool ret;
+ PRUint32 off;
+ } array[] =
+ {
+ { (const char *)0, (const char *)0, PR_FALSE, 0 },
+ { (const char *)0, "blah", PR_FALSE, 0 },
+ { "blah-de-blah", (const char *)0, PR_FALSE, 0 },
+ { "blah-de-blah", "blah", PR_TRUE, 0 },
+ { "", "blah", PR_FALSE, 0 },
+ { "blah-de-blah", "", PR_FALSE, 0 },
+ { "abcdefg", "a", PR_TRUE, 0 },
+ { "abcdefg", "c", PR_TRUE, 2 },
+ { "abcdefg", "e", PR_TRUE, 4 },
+ { "abcdefg", "g", PR_TRUE, 6 },
+ { "abcdefg", "i", PR_FALSE, 0 },
+ { "abcdefg", "ab", PR_TRUE, 0 },
+ { "abcdefg", "cd", PR_TRUE, 2 },
+ { "abcdefg", "ef", PR_TRUE, 4 },
+ { "abcdefg", "gh", PR_FALSE, 0 },
+ { "abcdabc", "bc", PR_TRUE, 1 },
+ { "abcdefg", "abcdefg", PR_TRUE, 0 },
+ { "abcdefgabcdefg", "a", PR_TRUE, 0 },
+ { "abcdefgabcdefg", "c", PR_TRUE, 2 },
+ { "abcdefgabcdefg", "e", PR_TRUE, 4 },
+ { "abcdefgabcdefg", "g", PR_TRUE, 6 },
+ { "abcdefgabcdefg", "i", PR_FALSE, 0 },
+ { "abcdefgabcdefg", "ab", PR_TRUE, 0 },
+ { "abcdefgabcdefg", "cd", PR_TRUE, 2 },
+ { "abcdefgabcdefg", "ef", PR_TRUE, 4 },
+ { "abcdefgabcdefg", "gh", PR_FALSE, 0 },
+ { "abcdabcabcdabc", "bc", PR_TRUE, 1 },
+ { "abcdefgabcdefg", "abcdefg", PR_TRUE, 0 },
+ { "ABCDEFG", "a", PR_FALSE, 0 },
+ { "ABCDEFG", "c", PR_FALSE, 0 },
+ { "ABCDEFG", "e", PR_FALSE, 0 },
+ { "ABCDEFG", "g", PR_FALSE, 0 },
+ { "ABCDEFG", "i", PR_FALSE, 0 },
+ { "ABCDEFG", "ab", PR_FALSE, 0 },
+ { "ABCDEFG", "cd", PR_FALSE, 0 },
+ { "ABCDEFG", "ef", PR_FALSE, 0 },
+ { "ABCDEFG", "gh", PR_FALSE, 0 },
+ { "ABCDABC", "bc", PR_FALSE, 0 },
+ { "ABCDEFG", "abcdefg", PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "a", PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "c", PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "e", PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "g", PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "i", PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "ab", PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "cd", PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "ef", PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "gh", PR_FALSE, 0 },
+ { "ABCDABCABCDABC", "bc", PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "abcdefg", PR_FALSE, 0 }
+ };
+
+ int i;
+
+ printf("Test 023 (PL_strstr) ..."); fflush(stdout);
+
+ for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+ {
+ char *rv = PL_strstr(array[i].str, array[i].sub);
+
+ if( PR_FALSE == array[i].ret )
+ {
+ if( (char *)0 != rv )
+ {
+ printf("FAIL %d: %s,%s -> %.32s, not null\n", i,
+ array[i].str ? array[i].str : "(null)",
+ array[i].sub ? array[i].sub : "(null)",
+ rv);
+ return PR_FALSE;
+ }
+ }
+ else
+ {
+ if( (char *)0 == rv )
+ {
+ printf("FAIL %d: %s,%s -> null, not 0x%x+%lu\n", i,
+ array[i].str ? array[i].str : "(null)",
+ array[i].sub ? array[i].sub : "(null)",
+ array[i].str, array[i].off);
+ return PR_FALSE;
+ }
+
+ if( &array[i].str[ array[i].off ] != rv )
+ {
+ printf("FAIL %d: %s,%s -> 0x%x, not 0x%x+%lu\n", i,
+ array[i].str ? array[i].str : "(null)",
+ array[i].sub ? array[i].sub : "(null)",
+ rv, array[i].str, array[i].off);
+ return PR_FALSE;
+ }
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_strrstr */
+PRBool test_024(void)
+{
+ static struct
+ {
+ const char *str;
+ const char *sub;
+ PRBool ret;
+ PRUint32 off;
+ } array[] =
+ {
+ { (const char *)0, (const char *)0, PR_FALSE, 0 },
+ { (const char *)0, "blah", PR_FALSE, 0 },
+ { "blah-de-blah", (const char *)0, PR_FALSE, 0 },
+ { "blah-de-blah", "blah", PR_TRUE, 8 },
+ { "", "blah", PR_FALSE, 0 },
+ { "blah-de-blah", "", PR_FALSE, 0 },
+ { "abcdefg", "a", PR_TRUE, 0 },
+ { "abcdefg", "c", PR_TRUE, 2 },
+ { "abcdefg", "e", PR_TRUE, 4 },
+ { "abcdefg", "g", PR_TRUE, 6 },
+ { "abcdefg", "i", PR_FALSE, 0 },
+ { "abcdefg", "ab", PR_TRUE, 0 },
+ { "abcdefg", "cd", PR_TRUE, 2 },
+ { "abcdefg", "ef", PR_TRUE, 4 },
+ { "abcdefg", "gh", PR_FALSE, 0 },
+ { "abcdabc", "bc", PR_TRUE, 5 },
+ { "abcdefg", "abcdefg", PR_TRUE, 0 },
+ { "abcdefgabcdefg", "a", PR_TRUE, 7 },
+ { "abcdefgabcdefg", "c", PR_TRUE, 9 },
+ { "abcdefgabcdefg", "e", PR_TRUE, 11 },
+ { "abcdefgabcdefg", "g", PR_TRUE, 13 },
+ { "abcdefgabcdefg", "i", PR_FALSE, 0 },
+ { "abcdefgabcdefg", "ab", PR_TRUE, 7 },
+ { "abcdefgabcdefg", "cd", PR_TRUE, 9 },
+ { "abcdefgabcdefg", "ef", PR_TRUE, 11 },
+ { "abcdefgabcdefg", "gh", PR_FALSE, 0 },
+ { "abcdabcabcdabc", "bc", PR_TRUE, 12 },
+ { "abcdefgabcdefg", "abcdefg", PR_TRUE, 7 },
+ { "ABCDEFG", "a", PR_FALSE, 0 },
+ { "ABCDEFG", "c", PR_FALSE, 0 },
+ { "ABCDEFG", "e", PR_FALSE, 0 },
+ { "ABCDEFG", "g", PR_FALSE, 0 },
+ { "ABCDEFG", "i", PR_FALSE, 0 },
+ { "ABCDEFG", "ab", PR_FALSE, 0 },
+ { "ABCDEFG", "cd", PR_FALSE, 0 },
+ { "ABCDEFG", "ef", PR_FALSE, 0 },
+ { "ABCDEFG", "gh", PR_FALSE, 0 },
+ { "ABCDABC", "bc", PR_FALSE, 0 },
+ { "ABCDEFG", "abcdefg", PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "a", PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "c", PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "e", PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "g", PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "i", PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "ab", PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "cd", PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "ef", PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "gh", PR_FALSE, 0 },
+ { "ABCDABCABCDABC", "bc", PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "abcdefg", PR_FALSE, 0 }
+ };
+
+ int i;
+
+ printf("Test 024 (PL_strrstr) ..."); fflush(stdout);
+
+ for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+ {
+ char *rv = PL_strrstr(array[i].str, array[i].sub);
+
+ if( PR_FALSE == array[i].ret )
+ {
+ if( (char *)0 != rv )
+ {
+ printf("FAIL %d: %s,%s -> %.32s, not null\n", i,
+ array[i].str ? array[i].str : "(null)",
+ array[i].sub ? array[i].sub : "(null)",
+ rv);
+ return PR_FALSE;
+ }
+ }
+ else
+ {
+ if( (char *)0 == rv )
+ {
+ printf("FAIL %d: %s,%s -> null, not 0x%x+%lu\n", i,
+ array[i].str ? array[i].str : "(null)",
+ array[i].sub ? array[i].sub : "(null)",
+ array[i].str, array[i].off);
+ return PR_FALSE;
+ }
+
+ if( &array[i].str[ array[i].off ] != rv )
+ {
+ printf("FAIL %d: %s,%s -> 0x%x, not 0x%x+%lu\n", i,
+ array[i].str ? array[i].str : "(null)",
+ array[i].sub ? array[i].sub : "(null)",
+ rv, array[i].str, array[i].off);
+ return PR_FALSE;
+ }
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_strnstr */
+PRBool test_025(void)
+{
+ static struct
+ {
+ const char *str;
+ const char *sub;
+ PRUint32 max;
+ PRBool ret;
+ PRUint32 off;
+ } array[] =
+ {
+ { (const char *)0, (const char *)0, 12, PR_FALSE, 0 },
+ { (const char *)0, "blah", 12, PR_FALSE, 0 },
+ { "blah-de-blah", (const char *)0, 12, PR_FALSE, 0 },
+ { "blah-de-blah", "blah", 0, PR_FALSE, 0 },
+ { "blah-de-blah", "blah", 2, PR_FALSE, 0 },
+ { "blah-de-blah", "blah", 3, PR_FALSE, 0 },
+ { "blah-de-blah", "blah", 4, PR_TRUE, 0 },
+ { "blah-de-blah", "blah", 5, PR_TRUE, 0 },
+ { "blah-de-blah", "blah", 12, PR_TRUE, 0 },
+ { "", "blah", 12, PR_FALSE, 0 },
+ { "blah-de-blah", "", 12, PR_FALSE, 0 },
+ { "abcdefg", "a", 5, PR_TRUE, 0 },
+ { "abcdefg", "c", 5, PR_TRUE, 2 },
+ { "abcdefg", "e", 5, PR_TRUE, 4 },
+ { "abcdefg", "g", 5, PR_FALSE, 0 },
+ { "abcdefg", "i", 5, PR_FALSE, 0 },
+ { "abcdefg", "ab", 5, PR_TRUE, 0 },
+ { "abcdefg", "cd", 5, PR_TRUE, 2 },
+ { "abcdefg", "ef", 5, PR_FALSE, 0 },
+ { "abcdefg", "gh", 5, PR_FALSE, 0 },
+ { "abcdabc", "bc", 5, PR_TRUE, 1 },
+ { "abcdabc", "bc", 6, PR_TRUE, 1 },
+ { "abcdabc", "bc", 7, PR_TRUE, 1 },
+ { "abcdefg", "abcdefg", 6, PR_FALSE, 0 },
+ { "abcdefg", "abcdefg", 7, PR_TRUE, 0 },
+ { "abcdefg", "abcdefg", 8, PR_TRUE, 0 },
+ { "abcdefgabcdefg", "a", 12, PR_TRUE, 0 },
+ { "abcdefgabcdefg", "c", 12, PR_TRUE, 2 },
+ { "abcdefgabcdefg", "e", 12, PR_TRUE, 4 },
+ { "abcdefgabcdefg", "g", 12, PR_TRUE, 6 },
+ { "abcdefgabcdefg", "i", 12, PR_FALSE, 0 },
+ { "abcdefgabcdefg", "ab", 12, PR_TRUE, 0 },
+ { "abcdefgabcdefg", "cd", 12, PR_TRUE, 2 },
+ { "abcdefgabcdefg", "ef", 12, PR_TRUE, 4 },
+ { "abcdefgabcdefg", "gh", 12, PR_FALSE, 0 },
+ { "abcdabcabcdabc", "bc", 5, PR_TRUE, 1 },
+ { "abcdabcabcdabc", "bc", 6, PR_TRUE, 1 },
+ { "abcdabcabcdabc", "bc", 7, PR_TRUE, 1 },
+ { "abcdefgabcdefg", "abcdefg", 6, PR_FALSE, 0 },
+ { "abcdefgabcdefg", "abcdefg", 7, PR_TRUE, 0 },
+ { "abcdefgabcdefg", "abcdefg", 8, PR_TRUE, 0 },
+ { "ABCDEFG", "a", 5, PR_FALSE, 0 },
+ { "ABCDEFG", "c", 5, PR_FALSE, 0 },
+ { "ABCDEFG", "e", 5, PR_FALSE, 0 },
+ { "ABCDEFG", "g", 5, PR_FALSE, 0 },
+ { "ABCDEFG", "i", 5, PR_FALSE, 0 },
+ { "ABCDEFG", "ab", 5, PR_FALSE, 0 },
+ { "ABCDEFG", "cd", 5, PR_FALSE, 0 },
+ { "ABCDEFG", "ef", 5, PR_FALSE, 0 },
+ { "ABCDEFG", "gh", 5, PR_FALSE, 0 },
+ { "ABCDABC", "bc", 5, PR_FALSE, 0 },
+ { "ABCDABC", "bc", 6, PR_FALSE, 0 },
+ { "ABCDABC", "bc", 7, PR_FALSE, 0 },
+ { "ABCDEFG", "abcdefg", 6, PR_FALSE, 0 },
+ { "ABCDEFG", "abcdefg", 7, PR_FALSE, 0 },
+ { "ABCDEFG", "abcdefg", 8, PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "a", 12, PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "c", 12, PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "e", 12, PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "g", 12, PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "i", 12, PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "ab", 12, PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "cd", 12, PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "ef", 12, PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "gh", 12, PR_FALSE, 0 },
+ { "ABCDABCABCDABC", "bc", 5, PR_FALSE, 0 },
+ { "ABCDABCABCDABC", "bc", 6, PR_FALSE, 0 },
+ { "ABCDABCABCDABC", "bc", 7, PR_FALSE, },
+ { "ABCDEFGABCDEFG", "abcdefg", 6, PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "abcdefg", 7, PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "abcdefg", 8, PR_FALSE, 0 }
+ };
+
+ int i;
+
+ printf("Test 025 (PL_strnstr) ..."); fflush(stdout);
+
+ for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+ {
+ char *rv = PL_strnstr(array[i].str, array[i].sub, array[i].max);
+
+ if( PR_FALSE == array[i].ret )
+ {
+ if( (char *)0 != rv )
+ {
+ printf("FAIL %d: %s,%s/%lu -> %.32s, not null\n", i,
+ array[i].str ? array[i].str : "(null)",
+ array[i].sub ? array[i].sub : "(null)",
+ array[i].max, rv);
+ return PR_FALSE;
+ }
+ }
+ else
+ {
+ if( (char *)0 == rv )
+ {
+ printf("FAIL %d: %s,%s/%lu -> null, not 0x%x+%lu\n", i,
+ array[i].str ? array[i].str : "(null)",
+ array[i].sub ? array[i].sub : "(null)",
+ array[i].max, array[i].str, array[i].off);
+ return PR_FALSE;
+ }
+
+ if( &array[i].str[ array[i].off ] != rv )
+ {
+ printf("FAIL %d: %s,%s/%lu -> 0x%x, not 0x%x+%lu\n", i,
+ array[i].str ? array[i].str : "(null)",
+ array[i].sub ? array[i].sub : "(null)",
+ array[i].max, rv, array[i].str, array[i].off);
+ return PR_FALSE;
+ }
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_strnrstr */
+PRBool test_026(void)
+{
+ static struct
+ {
+ const char *str;
+ const char *sub;
+ PRUint32 max;
+ PRBool ret;
+ PRUint32 off;
+ } array[] =
+ {
+ { (const char *)0, (const char *)0, 12, PR_FALSE, 0 },
+ { (const char *)0, "blah", 12, PR_FALSE, 0 },
+ { "blah-de-blah", (const char *)0, 12, PR_FALSE, 0 },
+ { "blah-de-blah", "blah", 0, PR_FALSE, 0 },
+ { "blah-de-blah", "blah", 2, PR_FALSE, 0 },
+ { "blah-de-blah", "blah", 3, PR_FALSE, 0 },
+ { "blah-de-blah", "blah", 4, PR_TRUE, 0 },
+ { "blah-de-blah", "blah", 5, PR_TRUE, 0 },
+ { "blah-de-blah", "blah", 11, PR_TRUE, 0 },
+ { "blah-de-blah", "blah", 12, PR_TRUE, 8 },
+ { "blah-de-blah", "blah", 13, PR_TRUE, 8 },
+ { "", "blah", 12, PR_FALSE, 0 },
+ { "blah-de-blah", "", 12, PR_FALSE, 0 },
+ { "abcdefg", "a", 5, PR_TRUE, 0 },
+ { "abcdefg", "c", 5, PR_TRUE, 2 },
+ { "abcdefg", "e", 5, PR_TRUE, 4 },
+ { "abcdefg", "g", 5, PR_FALSE, 0 },
+ { "abcdefg", "i", 5, PR_FALSE, 0 },
+ { "abcdefg", "ab", 5, PR_TRUE, 0 },
+ { "abcdefg", "cd", 5, PR_TRUE, 2 },
+ { "abcdefg", "ef", 5, PR_FALSE, 0 },
+ { "abcdefg", "gh", 5, PR_FALSE, 0 },
+ { "abcdabc", "bc", 5, PR_TRUE, 1 },
+ { "abcdabc", "bc", 6, PR_TRUE, 1 },
+ { "abcdabc", "bc", 7, PR_TRUE, 5 },
+ { "abcdefg", "abcdefg", 6, PR_FALSE, 0 },
+ { "abcdefg", "abcdefg", 7, PR_TRUE, 0 },
+ { "abcdefg", "abcdefg", 8, PR_TRUE, 0 },
+ { "abcdefgabcdefg", "a", 12, PR_TRUE, 7 },
+ { "abcdefgabcdefg", "c", 12, PR_TRUE, 9 },
+ { "abcdefgabcdefg", "e", 12, PR_TRUE, 11 },
+ { "abcdefgabcdefg", "g", 12, PR_TRUE, 6 },
+ { "abcdefgabcdefg", "i", 12, PR_FALSE, 0 },
+ { "abcdefgabcdefg", "ab", 12, PR_TRUE, 7 },
+ { "abcdefgabcdefg", "cd", 12, PR_TRUE, 9 },
+ { "abcdefgabcdefg", "ef", 12, PR_TRUE, 4 },
+ { "abcdefgabcdefg", "gh", 12, PR_FALSE, 0 },
+ { "abcdabcabcdabc", "bc", 12, PR_TRUE, 8 },
+ { "abcdabcabcdabc", "bc", 13, PR_TRUE, 8 },
+ { "abcdabcabcdabc", "bc", 14, PR_TRUE, 12 },
+ { "abcdefgabcdefg", "abcdefg", 13, PR_TRUE, 0 },
+ { "abcdefgabcdefg", "abcdefg", 14, PR_TRUE, 7 },
+ { "abcdefgabcdefg", "abcdefg", 15, PR_TRUE, 7 },
+ { "ABCDEFG", "a", 5, PR_FALSE, 0 },
+ { "ABCDEFG", "c", 5, PR_FALSE, 0 },
+ { "ABCDEFG", "e", 5, PR_FALSE, 0 },
+ { "ABCDEFG", "g", 5, PR_FALSE, 0 },
+ { "ABCDEFG", "i", 5, PR_FALSE, 0 },
+ { "ABCDEFG", "ab", 5, PR_FALSE, 0 },
+ { "ABCDEFG", "cd", 5, PR_FALSE, 0 },
+ { "ABCDEFG", "ef", 5, PR_FALSE, 0 },
+ { "ABCDEFG", "gh", 5, PR_FALSE, 0 },
+ { "ABCDABC", "bc", 5, PR_FALSE, 0 },
+ { "ABCDABC", "bc", 6, PR_FALSE, 0 },
+ { "ABCDABC", "bc", 7, PR_FALSE, 0 },
+ { "ABCDEFG", "abcdefg", 6, PR_FALSE, 0 },
+ { "ABCDEFG", "abcdefg", 7, PR_FALSE, 0 },
+ { "ABCDEFG", "abcdefg", 8, PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "a", 12, PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "c", 12, PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "e", 12, PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "g", 12, PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "i", 12, PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "ab", 12, PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "cd", 12, PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "ef", 12, PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "gh", 12, PR_FALSE, 0 },
+ { "ABCDABCABCDABC", "bc", 12, PR_FALSE, 0 },
+ { "ABCDABCABCDABC", "bc", 13, PR_FALSE, 0 },
+ { "ABCDABCABCDABC", "bc", 14, PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "abcdefg", 13, PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "abcdefg", 14, PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "abcdefg", 15, PR_FALSE, 0 }
+ };
+
+ int i;
+
+ printf("Test 026 (PL_strnrstr) ..."); fflush(stdout);
+
+ for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+ {
+ char *rv = PL_strnrstr(array[i].str, array[i].sub, array[i].max);
+
+ if( PR_FALSE == array[i].ret )
+ {
+ if( (char *)0 != rv )
+ {
+ printf("FAIL %d: %s,%s/%lu -> %.32s, not null\n", i,
+ array[i].str ? array[i].str : "(null)",
+ array[i].sub ? array[i].sub : "(null)",
+ array[i].max, rv);
+ return PR_FALSE;
+ }
+ }
+ else
+ {
+ if( (char *)0 == rv )
+ {
+ printf("FAIL %d: %s,%s/%lu -> null, not 0x%x+%lu\n", i,
+ array[i].str ? array[i].str : "(null)",
+ array[i].sub ? array[i].sub : "(null)",
+ array[i].max, array[i].str, array[i].off);
+ return PR_FALSE;
+ }
+
+ if( &array[i].str[ array[i].off ] != rv )
+ {
+ printf("FAIL %d: %s,%s/%lu -> 0x%x, not 0x%x+%lu\n", i,
+ array[i].str ? array[i].str : "(null)",
+ array[i].sub ? array[i].sub : "(null)",
+ array[i].max, rv, array[i].str, array[i].off);
+ return PR_FALSE;
+ }
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_strcasestr */
+PRBool test_027(void)
+{
+ static struct
+ {
+ const char *str;
+ const char *sub;
+ PRBool ret;
+ PRUint32 off;
+ } array[] =
+ {
+ { (const char *)0, (const char *)0, PR_FALSE, 0 },
+ { (const char *)0, "blah", PR_FALSE, 0 },
+ { "blah-de-blah", (const char *)0, PR_FALSE, 0 },
+ { "blah-de-blah", "blah", PR_TRUE, 0 },
+ { "", "blah", PR_FALSE, 0 },
+ { "blah-de-blah", "", PR_FALSE, 0 },
+ { "abcdefg", "a", PR_TRUE, 0 },
+ { "abcdefg", "c", PR_TRUE, 2 },
+ { "abcdefg", "e", PR_TRUE, 4 },
+ { "abcdefg", "g", PR_TRUE, 6 },
+ { "abcdefg", "i", PR_FALSE, 0 },
+ { "abcdefg", "ab", PR_TRUE, 0 },
+ { "abcdefg", "cd", PR_TRUE, 2 },
+ { "abcdefg", "ef", PR_TRUE, 4 },
+ { "abcdefg", "gh", PR_FALSE, 0 },
+ { "abcdabc", "bc", PR_TRUE, 1 },
+ { "abcdefg", "abcdefg", PR_TRUE, 0 },
+ { "abcdefgabcdefg", "a", PR_TRUE, 0 },
+ { "abcdefgabcdefg", "c", PR_TRUE, 2 },
+ { "abcdefgabcdefg", "e", PR_TRUE, 4 },
+ { "abcdefgabcdefg", "g", PR_TRUE, 6 },
+ { "abcdefgabcdefg", "i", PR_FALSE, 0 },
+ { "abcdefgabcdefg", "ab", PR_TRUE, 0 },
+ { "abcdefgabcdefg", "cd", PR_TRUE, 2 },
+ { "abcdefgabcdefg", "ef", PR_TRUE, 4 },
+ { "abcdefgabcdefg", "gh", PR_FALSE, 0 },
+ { "abcdabcabcdabc", "bc", PR_TRUE, 1 },
+ { "abcdefgabcdefg", "abcdefg", PR_TRUE, 0 },
+ { "ABCDEFG", "a", PR_TRUE, 0 },
+ { "ABCDEFG", "c", PR_TRUE, 2 },
+ { "ABCDEFG", "e", PR_TRUE, 4 },
+ { "ABCDEFG", "g", PR_TRUE, 6 },
+ { "ABCDEFG", "i", PR_FALSE, 0 },
+ { "ABCDEFG", "ab", PR_TRUE, 0 },
+ { "ABCDEFG", "cd", PR_TRUE, 2 },
+ { "ABCDEFG", "ef", PR_TRUE, 4 },
+ { "ABCDEFG", "gh", PR_FALSE, 0 },
+ { "ABCDABC", "bc", PR_TRUE, 1 },
+ { "ABCDEFG", "abcdefg", PR_TRUE, 0 },
+ { "ABCDEFGABCDEFG", "a", PR_TRUE, 0 },
+ { "ABCDEFGABCDEFG", "c", PR_TRUE, 2 },
+ { "ABCDEFGABCDEFG", "e", PR_TRUE, 4 },
+ { "ABCDEFGABCDEFG", "g", PR_TRUE, 6 },
+ { "ABCDEFGABCDEFG", "i", PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "ab", PR_TRUE, 0 },
+ { "ABCDEFGABCDEFG", "cd", PR_TRUE, 2 },
+ { "ABCDEFGABCDEFG", "ef", PR_TRUE, 4 },
+ { "ABCDEFGABCDEFG", "gh", PR_FALSE, 0 },
+ { "ABCDABCABCDABC", "bc", PR_TRUE, 1 },
+ { "ABCDEFGABCDEFG", "abcdefg", PR_TRUE, 0 }
+ };
+
+ int i;
+
+ printf("Test 027 (PL_strcasestr) ..."); fflush(stdout);
+
+ for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+ {
+ char *rv = PL_strcasestr(array[i].str, array[i].sub);
+
+ if( PR_FALSE == array[i].ret )
+ {
+ if( (char *)0 != rv )
+ {
+ printf("FAIL %d: %s,%s -> %.32s, not null\n", i,
+ array[i].str ? array[i].str : "(null)",
+ array[i].sub ? array[i].sub : "(null)",
+ rv);
+ return PR_FALSE;
+ }
+ }
+ else
+ {
+ if( (char *)0 == rv )
+ {
+ printf("FAIL %d: %s,%s -> null, not 0x%x+%lu\n", i,
+ array[i].str ? array[i].str : "(null)",
+ array[i].sub ? array[i].sub : "(null)",
+ array[i].str, array[i].off);
+ return PR_FALSE;
+ }
+
+ if( &array[i].str[ array[i].off ] != rv )
+ {
+ printf("FAIL %d: %s,%s -> 0x%x, not 0x%x+%lu\n", i,
+ array[i].str ? array[i].str : "(null)",
+ array[i].sub ? array[i].sub : "(null)",
+ rv, array[i].str, array[i].off);
+ return PR_FALSE;
+ }
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_strcaserstr */
+PRBool test_028(void)
+{
+ static struct
+ {
+ const char *str;
+ const char *sub;
+ PRBool ret;
+ PRUint32 off;
+ } array[] =
+ {
+ { (const char *)0, (const char *)0, PR_FALSE, 0 },
+ { (const char *)0, "blah", PR_FALSE, 0 },
+ { "blah-de-blah", (const char *)0, PR_FALSE, 0 },
+ { "blah-de-blah", "blah", PR_TRUE, 8 },
+ { "", "blah", PR_FALSE, 0 },
+ { "blah-de-blah", "", PR_FALSE, 0 },
+ { "abcdefg", "a", PR_TRUE, 0 },
+ { "abcdefg", "c", PR_TRUE, 2 },
+ { "abcdefg", "e", PR_TRUE, 4 },
+ { "abcdefg", "g", PR_TRUE, 6 },
+ { "abcdefg", "i", PR_FALSE, 0 },
+ { "abcdefg", "ab", PR_TRUE, 0 },
+ { "abcdefg", "cd", PR_TRUE, 2 },
+ { "abcdefg", "ef", PR_TRUE, 4 },
+ { "abcdefg", "gh", PR_FALSE, 0 },
+ { "abcdabc", "bc", PR_TRUE, 5 },
+ { "abcdefg", "abcdefg", PR_TRUE, 0 },
+ { "abcdefgabcdefg", "a", PR_TRUE, 7 },
+ { "abcdefgabcdefg", "c", PR_TRUE, 9 },
+ { "abcdefgabcdefg", "e", PR_TRUE, 11 },
+ { "abcdefgabcdefg", "g", PR_TRUE, 13 },
+ { "abcdefgabcdefg", "i", PR_FALSE, 0 },
+ { "abcdefgabcdefg", "ab", PR_TRUE, 7 },
+ { "abcdefgabcdefg", "cd", PR_TRUE, 9 },
+ { "abcdefgabcdefg", "ef", PR_TRUE, 11 },
+ { "abcdefgabcdefg", "gh", PR_FALSE, 0 },
+ { "abcdabcabcdabc", "bc", PR_TRUE, 12 },
+ { "abcdefgabcdefg", "abcdefg", PR_TRUE, 7 },
+ { "ABCDEFG", "a", PR_TRUE, 0 },
+ { "ABCDEFG", "c", PR_TRUE, 2 },
+ { "ABCDEFG", "e", PR_TRUE, 4 },
+ { "ABCDEFG", "g", PR_TRUE, 6 },
+ { "ABCDEFG", "i", PR_FALSE, 0 },
+ { "ABCDEFG", "ab", PR_TRUE, 0 },
+ { "ABCDEFG", "cd", PR_TRUE, 2 },
+ { "ABCDEFG", "ef", PR_TRUE, 4 },
+ { "ABCDEFG", "gh", PR_FALSE, 0 },
+ { "ABCDABC", "bc", PR_TRUE, 5 },
+ { "ABCDEFG", "abcdefg", PR_TRUE, 0 },
+ { "ABCDEFGABCDEFG", "a", PR_TRUE, 7 },
+ { "ABCDEFGABCDEFG", "c", PR_TRUE, 9 },
+ { "ABCDEFGABCDEFG", "e", PR_TRUE, 11 },
+ { "ABCDEFGABCDEFG", "g", PR_TRUE, 13 },
+ { "ABCDEFGABCDEFG", "i", PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "ab", PR_TRUE, 7 },
+ { "ABCDEFGABCDEFG", "cd", PR_TRUE, 9 },
+ { "ABCDEFGABCDEFG", "ef", PR_TRUE, 11 },
+ { "ABCDEFGABCDEFG", "gh", PR_FALSE, 0 },
+ { "ABCDABCABCDABC", "bc", PR_TRUE, 12 },
+ { "ABCDEFGABCDEFG", "abcdefg", PR_TRUE, 7 }
+ };
+
+ int i;
+
+ printf("Test 028 (PL_strcaserstr) ..."); fflush(stdout);
+
+ for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+ {
+ char *rv = PL_strcaserstr(array[i].str, array[i].sub);
+
+ if( PR_FALSE == array[i].ret )
+ {
+ if( (char *)0 != rv )
+ {
+ printf("FAIL %d: %s,%s -> %.32s, not null\n", i,
+ array[i].str ? array[i].str : "(null)",
+ array[i].sub ? array[i].sub : "(null)",
+ rv);
+ return PR_FALSE;
+ }
+ }
+ else
+ {
+ if( (char *)0 == rv )
+ {
+ printf("FAIL %d: %s,%s -> null, not 0x%x+%lu\n", i,
+ array[i].str ? array[i].str : "(null)",
+ array[i].sub ? array[i].sub : "(null)",
+ array[i].str, array[i].off);
+ return PR_FALSE;
+ }
+
+ if( &array[i].str[ array[i].off ] != rv )
+ {
+ printf("FAIL %d: %s,%s -> 0x%x, not 0x%x+%lu\n", i,
+ array[i].str ? array[i].str : "(null)",
+ array[i].sub ? array[i].sub : "(null)",
+ rv, array[i].str, array[i].off);
+ return PR_FALSE;
+ }
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_strncasestr */
+PRBool test_029(void)
+{
+ static struct
+ {
+ const char *str;
+ const char *sub;
+ PRUint32 max;
+ PRBool ret;
+ PRUint32 off;
+ } array[] =
+ {
+ { (const char *)0, (const char *)0, 12, PR_FALSE, 0 },
+ { (const char *)0, "blah", 12, PR_FALSE, 0 },
+ { "blah-de-blah", (const char *)0, 12, PR_FALSE, 0 },
+ { "blah-de-blah", "blah", 0, PR_FALSE, 0 },
+ { "blah-de-blah", "blah", 2, PR_FALSE, 0 },
+ { "blah-de-blah", "blah", 3, PR_FALSE, 0 },
+ { "blah-de-blah", "blah", 4, PR_TRUE, 0 },
+ { "blah-de-blah", "blah", 5, PR_TRUE, 0 },
+ { "blah-de-blah", "blah", 12, PR_TRUE, 0 },
+ { "", "blah", 12, PR_FALSE, 0 },
+ { "blah-de-blah", "", 12, PR_FALSE, 0 },
+ { "abcdefg", "a", 5, PR_TRUE, 0 },
+ { "abcdefg", "c", 5, PR_TRUE, 2 },
+ { "abcdefg", "e", 5, PR_TRUE, 4 },
+ { "abcdefg", "g", 5, PR_FALSE, 0 },
+ { "abcdefg", "i", 5, PR_FALSE, 0 },
+ { "abcdefg", "ab", 5, PR_TRUE, 0 },
+ { "abcdefg", "cd", 5, PR_TRUE, 2 },
+ { "abcdefg", "ef", 5, PR_FALSE, 0 },
+ { "abcdefg", "gh", 5, PR_FALSE, 0 },
+ { "abcdabc", "bc", 5, PR_TRUE, 1 },
+ { "abcdabc", "bc", 6, PR_TRUE, 1 },
+ { "abcdabc", "bc", 7, PR_TRUE, 1 },
+ { "abcdefg", "abcdefg", 6, PR_FALSE, 0 },
+ { "abcdefg", "abcdefg", 7, PR_TRUE, 0 },
+ { "abcdefg", "abcdefg", 8, PR_TRUE, 0 },
+ { "abcdefgabcdefg", "a", 12, PR_TRUE, 0 },
+ { "abcdefgabcdefg", "c", 12, PR_TRUE, 2 },
+ { "abcdefgabcdefg", "e", 12, PR_TRUE, 4 },
+ { "abcdefgabcdefg", "g", 12, PR_TRUE, 6 },
+ { "abcdefgabcdefg", "i", 12, PR_FALSE, 0 },
+ { "abcdefgabcdefg", "ab", 12, PR_TRUE, 0 },
+ { "abcdefgabcdefg", "cd", 12, PR_TRUE, 2 },
+ { "abcdefgabcdefg", "ef", 12, PR_TRUE, 4 },
+ { "abcdefgabcdefg", "gh", 12, PR_FALSE, 0 },
+ { "abcdabcabcdabc", "bc", 5, PR_TRUE, 1 },
+ { "abcdabcabcdabc", "bc", 6, PR_TRUE, 1 },
+ { "abcdabcabcdabc", "bc", 7, PR_TRUE, 1 },
+ { "abcdefgabcdefg", "abcdefg", 6, PR_FALSE, 0 },
+ { "abcdefgabcdefg", "abcdefg", 7, PR_TRUE, 0 },
+ { "abcdefgabcdefg", "abcdefg", 8, PR_TRUE, 0 },
+ { "ABCDEFG", "a", 5, PR_TRUE, 0 },
+ { "ABCDEFG", "c", 5, PR_TRUE, 2 },
+ { "ABCDEFG", "e", 5, PR_TRUE, 4 },
+ { "ABCDEFG", "g", 5, PR_FALSE, 0 },
+ { "ABCDEFG", "i", 5, PR_FALSE, 0 },
+ { "ABCDEFG", "ab", 5, PR_TRUE, 0 },
+ { "ABCDEFG", "cd", 5, PR_TRUE, 2 },
+ { "ABCDEFG", "ef", 5, PR_FALSE, 0 },
+ { "ABCDEFG", "gh", 5, PR_FALSE, 0 },
+ { "ABCDABC", "bc", 5, PR_TRUE, 1 },
+ { "ABCDABC", "bc", 6, PR_TRUE, 1 },
+ { "ABCDABC", "bc", 7, PR_TRUE, 1 },
+ { "ABCDEFG", "abcdefg", 6, PR_FALSE, 0 },
+ { "ABCDEFG", "abcdefg", 7, PR_TRUE, 0 },
+ { "ABCDEFG", "abcdefg", 8, PR_TRUE, 0 },
+ { "ABCDEFGABCDEFG", "a", 12, PR_TRUE, 0 },
+ { "ABCDEFGABCDEFG", "c", 12, PR_TRUE, 2 },
+ { "ABCDEFGABCDEFG", "e", 12, PR_TRUE, 4 },
+ { "ABCDEFGABCDEFG", "g", 12, PR_TRUE, 6 },
+ { "ABCDEFGABCDEFG", "i", 12, PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "ab", 12, PR_TRUE, 0 },
+ { "ABCDEFGABCDEFG", "cd", 12, PR_TRUE, 2 },
+ { "ABCDEFGABCDEFG", "ef", 12, PR_TRUE, 4 },
+ { "ABCDEFGABCDEFG", "gh", 12, PR_FALSE, 0 },
+ { "ABCDABCABCDABC", "bc", 5, PR_TRUE, 1 },
+ { "ABCDABCABCDABC", "bc", 6, PR_TRUE, 1 },
+ { "ABCDABCABCDABC", "bc", 7, PR_TRUE, 1 },
+ { "ABCDEFGABCDEFG", "abcdefg", 6, PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "abcdefg", 7, PR_TRUE, 0 },
+ { "ABCDEFGABCDEFG", "abcdefg", 8, PR_TRUE, 0 }
+ };
+
+ int i;
+
+ printf("Test 029 (PL_strncasestr) ..."); fflush(stdout);
+
+ for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+ {
+ char *rv = PL_strncasestr(array[i].str, array[i].sub, array[i].max);
+
+ if( PR_FALSE == array[i].ret )
+ {
+ if( (char *)0 != rv )
+ {
+ printf("FAIL %d: %s,%s/%lu -> %.32s, not null\n", i,
+ array[i].str ? array[i].str : "(null)",
+ array[i].sub ? array[i].sub : "(null)",
+ array[i].max, rv);
+ return PR_FALSE;
+ }
+ }
+ else
+ {
+ if( (char *)0 == rv )
+ {
+ printf("FAIL %d: %s,%s/%lu -> null, not 0x%x+%lu\n", i,
+ array[i].str ? array[i].str : "(null)",
+ array[i].sub ? array[i].sub : "(null)",
+ array[i].max, array[i].str, array[i].off);
+ return PR_FALSE;
+ }
+
+ if( &array[i].str[ array[i].off ] != rv )
+ {
+ printf("FAIL %d: %s,%s/%lu -> 0x%x, not 0x%x+%lu\n", i,
+ array[i].str ? array[i].str : "(null)",
+ array[i].sub ? array[i].sub : "(null)",
+ array[i].max, rv, array[i].str, array[i].off);
+ return PR_FALSE;
+ }
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_strncaserstr */
+PRBool test_030(void)
+{
+ static struct
+ {
+ const char *str;
+ const char *sub;
+ PRUint32 max;
+ PRBool ret;
+ PRUint32 off;
+ } array[] =
+ {
+ { (const char *)0, (const char *)0, 12, PR_FALSE, 0 },
+ { (const char *)0, "blah", 12, PR_FALSE, 0 },
+ { "blah-de-blah", (const char *)0, 12, PR_FALSE, 0 },
+ { "blah-de-blah", "blah", 0, PR_FALSE, 0 },
+ { "blah-de-blah", "blah", 2, PR_FALSE, 0 },
+ { "blah-de-blah", "blah", 3, PR_FALSE, 0 },
+ { "blah-de-blah", "blah", 4, PR_TRUE, 0 },
+ { "blah-de-blah", "blah", 5, PR_TRUE, 0 },
+ { "blah-de-blah", "blah", 11, PR_TRUE, 0 },
+ { "blah-de-blah", "blah", 12, PR_TRUE, 8 },
+ { "blah-de-blah", "blah", 13, PR_TRUE, 8 },
+ { "", "blah", 12, PR_FALSE, 0 },
+ { "blah-de-blah", "", 12, PR_FALSE, 0 },
+ { "abcdefg", "a", 5, PR_TRUE, 0 },
+ { "abcdefg", "c", 5, PR_TRUE, 2 },
+ { "abcdefg", "e", 5, PR_TRUE, 4 },
+ { "abcdefg", "g", 5, PR_FALSE, 0 },
+ { "abcdefg", "i", 5, PR_FALSE, 0 },
+ { "abcdefg", "ab", 5, PR_TRUE, 0 },
+ { "abcdefg", "cd", 5, PR_TRUE, 2 },
+ { "abcdefg", "ef", 5, PR_FALSE, 0 },
+ { "abcdefg", "gh", 5, PR_FALSE, 0 },
+ { "abcdabc", "bc", 5, PR_TRUE, 1 },
+ { "abcdabc", "bc", 6, PR_TRUE, 1 },
+ { "abcdabc", "bc", 7, PR_TRUE, 5 },
+ { "abcdefg", "abcdefg", 6, PR_FALSE, 0 },
+ { "abcdefg", "abcdefg", 7, PR_TRUE, 0 },
+ { "abcdefg", "abcdefg", 8, PR_TRUE, 0 },
+ { "abcdefgabcdefg", "a", 12, PR_TRUE, 7 },
+ { "abcdefgabcdefg", "c", 12, PR_TRUE, 9 },
+ { "abcdefgabcdefg", "e", 12, PR_TRUE, 11 },
+ { "abcdefgabcdefg", "g", 12, PR_TRUE, 6 },
+ { "abcdefgabcdefg", "i", 12, PR_FALSE, 0 },
+ { "abcdefgabcdefg", "ab", 12, PR_TRUE, 7 },
+ { "abcdefgabcdefg", "cd", 12, PR_TRUE, 9 },
+ { "abcdefgabcdefg", "ef", 12, PR_TRUE, 4 },
+ { "abcdefgabcdefg", "gh", 12, PR_FALSE, 0 },
+ { "abcdabcabcdabc", "bc", 12, PR_TRUE, 8 },
+ { "abcdabcabcdabc", "bc", 13, PR_TRUE, 8 },
+ { "abcdabcabcdabc", "bc", 14, PR_TRUE, 12 },
+ { "abcdefgabcdefg", "abcdefg", 13, PR_TRUE, 0 },
+ { "abcdefgabcdefg", "abcdefg", 14, PR_TRUE, 7 },
+ { "abcdefgabcdefg", "abcdefg", 15, PR_TRUE, 7 },
+ { "ABCDEFG", "a", 5, PR_TRUE, 0 },
+ { "ABCDEFG", "c", 5, PR_TRUE, 2 },
+ { "ABCDEFG", "e", 5, PR_TRUE, 4 },
+ { "ABCDEFG", "g", 5, PR_FALSE, 0 },
+ { "ABCDEFG", "i", 5, PR_FALSE, 0 },
+ { "ABCDEFG", "ab", 5, PR_TRUE, 0 },
+ { "ABCDEFG", "cd", 5, PR_TRUE, 2 },
+ { "ABCDEFG", "ef", 5, PR_FALSE, 0 },
+ { "ABCDEFG", "gh", 5, PR_FALSE, 0 },
+ { "ABCDABC", "bc", 5, PR_TRUE, 1 },
+ { "ABCDABC", "bc", 6, PR_TRUE, 1 },
+ { "ABCDABC", "bc", 7, PR_TRUE, 5 },
+ { "ABCDEFG", "abcdefg", 6, PR_FALSE, 0 },
+ { "ABCDEFG", "abcdefg", 7, PR_TRUE, 0 },
+ { "ABCDEFG", "abcdefg", 8, PR_TRUE, 0 },
+ { "ABCDEFGABCDEFG", "a", 12, PR_TRUE, 7 },
+ { "ABCDEFGABCDEFG", "c", 12, PR_TRUE, 9 },
+ { "ABCDEFGABCDEFG", "e", 12, PR_TRUE, 11 },
+ { "ABCDEFGABCDEFG", "g", 12, PR_TRUE, 6 },
+ { "ABCDEFGABCDEFG", "i", 12, PR_FALSE, 0 },
+ { "ABCDEFGABCDEFG", "ab", 12, PR_TRUE, 7 },
+ { "ABCDEFGABCDEFG", "cd", 12, PR_TRUE, 9 },
+ { "ABCDEFGABCDEFG", "ef", 12, PR_TRUE, 4 },
+ { "ABCDEFGABCDEFG", "gh", 12, PR_FALSE, 0 },
+ { "ABCDABCABCDABC", "bc", 12, PR_TRUE, 8 },
+ { "ABCDABCABCDABC", "bc", 13, PR_TRUE, 8 },
+ { "ABCDABCABCDABC", "bc", 14, PR_TRUE, 12 },
+ { "ABCDEFGABCDEFG", "abcdefg", 13, PR_TRUE, 0 },
+ { "ABCDEFGABCDEFG", "abcdefg", 14, PR_TRUE, 7 },
+ { "ABCDEFGABCDEFG", "abcdefg", 15, PR_TRUE, 7 }
+ };
+
+ int i;
+
+ printf("Test 030 (PL_strncaserstr)..."); fflush(stdout);
+
+ for( i = 0; i < sizeof(array)/sizeof(array[0]); i++ )
+ {
+ char *rv = PL_strncaserstr(array[i].str, array[i].sub, array[i].max);
+
+ if( PR_FALSE == array[i].ret )
+ {
+ if( (char *)0 != rv )
+ {
+ printf("FAIL %d: %s,%s/%lu -> %.32s, not null\n", i,
+ array[i].str ? array[i].str : "(null)",
+ array[i].sub ? array[i].sub : "(null)",
+ array[i].max, rv);
+ return PR_FALSE;
+ }
+ }
+ else
+ {
+ if( (char *)0 == rv )
+ {
+ printf("FAIL %d: %s,%s/%lu -> null, not 0x%x+%lu\n", i,
+ array[i].str ? array[i].str : "(null)",
+ array[i].sub ? array[i].sub : "(null)",
+ array[i].max, array[i].str, array[i].off);
+ return PR_FALSE;
+ }
+
+ if( &array[i].str[ array[i].off ] != rv )
+ {
+ printf("FAIL %d: %s,%s/%lu -> 0x%x, not 0x%x+%lu\n", i,
+ array[i].str ? array[i].str : "(null)",
+ array[i].sub ? array[i].sub : "(null)",
+ array[i].max, rv, array[i].str, array[i].off);
+ return PR_FALSE;
+ }
+ }
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+/* PL_strtok_r */
+PRBool test_031(void)
+{
+ static const char *tokens[] = {
+ "wtc", "relyea", "nelsonb", "jpierre", "nicolson",
+ "ian.mcgreer", "kirk.erickson", "sonja.mirtitsch", "mhein"
+ };
+
+ static const char *seps[] = {
+ ", ", ",", " ", "\t", ",,,", " ,", " ", " \t\t", ","
+ };
+
+ static const char s2[] = ", \t";
+
+ char string[ 1024 ];
+ char *s1;
+ char *token;
+ char *lasts;
+ unsigned int i;
+
+ printf("Test 031 (PL_strtok_r) ..."); fflush(stdout);
+
+ /* Build the string. */
+ string[0] = '\0';
+ for( i = 0; i < sizeof(tokens)/sizeof(tokens[0]); i++ )
+ {
+ PL_strcat(string, tokens[i]);
+ PL_strcat(string, seps[i]);
+ }
+
+ /* Scan the string for tokens. */
+ i = 0;
+ s1 = string;
+ while( (token = PL_strtok_r(s1, s2, &lasts)) != NULL)
+ {
+ if( PL_strcmp(token, tokens[i]) != 0 )
+ {
+ printf("FAIL wrong token scanned\n");
+ return PR_FALSE;
+ }
+ i++;
+ s1 = NULL;
+ }
+ if( i != sizeof(tokens)/sizeof(tokens[0]) )
+ {
+ printf("FAIL wrong number of tokens scanned\n");
+ return PR_FALSE;
+ }
+
+ printf("PASS\n");
+ return PR_TRUE;
+}
+
+int
+main
+(
+ int argc,
+ char *argv[]
+)
+{
+ printf("Testing the Portable Library string functions:\n");
+
+ if( 1
+ && test_001()
+ && test_001()
+ && test_002()
+ && test_003()
+ && test_004()
+ && test_005()
+ && test_006()
+ && test_007()
+ && test_008()
+ && test_009()
+ && test_010()
+ && test_011()
+ && test_012()
+ && test_013()
+ && test_014()
+ && test_015()
+ && test_016()
+ && test_017()
+ && test_018()
+ && test_019()
+ && test_020()
+ && test_021()
+ && test_022()
+ && test_023()
+ && test_024()
+ && test_025()
+ && test_026()
+ && test_027()
+ && test_028()
+ && test_029()
+ && test_030()
+ && test_031()
+ )
+ {
+ printf("Suite passed.\n");
+ return 0;
+ }
+ else
+ {
+ printf("Suite failed.\n");
+ return 1;
+ }
+
+ /*NOTREACHED*/
+}
diff --git a/src/libs/xpcom18a4/nsprpub/lib/tests/windows/makefile b/src/libs/xpcom18a4/nsprpub/lib/tests/windows/makefile
new file mode 100644
index 00000000..1cf2c079
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/tests/windows/makefile
@@ -0,0 +1,82 @@
+#
+# 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 the Netscape Portable Runtime (NSPR).
+#
+# The Initial Developer of the Original Code is Netscape
+# Communications Corporation. Portions created by Netscape are
+# Copyright (C) 1998-2000 Netscape Communications Corporation. All
+# Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the
+# terms of the GNU General Public License Version 2 or later (the
+# "GPL"), in which case the provisions of the GPL are applicable
+# instead of those above. If you wish to allow use of your
+# version of this file only under the terms of the GPL and not to
+# allow others to use your version of this file under the MPL,
+# indicate your decision by deleting the provisions above and
+# replace them with the notice and other provisions required by
+# the GPL. If you do not delete the provisions above, a recipient
+# may use your version of this file under either the MPL or the
+# GPL.
+#
+
+#! gmake
+
+
+
+MOD_DEPTH = ../../..
+
+include $(MOD_DEPTH)/config/config.mk
+
+INCLUDES = -I$(DIST)/include
+
+CSRCS = winevent.c
+
+ifeq ($(OS_ARCH), WINNT)
+ifeq ($(OS_TARGET), WIN16)
+ LIBPR = $(DIST)/lib/nspr$(MOD_VERSION).lib
+ LIBPLC= $(DIST)/lib/plc$(MOD_VERSION).lib
+ LIBPLDS= $(DIST)/lib/plds$(MOD_VERSION).lib
+else
+ LDOPTS = -NOLOGO -DEBUG -DEBUGTYPE:CV -INCREMENTAL:NO
+ ifeq ($(OS_TARGET), WIN95)
+ LIBPR = $(DIST)/lib/nspr$(MOD_VERSION).$(LIB_SUFFIX)
+ LIBPLC= $(DIST)/lib/plc$(MOD_VERSION).$(LIB_SUFFIX)
+ LIBPLDS= $(DIST)/lib/plds$(MOD_VERSION).lib
+ else
+ LIBPR = $(DIST)/lib/libnspr$(MOD_VERSION).$(LIB_SUFFIX)
+ LIBPLC= $(DIST)/lib/libplc$(MOD_VERSION).$(LIB_SUFFIX)
+ LIBPLDS= $(DIST)/lib/libplds$(MOD_VERSION).lib
+ endif
+endif
+endif
+
+TARGETS = $(OBJDIR)/winevent.exe
+OS_CFLAGS = $(OS_EXE_CFLAGS)
+LDOPTS = -NOLOGO -DEBUG -DEBUGTYPE:CV -INCREMENTAL:NO
+LDFLAGS += -DEBUG
+LIBPR += $(LIBPLDS)
+LIBPR += kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib
+
+include $(MOD_DEPTH)/config/rules.mk
+
+$(OBJDIR)/winevent.exe: $(OBJS)
+ link $(LDOPTS) $< $(LIBPLC) $(LIBPR) wsock32.lib -out:$@
+
+export:: $(TARGETS)
+
+install:: export
+
+clean::
+ rm -rf $(TARGETS)
diff --git a/src/libs/xpcom18a4/nsprpub/lib/tests/windows/readme.1st b/src/libs/xpcom18a4/nsprpub/lib/tests/windows/readme.1st
new file mode 100644
index 00000000..2b756823
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/tests/windows/readme.1st
@@ -0,0 +1,37 @@
+readme.1st.
+
+The files in the lib/tests/WinGUI directory are taken
+from "Programming Windows 3.1" by Charles Petzold,
+specifically, the programs in chapter 14 related
+to the "poppad4" sample application.
+
+These programs are compiled with nspr20 to test nspr 2.0
+and to demostrate the use of nspr in a gui application.
+
+Library (DLL) PLDSxx.lib PLDSxx.dll is required to be
+linked with this test case. Functions in this dll are
+in the source ns/nspr20/lib/ds/plevent.* files.
+
+Permission to use.
+
+The source for poppad.c are used under license from
+Petzold. The license to use is stated in the book.
+The following paragraph of the license grants that
+use.
+
+ 5. SAMPLE CODE. If the SOFTWARE includes Sample Code, then
+ Microsoft grants you a royalty-free right to reproduce and
+ distribute the sample code of the SOFTWARE provided that you:
+ (a) distribute the sample code only in conjunction with and
+ as part of your software product; (b) do not use Microsoft's
+ or its authors' names, logos, or trademarks to market your
+ software product; (c) include the copyright notice that appears
+ on the SOFTWARE on your product label and as a part of the
+ sign-on message for your software product; and (d) agree to
+ idemnify, hold harmless, and defend Microsoft and its authors
+ from and against any claims or lawsuits, including attorneys'
+ fees, that arise or result from the use or distribution of
+ your software product.
+
+lth. 9/24/97.
+
diff --git a/src/libs/xpcom18a4/nsprpub/lib/tests/windows/winevent.c b/src/libs/xpcom18a4/nsprpub/lib/tests/windows/winevent.c
new file mode 100644
index 00000000..d571aed7
--- /dev/null
+++ b/src/libs/xpcom18a4/nsprpub/lib/tests/windows/winevent.c
@@ -0,0 +1,348 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape Portable Runtime (NSPR).
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-2000
+ * 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 MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File: winevent.c
+** Description: Test functions in plevent.c using Windows
+**
+** The winevent test exercises the PLEvent library in a maner
+** similar to how the Mozilla (or NGLayout) Client will use
+** it in a Windows environment.
+**
+** This test is based on ideas taken from Charles Petzold's
+** book "Programming Windows 3.1". License to use is in the
+** book. It has been ported to Win32.
+**
+** Operation:
+** The initialization is a standard Windows GUI application
+** setup. When the main window receives its WM_CREATE
+** message, a child window is created, a edit control is
+** instantiated in that window.
+**
+** A thread is created; this thread runs in the function:
+** TimerThread(). The new thread sends a message every second
+** via the PL_PostEvent() function. The event handler
+** HandlePadEvent() sends a windows message to the edit
+** control window; these messages are WM_CHAR messages that
+** cause the edit control to place a single '.' character in
+** the edit control.
+**
+** After a deterministic number of '.' characters, the
+** TimerThread() function is notified via a global variable
+** that it's quitting time.
+**
+** TimerThread() callse TestEvents(), an external function
+** that tests additional function of PLEvent.
+**
+*/
+
+#include "nspr.h"
+#include "plevent.h"
+
+#include <windows.h>
+#include <commdlg.h>
+
+#define ID_EDIT 1
+
+/*
+** Declarations for NSPR customization
+**
+*/
+typedef struct PadEvent
+{
+ PLEvent plEvent;
+ int unused;
+} PadEvent;
+
+static void PR_CALLBACK TimerThread( void *arg);
+static void PR_CALLBACK HandlePadEvent( PadEvent *padEvent );
+static void PR_CALLBACK DestroyPadEvent( PadEvent *padevent );
+
+static PRThread *tThread;
+static PLEventQueue *padQueue;
+static long ThreadSleepTime = 1000; /* in milli-seconds */
+static long timerCount = 0;
+static HWND hDlgModeless ;
+static HWND hwndEdit ;
+static PRBool testFinished = PR_FALSE;
+static HWND hwnd ;
+
+LRESULT CALLBACK WinProc (HWND, UINT, WPARAM, LPARAM);
+
+TCHAR appName[] = TEXT ("WinEvent") ;
+
+int WINAPI WinMain(
+ HINSTANCE hInstance,
+ HINSTANCE hPrevInstance,
+ PSTR szCmdLine,
+ int iCmdShow
+ )
+{
+ MSG msg ;
+ WNDCLASS wndclass ;
+ HANDLE hAccel ;
+
+ PR_Init(0, 0, 0);
+
+ wndclass.style = CS_HREDRAW | CS_VREDRAW;
+ wndclass.lpfnWndProc = WinProc;
+ wndclass.cbClsExtra = 0;
+ wndclass.cbWndExtra = 0;
+ wndclass.hInstance = hInstance;
+ wndclass.hIcon = LoadIcon( NULL, IDI_APPLICATION );
+ wndclass.hCursor = LoadCursor( NULL, IDC_ARROW );
+ wndclass.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH );
+ wndclass.lpszMenuName = NULL;
+ wndclass.lpszClassName = appName;
+
+ if ( !RegisterClass( &wndclass ))
+ {
+ MessageBox( NULL,
+ TEXT( "This program needs Win32" ),
+ appName,
+ MB_ICONERROR );
+ return 0;
+ }
+
+ hwnd = CreateWindow( appName,
+ appName,
+ WS_OVERLAPPEDWINDOW,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ NULL,
+ NULL,
+ hInstance,
+ NULL);
+
+ ShowWindow( hwnd, iCmdShow );
+ UpdateWindow( hwnd );
+
+ for(;;)
+ {
+ if ( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ))
+ {
+ if ( GetMessage( &msg, NULL, 0, 0 ))
+ {
+ if ( hDlgModeless == NULL || !IsDialogMessage( hDlgModeless, &msg ))
+ {
+ if ( !TranslateAccelerator( hwnd, hAccel, &msg ))
+ {
+ TranslateMessage( &msg );
+ DispatchMessage( &msg );
+ } /* end if !TranslateAccelerator */
+ }
+ }
+ else
+ {
+ break;
+ } /* end if GetMessage() */
+ }
+ else /* !PeekMessage */
+ {
+ PR_Sleep(50);
+ }/* end if PeekMessage() */
+ } /* end for() */
+
+ PR_JoinThread( tThread );
+ PL_DestroyEventQueue( padQueue );
+ PR_Cleanup();
+ return msg.wParam ;
+}
+
+LRESULT CALLBACK WinProc(
+ HWND hwnd,
+ UINT message,
+ WPARAM wParam,
+ LPARAM lParam
+)
+{
+ switch (message)
+ {
+ case WM_CREATE :
+ hwndEdit = CreateWindow(
+ TEXT( "edit" ),
+ NULL,
+ WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL |
+ WS_BORDER | ES_LEFT | ES_MULTILINE |
+ ES_AUTOHSCROLL | ES_AUTOVSCROLL,
+ 0, 0, 0, 0,
+ hwnd,
+ (HMENU)ID_EDIT,
+ ((LPCREATESTRUCT)lParam)->hInstance,
+ NULL);
+
+ /* Initialize Event Processing for NSPR
+ ** Retrieve the event queue just created
+ ** Create the TimerThread
+ */
+
+/*
+ PL_InitializeEventsLib( "someName" );
+ padQueue = PL_GetMainEventQueue();
+*/
+ padQueue = PL_CreateEventQueue("MainQueue", PR_GetCurrentThread());
+ PR_ASSERT( padQueue != NULL );
+ tThread = PR_CreateThread( PR_USER_THREAD,
+ TimerThread,
+ NULL,
+ PR_PRIORITY_NORMAL,
+ PR_LOCAL_THREAD,
+ PR_JOINABLE_THREAD,
+ 0 );
+ return 0 ;
+
+ case WM_SETFOCUS :
+ SetFocus( hwndEdit );
+ return 0;
+
+ case WM_SIZE :
+ MoveWindow( hwndEdit, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE );
+ return 0 ;
+
+ case WM_COMMAND :
+ if ( LOWORD(wParam) == ID_EDIT )
+ if ( HIWORD(wParam ) == EN_ERRSPACE ||
+ HIWORD( wParam ) == EN_MAXTEXT )
+
+ MessageBox( hwnd, TEXT( "Edit control out of space." ),
+ appName, MB_OK | MB_ICONSTOP );
+ return 0;
+
+ case WM_DESTROY :
+ PostQuitMessage(0);
+ return 0;
+ }
+ return DefWindowProc( hwnd, message, wParam, lParam );
+}
+
+
+
+/*
+** TimerThread() -- The Main function of the timer pop thread
+**
+*/
+static void PR_CALLBACK TimerThread( void *arg )
+{
+ PRIntn rc;
+
+ do {
+ PadEvent *ev;
+
+ /*
+ ** Create and Post the event the event
+ */
+ PL_ENTER_EVENT_QUEUE_MONITOR( padQueue );
+ ev = (PadEvent *) PR_NEW( PadEvent );
+ PL_InitEvent( &ev->plEvent, NULL,
+ (PLHandleEventProc)HandlePadEvent,
+ (PLDestroyEventProc)DestroyPadEvent );
+ PL_PostEvent( padQueue, &ev->plEvent );
+ PL_EXIT_EVENT_QUEUE_MONITOR( padQueue );
+
+ PR_Sleep( PR_MillisecondsToInterval(ThreadSleepTime) );
+ } while( testFinished == PR_FALSE );
+
+ PR_Sleep( PR_SecondsToInterval(4) );
+
+ /*
+ ** All done now. This thread can kill the main thread by sending
+ ** WM_DESTROY message to the main window.
+ */
+ SendMessage( hwnd, WM_DESTROY, 0, 0 );
+ return;
+}
+
+static char *startMessage = "Poppad: NSPR Windows GUI and event test program.\n"
+ "Every 1 second gets a '.'.\n"
+ "The test self terminates in less than a minute\n"
+ "You should be able to type in the window.\n\n";
+
+static char *stopMessage = "\n\nIf you saw a series of dots being emitted in the window\n"
+ " at one second intervals, the test worked.\n\n";
+
+/*
+** HandlePadEvent() -- gets called because of PostEvent
+*/
+static void PR_CALLBACK HandlePadEvent( PadEvent *padEvent )
+{
+ char *cp;
+ static const long lineLimit = 10; /* limit on number of '.' per line */
+ static const long timerLimit = 25; /* limit on timer pop iterations */
+
+ if ( timerCount++ == 0 )
+ {
+
+ for ( cp = startMessage; *cp != 0 ; cp++ )
+ {
+ SendMessage( hwndEdit, WM_CHAR, *cp, 1 );
+ }
+ }
+ /*
+ ** Send a WM_CHAR event the edit Window
+ */
+ SendMessage( hwndEdit, WM_CHAR, '.', 1 );
+
+ /*
+ ** Limit the number of characters sent via timer pop to lineLimit
+ */
+ if ( (timerCount % lineLimit) == 0)
+ {
+ SendMessage( hwndEdit, WM_CHAR, '\n', 1 );
+ }
+
+ if ( timerCount >= timerLimit )
+ {
+ for ( cp = stopMessage; *cp != 0 ; cp++ )
+ {
+ SendMessage( hwndEdit, WM_CHAR, *cp, 1 );
+ }
+ testFinished = PR_TRUE;
+ }
+
+ return;
+}
+
+/*
+** DestroyPadEvent() -- Called after HandlePadEvent()
+*/
+static void PR_CALLBACK DestroyPadEvent( PadEvent *padevent )
+{
+ PR_Free( padevent );
+ return;
+}